通过supervisor关闭Docker容器

10 浏览
0 Comments

通过supervisor关闭Docker容器

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

在查阅supervisor文档中关于supervisorctl stop 动作的说明后得知,会向进程发送SIGTERM,然后在一段宽限期后如果仍在运行会发送SIGKILL。我尝试手动执行这些操作并发现:

  • docker run进程发送SIGTERM没有任何反应
  • SIGKILL可以杀死进程,但实际上并没有更新docker。docker ps显示该容器仍在运行
  • Supervisor的SIGKILL无法关闭容器

问题是:我如何通过supervisor正确关闭Docker容器?


以下是模拟supervisor的实验结果:

起始状态:运行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
...  ...
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进程发送SIGTERMSIGHUPSIGQUIT似乎对进程没有任何影响。只有SIGKILL可以正确终止docker进程。Supervisor可以正确更新,但docker ps仍然显示docker进程正在运行。

0