(у меня нет Docker env под рукой для попытки. Просто угадаю.)
В вашем случае docker run
должен работать busybox/sh
или bash
как PID 1 .
Согласно Docker do c:
Примечание: процесс, выполняющийся как PID 1 внутри контейнера обрабатывается специально Linux: он игнорирует любой сигнал с действием по умолчанию. Таким образом, процесс не завершится на SIGINT
или SIGTERM
, если он не закодирован для этого.
Разница между busybox / sh и bash относительно SIGHUP
---
в моей системе (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
bash:
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 завершается, потому что, согласно руководству , "оболочка по умолчанию завершает работу при получении SIGHUP
" .
ОБНОВЛЕНИЕ 2020-03-07 # 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-03-07 # 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] #