잡동사니
Doccker stop시 process kill하기 본문
안녕하세요. yeTi입니다.
오늘은 graceful shutdown
을 위한 docker container
를 종료시 시그널을 받아 처리하는 방안에 대해서 알아보겠습니다.
docker stop
docker stop
명령어는 컨테이너내의 메인 프로세스에 SIGTERM
과 SIGKILL
을 순차적으로 호출합니다.
신호의 전달은 graceful shutdown
을 위해 중요합니다.
하지만, 만일 서비스 프로세스가 메인 프로세스에서 구동할 수 없는 상황이라면 해당 프로세스는 종료 신호를 전달받지 못하여 서비스 종료를 위한 후처리가 불가능합니다.
이에 shell script
를 메인 프로세스로 두고 python
서비스에 종료 신호를 전달하는 방안을 알아보고자 합니다.
CMD의 3가지 형식
docker
에서 컨테이너를 실행하기 위한 명령어로 CMD
와 ENTRYPOINT
가 있습니다. 두개의 명령어 중에서 CMD
를 기반으로 형식에 따라 내부 프로세스구조가 어떻게 달라지는지 확인해보겠습니다.
전체적인 샘플코드는 다음과 같습니다.
# Dockerfile
FROM ubuntu
Add start-ho.sh /usr/src/app/start-ho.sh
RUN ["chmod", "+x", "/usr/src/app/start-ho.sh"]
CMD ["sh", "-c", "/usr/src/app/start-ho.sh"]
# CMD ["/usr/src/app/start-ho.sh"]
# CMD /usr/src/app/start-ho.sh
# start-ho.sh
#!/bin/bash
while [[ 1=1 ]]; do
echo "run"
sleep 1
done
위와 같이 작성한 코드를 컨테이너로 구동하면 내부 프로세서는 다음과 같이 생성됩니다.
$ docker exec -it ho-docker ps -x
PID TTY STAT TIME COMMAND
1 pts/0 Ss+ 0:00 sh -c /usr/src/app/start-ho.sh
6 pts/0 S+ 0:00 /bin/bash /usr/src/app/start-ho.sh
8 pts/0 S+ 0:00 sleep 1
9 pts/1 Rs+ 0:00 ps -x
메인 프로세스가 shell
이 되고 /usr/src/app/start-ho.sh
을 실행하으로 docker stop
에 대한 시그널을 start-ho script
에서 받을 수 없습니다.
Dockerfile
에서 CMD
를 다음과 같이 변경해 보겠습니다.
CMD ["/usr/src/app/start-ho.sh"]
컨테이너의 메인 프로세서로 샘플로 작성한 start-ho script
가 구동된것을 확인할 수 있습니다.
$ docker exec -it ho-docker ps -x
PID TTY STAT TIME COMMAND
1 pts/0 Ss+ 0:00 /bin/bash /usr/src/app/start-ho.sh
12 pts/0 S+ 0:00 sleep 1
13 pts/1 Rs+ 0:00 ps -x
마지막으로 다음을 수행해보면
CMD /usr/src/app/start-ho.sh
CMD ["sh", "-c", "/usr/src/app/start-ho.sh"]
과 마찬가지로 메인 프로세스가 shell
이 되고 /usr/src/app/start-ho.sh
를 실행하는것을 확인할 수 있습니다.
$ docker exec -it ho-docker ps -x
PID TTY STAT TIME COMMAND
1 pts/0 Ss+ 0:00 /bin/sh -c /usr/src/app/start-ho.sh
6 pts/0 S+ 0:00 /bin/bash /usr/src/app/start-ho.sh
8 pts/0 S+ 0:00 sleep 1
9 pts/1 Rs+ 0:00 ps -x
따라서 도커실행시 CMD ["/usr/src/app/start-ho.sh"]
형식으로 작성해야 shell script
에서 시그널을 받을 수 있습니다.
shell script에서 signal 잡기
shell script
에서 서비스를 백그라운드로 구동한 이후에 pid
를 가지고 있는 파일을 계속 관찰한 후 시그널이 들어오면 해당 pid
를 kill
하는 방식으로 샘플을 작성했습니다.
# kill_child.sh
python3 child.py &
trap "sigterm; exit" SIGTERM
function sigterm() {
echo "Catch SIGTERM"
echo "Try kill pid $value"
kill "$value"
}
while [[ 1=1 ]]; do
value=`cat deamon.pid`
sleep 1
done
python
으로 작성한 샘플 서비스는 pid
를 특정 파일에 저장합니다.
import time
import os
import sys
pid = str(os.getpid())
with open("deamon.pid", "w") as f:
f.write(pid)
while True:
print('running')
time.sleep(1)
'IT' 카테고리의 다른 글
컨테이너와 쿠버네티스 환경에 대한 이해 (0) | 2021.08.23 |
---|---|
임베디드환경에서 MQTT 사용해보기 (0) | 2021.02.22 |
Python 패키지 PyPI에 업로드하기 (0) | 2020.07.22 |
M-JPEG에 대해서 알아보자 (2) | 2020.07.17 |
Duplicate Targetframework attribute (0) | 2020.05.22 |