본문 바로가기

개발관련/Kubernetes

쿠버네티스 Pod의 우아한 셧다운(Graceful shutdown of Pod with Kubernetes)

반응형

쿠버네티스에서 새로운 버전의 Pod를 배포할 때, blue-green 방식으로 Rolling update된다.

따라서 기존 Pod를 삭제하고 새로운 Pod로 트래픽을 절체하게 된다.

이 때, 기존 Pod 내부에서 돌아가고 있는 어플리케이션(예를 들어 백엔드 어플리케이션)의 Task가 모두 완료되지 않은 상태에서 기존 Pod를 삭제하게 된다면, 해당 Task 혹은 세션이 만료되지 않은 상태이기 때문에 애플리케이션 레이어의 네트워크 에러 및 장애가 발생할 수 있다.

이는 굉장히 위험할 수 있기 때문에(결제와 관련된 Task의 경우) 반드시 기존 Task를 모두 완료한 상태에서 기존 Pod를 삭제하도록 해야 한다.

 

 

 

일단 Pod의 종료 이벤트에 대해서 알아보자. 참고

 

Pod의 종료 이벤트 순서는 Pod를 시작하는 동안의 이벤트와 유사하다.

사용자가 Pod를 삭제하도록 요청하면 쿠버네티스 시스템은 Pod가 강제로 종료되기 전에 예정된 유예 기간을 기록하고 SIGTERM 신호를 컨테이너의 주 프로세스로 전송한다.(기본 유예 기간은 30초 이다.)

유예 기간이 만료되어도 Pod가 삭제되지 않으면 SIGKILL 신호가 해당 프로세스로 전송되고 Pod가 API 서버에서 삭제된다.(이런 경우는 보통 Pod의 작업이 완료되지 않았기 때문일 수 있다.)

 

 

 

디테일한 흐름 예시를 보자.

  1. 사용자가 Pod 삭제 명령을 내린다. (기본 유예 시간 30 초)
  2. API 서버 안의 Pod는 유예 기간에 따라 시간을 넘은 것(죽은 것)으로 간주되는 Pod가 업데이트 된다.
  3. 사용자 명령에서 Pod는 Terminating 이라는 문구를 나타낸다.
  4. (3번 단계와 동시에) kubelet은 Pod가 2번 단계에서 설정된 시간으로 인해 Terminating으로 표시되는 것을 확인하면 Pod 종료 단계를 시작한다.
    1. Pod의 컨테이너 중 하나에 preStop hook이 정의된 경우, 해당 컨테이너 내부에서 실행된다. 유예 기간이 만료된 후에도 preStop hook이 계속 실행중이면, 유예 기간을 짧게(2초)를 1회 연장해서 2번 단계를 실행한다.
    2. Pod의 프로세스에 SIGTERM 신호가 전달된다. Pod의 모든 컨테이너가 SIGTERM 신호를 동시에 받기 때문에 컨테이너의 종료 순서가 중요한 경우에는 preStop hook이 각각 필요할 수 있음을 알아두자. 만약 preStop hook을 완료하는 데 더 오랜 시간이 필요한 경우 terminationGracePeriodSeconds를 수정 혹은 설정해야 한다.
  5. (3번 단계와 동시에) Pod는 서비스를 위해 엔드포인트 목록에서 제거되며, 더 이상 레플리케이션 컨트롤러가 실행중인 Pod로 고려하지 않는다. 느리게 종료되는 Pod는 로드밸런서(서비스 프록시와 같은)의 로테이션에서 지워지기 때문에 트래픽을 계속 처리할 수 없다.
  6. 유예 기간이 만료되면, Pod에서 실행중이던 모든 프로세스가 SIGKILL로 종료된다.
  7. kubelet은 유예기간 0(즉시 삭제)을 세팅하여 API 서버에서 Pod 삭제를 끝낼 것이다. API 서버에서 사라진 Pod는 클라이언트에게서 더 이상 보이지 않는다.

 

 

기본적으로 모든 삭제는 30초 이내에 끝이 난다.

kubectl delete 명령은 사용자가 기본 설정을 오버라이드 하고 자신이 원하는 값을 설정할 수 있게 해주는 --grace-period=<seconds> 옵션을 지원한다. 0값은 파드를 강제로 삭제한다. kubectl 버전 >= 1.5 에서는, 강제 삭제 수행을 위해서 반드시 --grace-period=0와 함께 추가 플래그인 --force를 지정해야 한다.

 

 

 

*preStop hook

이 훅은 API 요청이나 활성 프로브(liveness probe) 실패, 선점, 자원 경합 등의 관리 이벤트로 인해 컨테이너가 종료되기 직전에 호출된다. 컨테이너가 이미 terminated 또는 completed 상태인 경우에는 preStop 훅 요청이 실패한다. 그것은 동기적인 동작을 의미하는, 차단(blocking)을 수행하고 있으므로, 컨테이너를 삭제하기 위한 호출이 전송되기 전에 완료되어야한다. 파라미터는 핸들러에 전달되지 않는다.

종료 동작에 더 자세한 대한 설명은 파드의 종료에서 찾을 수 있다.

 


참고

 

파드

 

kubernetes.io

 

 

Attach Handlers to Container Lifecycle Events

 

kubernetes.io

 

 

컨테이너 라이프사이클 훅(Hook)

 

kubernetes.io

 

 

Graceful shutdown of pods with Kubernetes

19 Aug 2016 by Marco Pracucci Docker containers can be terminated any time, due to an auto-scaling policy, pod or deployment deletion or while rolling out an update. In most of such cases, you will probably want to graceful shutdown your application runnin

pracucci.com

 

 

DevOps with Kubernetes

Hideto Saito has around 20 years of experience in the computer industry. In 1998, while working for Sun Microsystems Japan, he was impressed with Solaris OS, OPENSTEP, and Sun Ultra Enterprise 10000 (AKA StarFire). Then, he decided to pursue the UNIX and m

books.google.co.kr

 

 

Termination Signals (The GNU C Library)

The SIGQUIT signal is similar to SIGINT, except that it’s controlled by a different key—the QUIT character, usually C-\—and produces a core dump when it terminates the process, just like a program error signal. You can think of this as a program erro

www.gnu.org

 

반응형