发送SIGHUP
与
kill -HUP <pid>
我的本机系统上的
busybox sh
进程运行正常,并且 shell 挂起。但是,如果我使用 docker kill
将信号发送到docker kill -s HUP <container>
它什么也没做。 Alpine容器仍在运行:
$ CONTAINER=$(docker run -dt alpine:latest)
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Up 1 second
$ docker kill -s HUP $CONTAINER
4fea4f2dabe0f8a717b0e1272528af1a97050bcec51babbe0ed801e75fb15f1b
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Up 7 seconds
顺便说一下,使用Ubuntu容器(运行
bash
),它可以按预期工作:$ CONTAINER=$(docker run -dt debian:latest)
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Up 1 second
$ docker kill -s HUP $CONTAINER
9a4aff456716397527cd87492066230e5088fbbb2a1bb6fc80f04f01b3368986
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Exited (129) 1 second ago
发送
SIGKILL
确实可以,但是我宁愿找出SIGHUP
为什么不起作用的方法。更新:我将添加另一个示例。在这里,您可以看到
busybox sh
通常确实可以成功卡在SIGHUP
上:$ busybox sh -c 'while true; do sleep 10; done' &
[1] 28276
$ PID=$!
$ ps -e | grep busybox
28276 pts/5 00:00:00 busybox
$ kill -HUP $PID
$
[1]+ Hangup busybox sh -c 'while true; do sleep 10; done'
$ ps -e | grep busybox
$
但是,在Docker容器内运行相同的无限睡眠循环不会退出。如您所见,该容器仍在
SIGHUP
之后运行,并且仅在SIGKILL
之后退出:$ CONTAINER=$(docker run -dt alpine:latest busybox sh -c 'while true; do sleep 10; done')
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Up 14 seconds
$ docker kill -s HUP $CONTAINER
31574ba7c0eb0505b776c459b55ffc8137042e1ce0562a3cf9aac80bfe8f65a0
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Up 28 seconds
$ docker kill -s KILL $CONTAINER
31574ba7c0eb0505b776c459b55ffc8137042e1ce0562a3cf9aac80bfe8f65a0
$ docker ps -a --filter "id=$CONTAINER" --format "{{.Status}}"
Exited (137) 2 seconds ago
$
最佳答案
(我手头没有Docker env可以尝试。只是猜测。)
对于您的情况,docker run
必须正在运行busybox/sh
或bash
作为 PID 1 。
根据Docker doc:
关于SIGHUP
的 busybox / sh 和 bash 之间的区别-
在我的系统(Debian 9.6,x86_64)上,busybox/sh
和bash
的信号掩码如下:
busybox / sh:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 82817 0.0 0.0 6952 1904 pts/2 S+ 10:23 0:00 busybox sh
PENDING (0000000000000000):
BLOCKED (0000000000000000):
IGNORED (0000000000284004):
3 QUIT
15 TERM
20 TSTP
22 TTOU
CAUGHT (0000000008000002):
2 INT
28 WINCH
重击:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 4871 0.0 0.1 21752 6176 pts/16 Ss 2019 0:00 /usr/local/bin/bash
PENDING (0000000000000000):
BLOCKED (0000000000000000):
IGNORED (0000000000380004):
3 QUIT
20 TSTP
21 TTIN
22 TTOU
CAUGHT (000000004b817efb):
1 HUP
2 INT
4 ILL
5 TRAP
6 ABRT
7 BUS
8 FPE
10 USR1
11 SEGV
12 USR2
13 PIPE
14 ALRM
15 TERM
17 CHLD
24 XCPU
25 XFSZ
26 VTALRM
28 WINCH
31 SYS
如我们所见, busybox / sh 不处理
SIGHUP
,因此被忽略。 Bash 捕获SIGHUP
,因此docker kill
可以向其传递信号。然后Bash终止,因为根据其manual,“默认情况下,shell在收到SIGHUP
时退出”。2020年3月7日更新#1:
做了一个快速测试,我以前的分析基本上是正确的。您可以这样验证:
[STEP 104] # docker run -dt debian busybox sh -c \
'trap exit HUP; while true; do sleep 1; done'
331380090c59018dae4dbc17dd5af9d355260057fdbd2f2ce9fc6548a39df1db
[STEP 105] # docker ps
CONTAINER ID IMAGE COMMAND CREATED
331380090c59 debian "busybox sh -c 'trap…" 11 seconds ago
[STEP 106] # docker kill -s HUP 331380090c59
331380090c59
[STEP 107] # docker ps
CONTAINER ID IMAGE COMMAND CREATED
[STEP 108] #
如前所述,默认情况下
busybox/sh
不会捕获SIGHUP
,因此该信号将被忽略。但是在busybox/sh
明确捕获SIGHUP
之后,信号将传递给它。我还尝试了
SIGKILL
,是的,它将始终终止正在运行的容器。这是合理的,因为SIGKILL
不能被任何进程捕获,因此信号将始终传递到容器并杀死它。2020年3月7日更新#2:
您也可以通过这种方式(更简单)进行验证:
[STEP 110] # docker run -ti alpine
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps
/ # kill -HUP 1 <-- this does not kill it because linux ignored the signal
/ #
/ # trap 'echo received SIGHUP' HUP
/ # kill -HUP 1
received SIGHUP <-- this indicates it can receive SIGHUP now
/ #
/ # trap exit HUP
/ # kill -HUP 1 <-- this terminates it because the action changed to `exit`
[STEP 111] #
关于linux - 为什么SIGHUP在Alpine Docker容器中的busybox sh上不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60533390/