도커 컨테이너 실행 절전을 중지하려면 어떻게해야합니까? 복잡한 프로세스를위한 것입니다. 이 Dockerfile

sleep 물론 가장 복잡한 프로세스를위한 것입니다.

이 Dockerfile (exec 양식을 사용하여 볼 수 있듯이 하나의 프로세스 만 실행되고 하위는 없습니다 bash) :

FROM busybox
CMD ["/bin/sleep", "100000"]

무정전 컨테이너를 만듭니다.

docker build -t kill-sleep .
docker run --rm --name kill-sleep kill-sleep

내가 멈추려 고 할 때 :

time docker stop kill-sleep

kill-sleep
real    0m10.449s
user    0m0.021s
sys     0m0.027s

컨테이너가 종료되기 전에 명령이 10 초에 시간 초과됩니다.

문제는 sleep호스트에서 신호를 실행하면 신호를 처리하지 않습니다.

sleep 100000
# in another shell
ps faxww | grep sleep
kill -TERM 31333  # the PID

프로세스가 즉시 중지됩니다.

컨테이너에서 PID 1로 실행되고 있다는 사실과 문제가있을 수 있지만 아직 참조 문서를 보지 못했습니다.



답변

를 실행 docker stop ...하면 몇 가지 일이 발생합니다 .

  1. dockerSIGTERM컨테이너의 기본 프로세스로를 보냅니다 . 프로세스는 a를 마스킹 / 무시할 수 있으며 SIGTERM, 그렇지 않으면 ” 아무것도 “발생 하지 않습니다 .
  2. 시간 초과 (기본값 10 초) 후 a 를 기본 프로세스로 docker보냅니다 SIGKILL. 이 신호는 프로세스에 의해 마스킹 될 수 없으므로 종료 절차를 실행할 기회없이 즉시 죽습니다.

이상적으로 내부에서 실행되는 프로세스 dockerSIGTERM종료하기 전에 모든 하우스 키핑을 관리하여 적시에 응답합니다 .

프로세스에 수행 할 하우스 키핑이 없거나 (예 sleep🙂 제대로 응답하지 않는 SIGTERM경우 -t플래그를 사용하여 더 짧은 (또는 더 긴) 시간 초과를 지정할 수 있습니다 .

-t, --time=10
    Seconds to wait for stop before killing it

예를 들어, 귀하의 경우에는을 실행할 수 있습니다 docker stop -t 0 ${CONTAINER}.


이 신호 동작이 다른 이유는 sleepPID = 1로 실행 하기 때문 입니다.

일반적으로 (예 :! PID 실행 = 1), 프로세스가 명시 적으로 프로세스 리드를 처리하지 않는 어떤 신호가 종료되고 – 송신 시도 sleepSIGUSR1.

그러나 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대한 보내고 것은 sleepPOSIX 표준 쉘 신호를 처리하는 방법에 기인한다 (참조 ,이 이상을).

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


답변