通过supervisor关闭Docker容器
通过supervisor关闭Docker容器
我无法通过supervisorctl stop all
关闭由supervisor启动的Docker容器。即使通过supervisorctl status
显示容器已经关闭,docker ps
和ps
表明它们实际上仍在运行。
在查阅supervisor文档中关于supervisorctl stop
动作的说明后得知,会向进程发送SIGTERM
,然后在一段宽限期后如果仍在运行会发送SIGKILL
。我尝试手动执行这些操作并发现:
- 向
docker run
进程发送SIGTERM
没有任何反应 SIGKILL
可以杀死进程,但实际上并没有更新docker。docker ps
显示该容器仍在运行- Supervisor的
SIGKILL
无法关闭容器
问题是:我如何通过supervisor正确关闭Docker容器?
以下是模拟supervisor的实验结果:
起始状态:运行foo-1
和bar-1
(我保留了GCE容器,以防它们会有什么影响)。ps aux
和docker 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 ...... 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
接下来supervisor将发出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
在上述实验期间关闭了supervisor(以避免其自动启动行为干扰)。通过向进程显式发送SIGKILL
的结果无法通过supervisor实现;进程仍然存活(尽管supervisor日志表明不是这样)。
docker stop
可以停止容器。
更新
Docker容器内部还运行着一个管理某些进程的supervisord
进程。也许问题在于信号没有传递,因此无法关闭...
更新2
我缩小了问题范围。我能够直接从Dockerfile
启动容器的进程,而不是通过启动supervisord
,这是有区别的。我能够通过supervisor(控制容器的外部容器)控制该容器。
更新3
根据此处建议设置stopasgroup=true
对我没有任何改变。
更新4
我已经解决了一个问题:无法使用supervisorctl
关闭进程。问题在于我在supervisor配置文件中使用command=sudo docker run...
启动docker容器,这样会创建sudo docker run...
和docker run...
两个进程。只有supervisorctl stop...
终止了sudo docker run...
进程,而实际的docker进程仍在运行。当我省略sudo
命令时,每个supervisor程序只启动1个进程,并且supervisorctl stop
可以终止该进程。
其中一个问题仍然存在,即docker ps
显示容器仍在运行,而ps aux
则没有。奇怪的是,容器似乎仍然处于活动状态,因为它们会响应请求。快速查看进程列表确认了由docker容器生成的所有进程仍然活动,但是进程列表中缺少docker run...
进程。
更新5
向docker run
进程发送SIGTERM
、SIGHUP
或SIGQUIT
似乎对进程没有任何影响。只有SIGKILL
可以正确终止docker进程。Supervisor可以正确更新,但docker ps
仍然显示docker进程正在运行。