티스토리 뷰

반응형

참고.

 

컨테이너 빌드에 대한 권장사항  |  클라우드 아키텍처 센터  |  Google Cloud

의견 보내기 컨테이너 빌드에 대한 권장사항 이 문서에서는 컨테이너를 빌드하기 위한 권장사항을 설명합니다. 컨테이너를 더 쉽게 빌드(예: Cloud Build 사용)하고 Google Kubernetes Engine(GKE)에서 더

cloud.google.com

1. Signal이란?

  • 운영체제로부터, 특정한 Event 발생시 이를 알리기 위한 신호를 말함
  • 인터럽트의 일종이며, Docker Container에서는 컨테이너 내부의 프로세스 수명 주기를 제어하는 주요한 방법이다.
  • 리눅스에서는 프로세스끼리 통신을 위해 사용하기도 한다.
  • 시그널은 운영체제별로 다양한 종류를 지원한다.
    • 예시 : 
// macOS
[~] kill -l
HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2

// ubuntu
ubuntu:~$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX
  • 특히, Ctrl+C 또는 kill 등의 명령을 통한 프로세스 종료시에는 해당 프로세스에 "SIGTERM"이 전달된다.
    • kill -9를 주로 사용하는 것도 해당 프로세스에 SIGKILL을 보내기 위함이다.
  • 참고 : 
    • SIGKILL : 프로세스를 강제로 종료시키는 시그널
      • 프로세스가 정상적인 종료를 하지 못할 수 있음.
    • SIGTERM : 정상적인 종료를 유도하는 시그널
      • 가능한 한 프로세스의 정상 종료를 유도함.

 

2. Signal Handler?

  • 프로세스는 시그널을 받았을 때, 아래와 같은 방식 중 하나로 대응한다.
    • 프로세스는 일반적으로 시그널을 받았을 때 프로세스를 종료하는 방식으로 처리한다.
    • 무시하는 경우도 있지만, SIGKILL과 SIGSTOP은 무시될 수 없다.
    • 또는 프로그래머가 설정한 핸들러를 호출하는 방식으로 대응할 수도 있다.

 

3. Graceful Shutdown in Docker

  • 일반적인 서버 프로그램은 SIGTERM을 받을 경우, 현재 연결에 대한 작업을 마친 후에 종료한다.
    • 이는 일반적인 경우의 Graceful Shutdown에 해당한다.
    • Eureka에 등록된 서비스는 이 과정에서 등록 해제된다.
  • 그러나 Dockerfile에 정의된 Entrypoint가 Shell Script인 경우, Docker container로부터 발생한 SIGTERM을 루트 프로세스(PID 1)인 스크립트가 받기 때문에 Docker에서 실행된 서비스는 Graceful Shutdown 되지 않는다.
    • Shell script로부터 실행된 서버 프로세스는 Signal을 받지 못한 채 컨테이너 자체가 종료되므로, Eureka Server의 Eviction Timer에 의해 퇴거될 때까지 유레카 측에 서비스로서 남아있게 된다.

i). 예시 1. 정상 케이스

  • 1번 PID가 SIGTERM을 받아 Graceful Shutdown된다.
ec2-user@ip-00-00-00-00:~$ docker exec -it my-service-1 sh
/ # ps
PID   USER     TIME  COMMAND
    1 root      1:41 java ~중략
 1927 root      0:00 sh
 1933 root      0:00 ps

 

ii). 예시 2. 비정상 케이스

  • Eureka Server에 my-service-2가 클라이언트로서 등록된 경우를 가정하자.
  • 이 경우, 1번 PID가 my.sh이므로 SIGTERM을 my.sh이 받는다.
[~] docker exec -it my-service-2 sh 
/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 {my.sh} /bin/sh /my.sh
    6 root      0:33 java ~중략
   71 root      0:00 sh
   76 root      0:00 ps
/ #

 

4. about docker stop

  • docker stop은 실행 중인 컨테이너의 Root Process(=PID 1)에 SIGTERM을 보낸다.
  • 그럼에도 프로세스가 종료되지 않는다면, SIGKILL을 보낸다.
    • 참고.
 

Gracefully Stopping Docker Containers - CenturyLink Cloud Developer Center

Much of the focus of Docker is on the process of packaging and running your application in an isolated container. There are countless tutorials that explain how to run your application in a Docker container, but very few that discuss how properly stop your

www.ctl.io

  • 따라서 예시 2.에 발생했던 문제는
    • docker-compose down 과정에서 my-service-2 컨테이너에 SIGTERM 전송
    • SIGTERM을 Root Process(PID 1)인 my.sh이 받아 SIGTERM = Graceful Shutdown
    • 그러나 Eureka에 등록된 서비스인 my-service-2는 SIGTERM을 받지 못했으므로 종료 신호를 Eureka에 보내지 않음
    • Root Process 종료로 인해 my-service-2 컨테이너는 삭제되나, Eureka는 별도의 종료 신호를 받지 않았으므로 my-service-2를 퇴거시키지 않음
    • 결과 Eureka Server에 설정된 Eviction timer에 의해 my-service-2가 퇴거될 때까지 Eureka에 정보가 남게 된다.
  • 로 요약할 수 있다.
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함