쿠버네티스 패턴 - 5장 수명주기 관리
👉 수명주기 관리
클라우드 네이티브 플랫폼에서 컨테이너화 된 어플리케이션을 잘 관리하기 위해서는
관리 플랫폼에서 생성되는 이벤트를 통해서 어플리케이션의 수명 주기를 조절해야합니다.
수명 주기 패턴은 쿠버네티스에서 사용하는 파드와 컨테이너의 수명주기를 파악하고
어떻게 관리하는지에 대해 설명합니다.
🍏 문제점
쿠버네티스 패턴 - 4장 정상상태 점검을 통해서 쿠버네티스가 어떻게 컨테이너에 대한 상태를 파악하는지에 대해 설명하였습니다.
또한 Container Probe를 통해서 컨테이너에 대한 조치까지 알아보았습니다.
하지만 파드가 시작할 때 Probe로 상태를 확인하는 것 뿐만아니라 특정 커맨드 작업을 수행해야할 수 도 있므며, 컨테이너에 대한 Probe가 실패할 경우 컨테이너가 정상적으로 종료하기 위한 작업이 필요할 수 있습니다.
클라우드 네이티브 플랫폼에서는 컨테이너화된 어플리케이션을 특정 이벤트로 관리할 수 있어야 하며, 이를 통해서 수명주기를 관리할 수 있어야 합니다.
🍏 해결책
쿠버네티스는 컨테이너화된 어플리케이션을 관리하기 위해 Lifecycle을 나누어 단계를 구분하고 특정 이벤트를 호출합니다.
이를 위해 관리하는 기본적인 단위는 파드이며, 컨테이너들의 집합이라고 할 수 있습니다.
👍 따라서 파드와 컨테이너의 Lifecycle을 파악하여 언제 무엇이 실행되고 언제 어떻게 종료되는지 알아야합니다.
이를 위해서 가장 먼저 파드와 컨테이너의 상태를 알아보도록 하겠습니다.
Pod's phase
Pod는 총 5가지의 단계를 가지고 있습니다.
이 단계는 kubectl get pod
로 알 수 있으며 파드의 상태를 파악할 수 있습니다.
1) pending
- API 서버가 Pod의 Resource를 생성하여 etcd에 저장 완료
- 아직 Pod가 Schedule 되지 않았거나, 컨테이너 이미지 다운로드가 완료되지 않은 상태
2) Running
- Pod가 Node에 Schedule 완료
- kubelet에 의해 모든 컨테이너 생성 완료
- 적어도 하나의 컨테이너가 실행 중이거나, 시작 또는 재시작 중에 있음
3) Succeeded
- Pod의 모든 컨테이너가 성공적으로 종료
- Pod의 모든 컨테이너가 재시작 되지 않음
4) Failed
- Pod의 모든 컨테이너가 종료되었으며, 적어도 하나 이상이 실패로 종료
- 실패한 컨테이너는 non-zero 상태로 나왔거나, 시스템에 의해서 종료 되었음
5) Unknwon
- 파드의 상태를 알 수 없는 경우
- 일반적으로 kubelet과 통신하는 중 오류가 발생하여 API Server에서 Pod의 상태를 쿼리할 수 없는 경우가 많음
👌 Terminating : 해당 상태는 Pod의 단계로 포함하지 않으며, gracefully 종료 중임을 나타냅니다.
이를 위해 시간이 부여되며 기본값은 30초입니다. 강제로 파드를 종료하려면--force
플래그를 설정하면 됩니다.
Container Status
파드의 단계를 알았다면 내부적으로 컨테이너가 어떤 상태인지 알아야합니다.
컨테이너의 상태를 알기 위해서는 kubectl describe pods
를 통해서 파악할 수 있습니다.
1) Wating
Running
orTerminated
가 아니면Watining
상태- 컨테이너의 시작을 완료하는 데 필요한 작업을 진행하는 상태
- 예시로 컨테이너 이미지를 다운로드 중이거나, Secret 데이터를 적용하는 작업이 있음
- kubectl 을 통해서 파드를 쿼리할 때
Wating
상태인 경우 이유를 요약하는 Reason 필드도 표시
2) Running
- 컨테이너가 문제없이 실행되고 있음을 나타냄
- kubectl 을 통해서 파드를 쿼리할 때
Running
상태에 진입한 시기를 볼 수 있음
3) Terminated
- 컨테이너가 실행을 시작한 후 완료되었거나, 어떤 이유로 실패한 상태를 나타냄
- kubectl 을 통해서 파드를 쿼리할 때 종료 이유 및 종료 코드와 컨테이너의 시작과 종료 시간이 표시됨
Container Lifecycle Hook
쿠버네티스도 컴포넌트 Lifecycle Hook을 가진 프로그래밍 언어 프레임워크와 같이 Lifecycle Hook을 제공합니다.
특히 Hook은 Pod의 Lifecycle 과정에 포함되므로 이 글에서 같이 설명하도록 하겠습니다.
1) Hook Handler
Probe와 같이 Container Lifecycle Hook을 위한 Handler가 존재합니다.
Hook Handler는 두 가지가 있으며 다음 yaml을 통해서 보겠습니다.
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
httpGet:
port: 8080
path: /postStart
preStop:
exec:
command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
httpGet
컨테이너의 특정 엔드포인트에 대해서 HTTP 요청을 실행합니다.
해당 예시에서는 컨테이너 IP:8080/postStart
로 HTTP 요청을 실행합니다.
exec
컨테이너의 cgroups와 namespace 안에서, 특정 커맨드를 실행합니다.
해당 예시에서는 컨테이너 내에서 /bin/sh -c nginx -s quit; while killall -0 nginx; do sleep 1; done
을 실행합니다.
2) postStart Hook
개념
- 컨테이너가 생성된 직후에 실행되는 Hook 으로 메인 컨테이너와 Async 로 실행됨
- Blocking call이며 완료될 때까지는 컨테이너 상태가
Wating
이며, Pod는Pending
상태
사용
- 컨테이너 프로세스의 초기화 시간을 벌기 위해 컨테이너의 시작 상태를 지연시키는 데 사용
- 파드가 어떤 전제조건을 충족하지 못했을 때 컨테이너가 시작되지 않도록 하기 위해 사용
주의 사항
- Entrypoint 와 Async 로 동작하며, 파라미터가 Handler에 전달되지 않음
3) preStop Hook
개념
- 컨테이너가 종료되기 직전에 실행되는 Hook
- Blocking call이며 Liveness Probe 실패, 선점, 자원 경합의 요인으로 종료될 때 실행
사용
- 데이터베이스 및 WebSocket 연결 중지, 현재 상태 저장 등을 수행하여 깨끗하게 종료 될 수 있도록 할 때 사용
주의 사항
- 컨테이너의 상태가
Terminated
orCompleted
상태인 경우 preStop Hook은 실패 함 - SIGTERM 과 Async 로 동작하지 않으며,
terminationGracePeriodSeconds
가 만료된 후 SIGKILL 을 통해 종료함
4) Hook delivery guarantees
- Hook Delivery는 한 번 이상으로 의도되어 있어 여러 번 호출 될 수 있음
- 일반적으로 한번이지만 Hook을 전송하는 도중에 kubelet이 재시작되는 경우와 같이 재전송 될 가능성이 있음
Activation lifecycle
컨테이너를 안전하게 시작하기 위해서 Activation lifecycle을 알아야합니다.
다음 단계를 통해서 설명하도록 하겠습니다.
1) Init Container
- 파드가 Schedule 된 후 어플리케이션 컨테이너들이 실행되기 전에 실행되는 특수한 컨테이너
- 어플리케이션 이미지에 없는 유틸리티 또는 설정 스크립트를 포함할 수 있음
- 항상 완료되는 것을 목표로 실행되며, 성공적으로 완료되지 못하면 반복적으로 재시작함
👌 Init Container는 쿠버네티스 패턴 - 14장 초기화 컨테이너 에서 자세하게 설명할 예정입니다.
2) Container start & postStart Hook
- Init Container가 완료되면 어플리케이션 컨테이너가 실행됨
- 이때 메인 컨테이너와 postStart Hook은 동시에 Async로 실행됨
- 메인 컨테이너가 잘 실행되어도 postStart Hook이 완료되지 않으면 컨테이너 상태가
Wating
이며, Pod는Pending
상태
Termination lifecycle
컨테이너를 안전하게 종료하기 위해서 Termination lifecycle을 알아야합니다.
다음 단계를 통해서 설명하도록 하겠습니다.
1) Start terminating
- Pod의 State를
Terminating
으로 바꿈 - Endpoint list에서 Pod를 제거하여 새로운 traffic 차단
- 컨테이너는 여전히 Pod 내에서 실행 중인 상태
2) Grace Period
- Gracefully Termination을 위해 기본적으로 30초를 기다림
- preStop Hook, SIGTERM signal과 병렬적으로 수행되어 끝나지 않아도, 시간이 지나면 SIGKILL signal 발생
- Pod yaml에서
TerminationGracePeriodSeconds
옵션을 설정하여 변경 가능
3) preStop Hook
- Pod에 구현되어있는 preStop Hook을 실행
- 컨테이너가 SIGTERM signal을 수신하기 전에 완료되어야 함
4) SIGTERM signal
- 쿠버네티스가 컨테이너를 멈추기 위해 보내는 신호
- 해당 신호를 통해 컨테이너가 곧 종료될 것임을 알림
- 데이터베이스 및 WebSocket 연결 중지, 현재 상태 저장 등을 수행하여 깨끗하게 종료 될 수 있도록 함
5) SIGKILL signal
- 컨테이너 프로세스를 강제로 종료하는 signal
- Grace Period 후에도 컨테이너 프로세스가 종료되지 않는다면 해당 signal을 통해서 강제 종료함
🍏 정리
이번 글에서 살펴본 것은 Pod 및 Container의 상태와 단계를 알아보았으며,
Pod가 시작되는 것부터 종료될 때까지의 Lifecycle을 알아보고 특정 이벤트에 대해서 알아보았습니다.
이 내용을 정리하면 다음과 같은 그림이 될 것입니다.
클라우드 네이티브 플랫폼에서 실행되는 어플리케이션을 잘 관리하기 위해서는 Lifecycle을 알고 특정 이벤트를 통해서 관리해야합니다.
이렇게 된다면 어플리케이션의 자동화가 사람을 통해서가 아닌 플랫폼에 의해서 될 것입니다.
👉 Reference
- 쿠버네티스 패턴, ©2020 빌긴 이브리암, 롤란트 후스 지음, 안승규, 서한배 옮김, 책만, 9791189909123
- 파드의 라이프사이클
- 컨테이너 라이프사이클 훅
- A Pod's Life
- Kubernetes best practices: terminating with grace
- Graceful Shutdown of Spring Boot Applications in Kubernetes
- Pod Lifecycle, Container Lifecycle, Hooks and restartPolicy
- Attach Handlers to Container Lifecycle Events
Author And Source
이 문제에 관하여(쿠버네티스 패턴 - 5장 수명주기 관리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@jayoh/쿠버네티스-패턴-5장-수명주기-관리
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Author And Source
이 문제에 관하여(쿠버네티스 패턴 - 5장 수명주기 관리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jayoh/쿠버네티스-패턴-5장-수명주기-관리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)