728x90
728x90
# Graceful Shutdown이란?
- 현재 들어온 요청을 모두 수행하고 우아하게 종료한다 ... 는 개념
- 예를 들어, A deployment가 restart 된다고 할 때 pod B가 죽고 pod C가 새로 떠야한다고 가정해보자
- service에서 pod B -> pod C 엔드포인트 변경을 해줘야 하는데, 이게 조금 늦을 수 있음
- 그러면 pod B는 종료되어야 하지만 여전히 pod B로 트래픽이 흘러들어갈 수 있음
- -> pod B의 Application은 새로운 요청 수락만 먼저 중지하고, 모든 연결이 종료된 다음에 죽어야 함
- 또 다른 예시로, pod가 특정 DB와 connection을 맺고 있는 경우 해당 연결을 종료하고 죽어야 함
# Pod 종료 순서
- 사람 또는 시스템 : Pod 종료 API 발생시킴
kube-apiserver
: etcd에 저장된 pod의 상태를 Terminating으로 변경kubelet
: pod의 Terminating 상태 감지kubelet
: Terminating pod의 컨테이너에preStop
훅이 존재한다면 해당 훅 실행kubelet
:preStop
훅 완료 후 각 컨테이너에SIGTERM
시그널 전송 (정상적인 종료 절차 밟으라고 요청하는 것)- 각 containers : 정리 작업 수행 후 종료
- 이 때, 종료기간(
terminationGracePeriodSeconds
) 내로 종료되지 않은 컨테이너들에겐SIGKILL
날라감 (강제 종료) kubelet
: 컨테이너들이 모두 종료되면api-server
에 pod 종료 상태 보고kube-apiserver
: etcd에서 해당 pod 삭제
우리가 볼 구간은 4 ~ 7 번이다.
## terminationGracePeriodSeconds 란?
- kubernetes에서 Pod를 안전하게 종료하기 위해 사용하는 설정 값
- 즉, kubelet이
SIGTERM
신호을 보낸 후부터 완전히 종료될 때까지 기다리는 시간(초)이다. - 해당 시간이 끝나면
SIGKILL
신호를 보내 Pod를 종료한다.
## preStop이란?
- kubectl delete pod 또는 관리 이벤트 등과 같은 종료 명령을 받으면 바로 실행된다.
- 어플리케이션에서 Graceful Shutdown 로직을 구현하지 않았을 때 Pod의 Yaml파일에서 간단히 설정할 수 있는 방법이다.
## 주의
preStop
은 terminationGracePeriodSeconds
시간보다 짧게 소요되어야 한다.
# 그래서 작성하는 방법은?
Application단에서 graceful shutdown을 쉽게 구현 가능하다면 (ex, springboot) 그게 제일 좋고,
그게 힘든 경우는 아래처럼 preStop
으로 sleep
커맨드를 넣어주자
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
lifecycle:
preStop:
exec:
command:
- sleep
- 10
# (추가) SIGTERM & SIGKILL - 유명한 그림
출처 : https://linuxhandbook.com/sigterm-vs-sigkill/
# Ref
- https://wangwei1237.github.io/Kubernetes-in-Action-Second-Edition/docs/Understanding_the_pod_lifecycle.html
- https://jenakim47.tistory.com/80
- https://foxutech.medium.com/kubernetes-pod-graceful-shutdown-how-a9a46e0b1e53
끝!
728x90
728x90
댓글