시작하며

쿠버네티스에서 애플리케이션을 안정적으로 운영하려면 배포 전략과 Pod의 상태 변화를 잘 이해해야 한다. 이 글에서는 롤링 업데이트, 블루-그린 배포, Pod 라이프사이클, HPA 오토스케일링에 대해 정리한다.

Deployment를 통한 롤링 업데이트

운영 중인 앱의 경우 보통 Deployment를 생성하고, 그 안에 속한 ReplicaSet이 포드를 생성하는 것이 일반적이다. 이때 revision(--record 옵션)을 통해 원하는 버전의 앱으로 롤백할 수 있다.

Recreate 방식은 기존 버전의 포드를 전부 삭제한 뒤 새로운 버전의 포드를 생성하는 방식이다. RollingUpdate의 경우 디플로이먼트를 업데이트하는 도중에도 사용자의 요청을 처리할 수 있는 포드가 계속 존재한다.

  • maxUnavailable: 업데이트 중 사용 불가능한 포드의 최대 수
  • maxSurge: 업데이트 중 추가로 생성할 수 있는 포드의 최대 수

블루-그린 배포

블루-그린 배포는 기존 버전의 포드를 그대로 놔둔 상태에서 새로운 버전의 포드를 미리 생성해 두고 서비스의 라우팅만 변경하는 배포 방식이다. Service의 라벨을 변경하는 방식을 사용하면 쿠버네티스에서도 간단하게 구현할 수 있다.

Pod 라이프사이클

1) Pending
2) Running
    - Init Container : 시작 단계
    - postStart : 컨테이너 실행/삭제 특정 작업 수행
    - livenessProbe, readinessProbe : 상태 검사
3) Completed
4) Error
5) Terminating

Init Container가 차례대로 실행되고 → 컨테이너 내부에서 postStart 훅이 실행되고 나서야 → Pod가 Running 상태로 바뀐다.

그 다음 단계로, 사용자의 요청을 처리할 수 있는 상태인지를 판별하는 것이 livenessProbe와 readinessProbe이다.

  • livenessProbe: 컨테이너 내부 앱이 살아있는지(liveness) 검사
  • readinessProbe: 내부 앱이 사용자 요청을 처리할 준비가 됐는지(readiness) 검사

반대로 Terminating의 경우는 다음과 같은 작업들이 이루어진다.

deletionTimestamp(리소스 삭제 예정을 의미하는 값)이 포드의 데이터에 추가 → 포드는 Terminating으로 바뀜 →

  1. preStop 훅 실행
  2. 레플리카 관리 영역에서 벗어남
  3. 라우팅 대상에서 제외됨

→ SIGTERM이 컨테이너로 전달(이때 init 프로세스 종료) → 이후에도 종료되지 않으면 SIGKILL 시그널이 전달되어 강제 종료

HPA 오토스케일링

HPA(Horizontal Pod Autoscaler)는 리소스 사용량에 따라 디플로이먼트의 포드 개수를 자동으로 조절하는 기능이다.

다만 잠시 동안만 CPU를 소모하는 JVM 기반 애플리케이션의 경우, 포드 생성 시간이 아닌 CPU 사용률을 기준으로 오토스케일링을 진행하기 때문에 불필요하게 포드가 계속 스케일아웃될 수 있고, 포드가 증식하는 연쇄 작용을 불러일으킬 수도 있다.

복습 Q&A

Q1. 쿠버네티스는 포드를 생성할 때, master node에 디폴트로 설정된 어떤 개념을 통해 worker node에 포드가 할당되게 하는가? A1. Taint

Q2. NoSchedule과 NoExecute의 차이는 무엇인가? A2. NoSchedule은 노드에 설정하더라도 기존에 실행 중인 포드는 정상적으로 동작한다. 하지만 NoExecute의 경우 스케줄링도 하지 않을 뿐더러, 별도의 toleration이 설정되어 있지 않다면 해당 노드에서 실행 중인 포드를 아예 종료시킨다.

Q3. drain 등으로 Eviction이 발생할 때, drain되는 포드 개수를 1개로 유지하려면? A3. PodDisruptionBudget을 정의하고 maxUnavailable(혹은 minAvailable을 n-1로) 값을 1로 세팅한다.

Q4. 운영 중 버전 관리를 위해 Deployment에서 관리하는 ReplicaSet 변경 사항을 저장한 것을 무엇이라 하는가? A4. revision

Q5. Pod 상태가 Running이 되기 위해 내부적으로 어떤 동작들이 이루어져야 하는가? A5. Init Container 실행, postStart 훅 실행

Q6. Pod가 Terminating 상태가 된 후 유예 기간이 지나도 종료되지 않을 때 전달되는 시그널은? A6. SIGKILL

Q7. HPA를 통한 오토스케일링을 위해 별도로 설치해야 하는 도구와 이유는? A7. metrics-server. 사용 중인 자원량(CPU, Memory 등)에 대한 정보를 쿠버네티스가 자체적으로 수집하지는 못하기 때문이다.

정리하며

쿠버네티스의 배포 상태 관리는 롤링 업데이트와 블루-그린 방식을 상황에 맞게 선택하는 것에서 시작한다. Pod 라이프사이클의 각 단계와 livenessProbe/readinessProbe의 역할을 이해하면 안정적인 운영이 가능하며, HPA를 활용할 때는 JVM 기반 애플리케이션의 특성을 고려한 설정이 필요하다.