通过主pipeclosuresDocker容器

我无法closures主pipe通过supervisorctl stop all启动的Docker容器supervisorctl stop all 。 即使通过supervisorctl status显示容器已closures, docker psps表明它们实际上仍在运行。

咨询supervisorctl stop <name>操作的主pipe文档显示,如果在某个宽限期之后仍然运行, SIGTERM被发送到进程之后的SIGKILL 。 我试图手动做到这一点,发现

  • 发送到docker run进程的SIGTERM不会执行任何操作
  • SIGKILL会杀死进程,但实际上并没有更新docker。 docker ps显示这个容器仍在运行
  • 主pipe的SIGKILL不closures容器

问题是:如何正确closures一个Docker容器的主pipe?


以下是我的模拟pipe理员的实验结果:

开始位置: foo-1bar-1正在运行(我离开了GCE容器,以防他们有所作为)。 ps auxdocker ps是同步的。

 me@devenv:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5ba70bf8937f me/app:foo "/bin/sh -c 'supervi 5 minutes ago Up 5 minutes foo-1 e1a684bcfceb me/app:bar "/bin/sh -c 'supervi 5 minutes ago Up 5 minutes bar-1 fce5db0517df google/cadvisor:0.8.0 "/usr/bin/cadvisor" 35 minutes ago Up 35 minutes bbbb db677eed47ef kubernetes/pause:go "/pause" 35 minutes ago Up 35 minutes 0.0.0.0:4194->8080/tcp aaaa me@devenv:~$ ps aux | grep "docker run" root 23358 0.0 0.1 124092 11856 pts/0 Sl 02:05 0:00 docker run --rm --name foo-1 ... -i me/app:foo root 23365 0.0 0.1 124092 11928 pts/0 Sl 02:05 0:00 docker run --rm --name bar-1 ... -i me/app:bar 

通过向进程发送SIGTERM来模拟supervisorctl stop foo-1 。 结果:过程仍然有效。

 me@devenv:~$ sudo kill -SIGTERM 23358 ... <waiting> ... me@devenv:~$ ps aux | grep "docker run" root 23358 0.0 0.1 124092 11856 pts/0 Sl 02:05 0:00 docker run --rm --name foo-1 ... -i me/app:foo root 23365 0.0 0.1 124092 11928 pts/0 Sl 02:05 0:00 docker run --rm --name bar-1 ... -i me/app:bar me@devenv:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5ba70bf8937f me/app:foo "/bin/sh -c 'supervi 6 minutes ago Up 6 minutes foo-1 e1a684bcfceb me/app:bar "/bin/sh -c 'supervi 6 minutes ago Up 6 minutes bar-1 fce5db0517df google/cadvisor:0.8.0 "/usr/bin/cadvisor" 36 minutes ago Up 36 minutes bbbb db677eed47ef kubernetes/pause:go "/pause" 36 minutes ago Up 36 minutes 0.0.0.0:4194->8080/tcp aaaa 

接下来的主pipe会做的是发行SIGKILL 。 结果:进程被终止( ps aux ),但仍显示为正在运行的docker进程( docker ps )。

 me@devenv:~$ sudo kill -SIGKILL 23358 me@devenv:~$ ps aux | grep "docker run" root 23365 0.0 0.1 124092 11928 pts/0 Sl 02:05 0:00 docker run --rm --name bar-1 ... -i me/app:bar me@devenv:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5ba70bf8937f me/app:foo "/bin/sh -c 'supervi 19 minutes ago Up 19 minutes foo-1 e1a684bcfceb me/app:bar "/bin/sh -c 'supervi 19 minutes ago Up 19 minutes bar-1 fce5db0517df google/cadvisor:0.8.0 "/usr/bin/cadvisor" 49 minutes ago Up 49 minutes bbbb db677eed47ef kubernetes/pause:go "/pause" 49 minutes ago Up 49 minutes 0.0.0.0:4194->8080/tcp aaaa 

