Open raphaelIl opened 2 years ago
import os
import subprocess
import signal
import time
class GracefulKiller:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
print('{} signal has been trapped.'.format(signum))
time.sleep(1)
self.kill_now = True
if __name__ == '__main__':
killer = GracefulKiller()
t = 0;
while True:
time.sleep(1)
t = t+1
print(str(t) + "sec")
if killer.kill_now:
break
print("graceful shutdown Done")
docker-compose kubernetes에서 어디서 sigterm을 날리는지 확인할것
dumb_init을 이용하면 signal을 trap하여 하위 프로세스에게 전달할 수 있다.
TL;DR
목표
이미 들어온 트래픽이 있는 와중에 새로운 배포프로세스가 실행될때 우아한 종료는 어떻게 될런지 정리해본다.
Kubernetes의 Pod Termination 과정은 요약하면
Config
Application
Enable Graceful shutdown
Actuator Shutdown API
Kubernetes
preStop
shutdown api는 get이 아닌 post를 사용해야 한다.
위와 아래의 차이는 생각보다 컸다.
main process는 왜 SIGTERM을 감지하지 못하나
갑자기 pid를 왜 언급하냐면 container 레벨에서 pid는 1번이여야한다. graceful 설정을 했음에도 감지하지 못하는 이유는 컨테이너 pid1(main process)가 was 프로세스가 아니라 컨테이너 프로세스이기 때문이다
해결책은 child process로 trap 해야할 signal을 전달하거나 구조를 변경하거나.. SIGTERM을 catch해서 처리하는게 근본적인 해결방법이라 생각되나 그러기엔 배포 파이프라인에서 변경해야할게 너무 많았다.
dockerfile을 변경하면 된다, 왜 이걸 하기 싫었나면 레거시 버전에서 잘될것인지 확인해야 했는데 생각보다 쉽게 확인할 수 있었다.
참고 사항