docker compose:数百个健康检查进程未终止。
services:
tomcat:
...
healthcheck:
test:
- CMD-SHELL
- curl --fail http://localhost:8080 || exit 1
interval: 5s
timeout: 5s
retries: 30
ps 辅助 | grep curl
tomcat 939765 0.0 0.0 0 0 ? Z 08:46 0:00 [curl] <defunct>
tomcat 939824 0.0 0.0 0 0 ? Z 08:46 0:00 [curl] <defunct>
tomcat 939904 0.0 0.0 0 0 ? Z 08:47 0:00 [curl] <defunct>
tomcat 939962 0.0 0.0 0 0 ? Z 08:47 0:00 [curl] <defunct>
tomcat 940038 0.0 0.0 0 0 ? Z 08:47 0:00 [curl] <defunct>
tomcat 940094 0.0 0.0 0 0 ? Z 08:47 0:00 [curl] <defunct>
tomcat 940321 0.0 0.0 0 0 ? Z 08:48 0:00 [curl] <defunct>
tomcat 940380 0.0 0.0 0 0 ? Z 08:48 0:00 [curl] <defunct>
tomcat 940460 0.0 0.0 0 0 ? Z 08:48 0:00 [curl] <defunct>
tomcat 940516 0.0 0.0 0 0 ? Z 08:48 0:00 [curl] <defunct>
tomcat 940600 0.0 0.0 0 0 ? Z 08:49 0:00 [curl] <defunct>
tomcat 940657 0.0 0.0 0 0 ? Z 08:49 0:00 [curl] <defunct>
tomcat 940734 0.0 0.0 0 0 ? Z 08:49 0:00 [curl] <defunct>
tomcat 940875 0.0 0.0 0 0 ? Z 08:49 0:00 [curl] <defunct>
tomcat 940955 0.0 0.0 0 0 ? Z 08:50 0:00 [curl] <defunct>
tomcat 941013 0.0 0.0 0 0 ? Z 08:50 0:00 [curl] <defunct>
tomcat 941102 0.0 0.0 0 0 ? Z 08:50 0:00 [curl] <defunct>
tomcat 941162 0.0 0.0 0 0 ? Z 08:50 0:00 [curl] <defunct>
tomcat 941244 0.0 0.0 0 0 ? Z 08:51 0:00 [curl] <defunct>
tomcat 941332 0.0 0.0 0 0 ? Z 08:51 0:00 [curl] <defunct>
tomcat 941392 0.0 0.0 0 0 ? Z 08:51 0:00 [curl] <defunct>
tomcat 941474 0.0 0.0 0 0 ? Z 08:51 0:00 [curl] <defunct>
tomcat 941532 0.0 0.0 0 0 ? Z 08:52 0:00 [curl] <defunct>
tomcat 941609 0.0 0.0 0 0 ? Z 08:52 0:00 [curl] <defunct>
tomcat 941671 0.0 0.0 0 0 ? Z 08:52 0:00 [curl] <defunct>
tomcat 941749 0.0 0.0 0 0 ? Z 08:52 0:00 [curl] <defunct>
tomcat 941810 0.0 0.0 0 0 ? Z 08:53 0:00 [curl] <defunct>
....
tomcat 941895 0.0 0.2 22364 8436 ? S 08:53 0:00 curl --fail http://localhost:8080
tomcat 941954 0.0 0.2 22364 8512 ? S 08:53 0:00 curl --fail http://localhost:8080
tomcat 942032 0.0 0.2 22364 8384 ? S 08:53 0:00 curl --fail http://localhost:8080
tomcat 942238 0.0 0.2 22364 8528 ? S 08:54 0:00 curl --fail http://localhost:8080
tomcat 942316 0.0 0.2 22364 8552 ? S 08:54 0:00 curl --fail http://localhost:8080
tomcat 942377 0.0 0.2 22364 8496 ? S 08:55 0:00 curl --fail http://localhost:8080
tomcat 942452 0.0 0.2 22364 8360 ? S 08:55 0:00 curl --fail http://localhost:8080
...
即使在检查容器健康之后,健康检查器是否还会继续定期运行?
“curl”进程没有终止的原因是什么?
最佳答案
查看此输出,我将其读为 curl
命令未在 5 秒内完成并被终止,并且主容器进程未设置为处理它获得对未自行启动的子进程的责任的情况。
我怀疑您可以采取两件事来解决此问题:
- 修复您的应用程序,以便其及时响应运行状况检查。它不应该处于接受连接但等待超过 5 秒才能应答的状态。
- 使用
init: true
启动您的容器.
我认为发生的情况取决于 Linux (Unix) 进程如何工作的一些非常具体的细节。 CMD-SHELL
健康检查由 Docker 作为容器进程命名空间中的附加进程注入(inject),方式与 docker exec
相同。 。但更具体地说,有两个进程:一个包装器 sh
运行命令管道的进程,以及 curl
命令作为子进程。
/bin/sh -c 'curl --fail http://localhost:8080 || exit 1'
+-- curl --fail http://localhost:8080
当达到超时时,Docker 将终止进程。不过,它并不具体了解子进程,因此它向 sh
发送信号。过程。如果它仍然没有终止,Docker 会向它发送 SIGTERM,相当于 kill -9
的 Unix 信号。 ,shell进程就不复存在了。
curl
会发生什么?过程?它的父级曾经是 sh
过程,但那已经消失了。这里的标准 Unix 规则是,它被移动为“init”进程的子进程,进程 ID 为 1。在 Docker 上下文中,主容器进程(如果有的话,则为 ENTRYPOINT
,如果有,则为 CMD
)不是)就是这个过程。
最终是curl
过程将完成,也许有自己的超时。这里的标准 Unix 规则是,大部分进程都会清理,但其进程表条目仍保留,并且其父进程可以等待(2) 并找出其状态代码。已退出但尚未等待的进程是“僵尸”进程;这是您的流程条目的长列表,其中包含 Z
在状态栏中和 <defunct>
在线的末尾。值得注意的是,这些不使用内存或文件句柄或其他资源,仅处理表条目。
这些东西的组合加起来是:容器中的主进程是进程ID 1;进程 ID 1 预计为“init”进程;进程ID 1有时会意外地让子进程附加到它,但它本身并没有启动,并且需要在它们之后进行清理(“收获僵尸”)。如果您的主进程是 Tomcat 服务器,并且它没有监视其他子进程(或 SIGCHLD 信号),那么您将以您所看到的方式泄漏进程。
撰写 init: true
选项将主容器命令包装在轻量级 init 进程中,默认 Tini 。如果进程 1 需要获取僵尸,Tini 就会这样做,并且它会处理一些围绕信号的情况。这几乎就是它的全部功能,但它是一个重要的功能。
关于 docker 组成 : hundreds of health check processes not terminated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77105400/