在上面的实验中,主pipeclosures了(为了避免自动启动行为干扰)。 主pipe无法实现将SIGKILL明确发送到stream程的结果; 该过程仍然存在(即使监督员以其他方式logging状态)。 docker stop <container_id>不过停止了容器。

更新

Docker容器内部也是一个pipe理特定进程的supervisord进程。 也许问题是信号不传播,因此它不会closures…

更新2

我缩小了这个问题。 我能够直接从Dockerfile启动一个容器进程,而不是通过启动supervisord ,它Dockerfile 。 我可以通过主pipe(控制集装箱的docker集装箱以外的那个集装箱)来控制这个集装箱。

更新3

按照这里的build议设置stopasgroup=true不会改变任何东西。

更新4

我能够解决其中一个问题: supervisorctl不能closures进程。 问题是,我正在启动泊坞窗容器的监督员configuration文件与command=sudo docker run...创build一个sudo docker run...docker run...进程。 supervisorctl stop...刚刚终止了sudo docker run...进程,而实际的docker进程仍在运行。 当我省略sudo命令时,每个超级用户程序只启动一个进程, supervisorctl stop终止进程。

一个问题仍然是, docker ps显示容器仍在运行,而ps aux不运行。 奇怪的是,容器似乎仍然是积极的,因为他们回应请求。 快速看一下进程列表,确认docker容器产生的所有进程仍然是活动的,但进程列表中缺lessdocker run...进程。

更新5

发送SIGTERMSIGHUPSIGQUITdocker run进程似乎没有对进程做任何事情。 只有SIGKILL才能正确终止docker进程。 主pipe得到正确更新,但docker ps仍然显示docker进程运行。

我想我发现了这个问题。 我没有意识到,但是当docker集装箱启动时,有多种启动程序的方法。

显然, CMD myexec param1 param2启动一个shell,然后启动myexec (事实上​​,这两个进程在容器中可见/bin/sh -c myexec...在PID 1.更好的方法是直接启动程序我的情况supervisord)。

另一方面, CMD ["/usr/bin/python", "/usr/local/bin/supervisord", "-c", "/root/supervisord.conf", "--nodaemon"]工作正常。 我现在可以通过主pipe启动和停止docker集装箱。

以下是 Docker文档中的相关部分:

CMD指令有三种forms:

CMD ["executable","param1","param2"] (execforms,这是首选forms)

CMD ["param1","param2"]参数1 CMD ["param1","param2"]参数2 CMD ["param1","param2"] (作为默认参数ENTRYPOINT)

CMD command param1 param2 (shellforms)

更新

示例主pipe文件(在Docker容器内):

 [program:app] command=python run_web_server.py stdout_logfile=/var/log/app/app.log directory=/opt/app autostart=true autorestart=false stopsignal=INT redirect_stderr=true startretries=0 stopasgroup=true killasgroup=true [unix_http_server] file=/var/run/supervisor.sock chmod=0700 [supervisord] logfile=/var/log/supervisor/supervisord.log pidfile=/var/run/supervisord.pid childlogdir=/var/log/supervisor [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock 

生成Docker(外部)主pipe文件的mako模板:

 [program:container] command=docker run --rm --name ${name} \ % if container_links is not UNDEFINED: % for host in container_hosts: --add-host ${host['name']}:${host['ip']} \ % endfor % endif % if container_links is not UNDEFINED: % for link in container_links: --link ${link}:${link} \ % endfor % endif % if port_mappings is not UNDEFINED: % for ext in port_mappings: -p ${ext}:${port_mappings[ext]} \ % endfor % endif -e "INSTANCE_NAME=${name}" \ -e "TZ=${timezone}" \ % if environ is not UNDEFINED: % for k in environ: -e "${k}=${environ[k]}" \ % endfor % endif -v ${deployment_dir}/tmp:${deployment_dir}/app/tmp \ ... more -v -i foo/app-${version}:${type} stdout_logfile=${deployment_dir}/log/${name}.log redirect_stderr=true autostart=false autorestart=false % if priority is not UNDEFINED: priority=${priority} % endif startretries=0 # stopasgroup=true # killasgroup=true