我使用 alpine 镜像运行了一个容器,并timeout
在其中运行了一个命令。timeout
命令运行后,alpine 中留下了一个死进程,我无法使用 kill 命令杀死它。我的执行流程如下:运行一个 alpine 容器
# cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.20.0
PRETTY_NAME="Alpine Linux v3.20"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
使用timeout
执行命令
# timeout -k 10 5 /bin/sleep 20
Terminated
此后,容器中会留有一个超时的死进程,并且无法通过 kill 将其杀死。
# ps -ef
PID USER TIME COMMAND
1 root 0:00 sleep infinity
18 root 0:00 sh
33 root 0:00 [timeout]
36 root 0:00 ps -ef
# kill -9 33
# ps -ef
PID USER TIME COMMAND
1 root 0:00 sleep infinity
18 root 0:00 sh
33 root 0:00 [timeout]
37 root 0:00 ps -ef
超时版本
# timeout --help
BusyBox v1.36.1 (2024-05-21 13:38:37 UTC) multi-call binary.
Usage: timeout [-s SIG] [-k KILL_SECS] SECS PROG ARGS
Run PROG. Send SIG to it if it is not gone in SECS seconds.
Default SIG: TERM.If it still exists in KILL_SECS seconds, send KILL.
最有可能的是,超时进程的父进程在超时进程之前终止,因此无法等待它。当进程的父进程在其子进程之前死亡时,子进程将处于孤立状态并被 pid 为 1 的进程收养。这通常是 init 进程,其在启动系统后的主要任务是等待此类孤立进程的终止,但容器不一定有这样的 init 进程(有关这方面的一些讨论,请参阅https://stackoverflow.com/questions/49162358/docker-init-zombies-why-does-it-matter 。)
使用
--init
命令选项docker run
应该可以解决这个问题。