를 실행 docker stop ...
하면 몇 가지 일이 발생합니다 .
docker
SIGTERM
컨테이너의 기본 프로세스로를 보냅니다 . 프로세스는 a를 마스킹 / 무시할 수 있으며 SIGTERM
, 그렇지 않으면 " 아무것도 "발생 하지 않습니다 .
- 시간 초과 (기본값 10 초) 후 a 를 기본 프로세스로
docker
보냅니다 SIGKILL
. 이 신호는 프로세스에 의해 마스킹 될 수 없으므로 종료 절차를 실행할 기회없이 즉시 죽습니다.
이상적으로 내부에서 실행되는 프로세스 docker
는 SIGTERM
종료하기 전에 모든 하우스 키핑을 관리하여 적시에 응답합니다 .
프로세스에 수행 할 하우스 키핑이 없거나 (예 sleep
:) 제대로 응답하지 않는 SIGTERM
경우 -t
플래그를 사용하여 더 짧은 (또는 더 긴) 시간 초과를 지정할 수 있습니다 .
-t, --time=10
Seconds to wait for stop before killing it
예를 들어, 귀하의 경우에는을 실행할 수 있습니다 docker stop -t 0 ${CONTAINER}
.
이 신호 동작이 다른 이유는 sleep
PID = 1로 실행 하기 때문 입니다.
일반적으로 (예 :! PID 실행 = 1), 프로세스가 명시 적으로 프로세스 리드를 처리하지 않는 어떤 신호가 종료되고 - 송신 시도 sleep
을 SIGUSR1
.
그러나 PID = 1로 실행할 때 처리되지 않은 신호는 무시되고 그렇지 않으면 커널 패닉이 발생합니다.
Kernel panic - not syncing: Attempted to kill init!
도커 도구를 사용하여 도커 컨테이너에 신호를 보낼 수 있습니다. 예를 들면 다음과 같습니다.
docker kill -s TERM kill-sleep
우리가 볼 수 있듯이 이것은 원하는 효과가 없지만 다음과 같습니다.
docker kill -s KILL kill-sleep
실험
도커 파일
FROM busybox
COPY run.sh /run.sh
RUN chmod +x /run.sh
CMD "/run.sh"
run.sh
#!/bin/sh
echo "sleeping"
sleep 100000
이제 실행
docker build -t kill-sleep .
docker run --rm --name kill-sleep kill-sleep
그리고 이것은 다른 터미널에서 :
docker stop kill-sleep
동일한 10 초 지연 / 시간 초과를 관찰합니다.
해결책
이제를 처리하겠습니다 SIGTERM
. 배경 처리 및 wait
대한 보내고 것은 sleep
POSIX 표준 쉘 신호를 처리하는 방법에 기인한다 (참조 ,이 이상을).
run.sh
#!/bin/sh
die_func() {
echo "oh no"
sleep 2
exit 1
}
trap die_func TERM
echo "sleeping"
sleep 100000 &
wait
명령을 다시 실행하면 우리가 무엇을하는지 볼 수 있습니다!
$ time docker stop kill-sleep
kill-sleep
real 0m2.515s
user 0m0.008s
sys 0m0.044s