Keep

     目前使用cypress作为拨测工具的核心框架,随着业务发展,对线上的监控拨测频率要求越来越高,之前串行方式已经无法满足业务诉求,但cypress本身的并行运行需要配合它自身的Dashboard Service来使用。所以打算利用docker+python+cypress简单实现一个cypress并行模式,简易架构图如下:

55f1ce2336ca4d3435c7a43b10341faa.png

Problem

实现过程中遇到了几个问题:

1.core.py用了APScheduler+tornado+docker-py来实现的,但基于tornado实现的接口始终没有返回

2.docker自定义镜像启动时始终没有执行dockerfile的脚本,而是直接使用了cypress run命令

3.因为core.py和docker镜像在同一台物理机,为了简单使用,直接用了Host模式网络,结果每次明明启动了3个agent,但实际运行只有1个

Try

   1.自定义接口始终无法返回:

   core.py脚本本来使用的是BlockingScheduler调度器,但后来发现APScheduler有专属tornado的调度器,改用TornadoScheduler后即可。初步猜测是BlockingScheduler调度器和tornado抢主线程导致,埋个坑,后面解释

   2.docker镜像启动时没有使用dockerfile中自定义脚本:

   将dockerfile中的最后的CMD改为ENTENTRYPOINT后,docker自定义镜像终于运行dockerfile中的自定义脚本

   3.明明启动3个agent,但实际运行的docker containers只有1个:

   因为cypress启动时会占用一个端口,将模式改为默认的Bridge模式,并且在镜像里面的回传脚本地址从127.0.0.1改为172.17.0.1即可。这样再启动时cypress脚本就会占用容器中的端口(对于物理机就是随机端口了)


简单说说dockerfile中的CMD和ENTRYPOINT的区别

尽管CMD和ENTRYPOINT都可以定义docker运行的启动命令,但两者的优先级不一样:若FROM的镜像用了ENTRYPOINT,然后又在dockerfile最后定义了CMD,那么这个镜像启动命令就是ENTRYPOINT+CMD;若FROM的镜像用了CMD,然后又在dockerfile最后定义了ENTRYPOINT,那么这个镜像启动命令就是ENTRYPOINT;同一命令都是覆盖的。上面可能有点绕口,来看几个例子:

镜像entrypoint,dockerfile如下:

FROM alpine:3.2ENTRYPOINT ["echo", "hello"]

执行docker run entrypoint后,打印如下:

hello

镜像cmd,dockerfile如下:

FROM entrypointCMD ["echo","word"]

执行docker run cmd后,打印如下:

hello echo word

我们修改下镜像cmd,并命名为cmd:entrypoint,其dockefile如下:

FROM entrypointENTRYPOINT ["echo","word"]

执行docker run cmd:entrypoint后,打印如下:

word

简单说下docker的网络模型,docker的网络模型分为四种:

  • Host(与宿主机共享一个网络)

  • Bridge(与宿主机共享一个局域网,有自己的网络;docker运行默认Bridge)

  • Container(与另一个容器共享一个网络,eg:业务容器和数据库容器)

  • None(封闭网络)

这里主要说明Host和Bridge的不同

Bridge模式下,每个容器都有自己一套网络策略和ip地址,然后容器跟宿主机是在同一个局域网子网下,如果要从容器中访问到宿主机的相关内容,可直接通过访问宿主机子网ip+端口来访问,可通过

ifconfig docker0

来获取宿主机在子网中的ip(linux系统)

docker18.03版本有一个feature,你可以直接通过host.docker.internal来获取到宿主机的子网ip

ed2f5f6c3c5bec28abe80b6506060f83.png

Host模式下,每个容器都和宿主机共享一套网络策略和ip地址,所以此时可以直接通过127.0.0.1访问到宿主机的内容

参考资料:https://docs.docker.com/

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