Kubernetes 배포에서 무중단 롤링 업데이트 수행 방법
Readiness Probe, maxSurge, maxUnavailable 및 정상 종료를 사용하여 Kubernetes 롤링 업데이트를 구성합니다.
Kubernetes 배포에서 무중단 롤링 업데이트 수행 방법
Kubernetes 롤링 업데이트는 가시적인 중단 없이 Pod를 교체할 수 있지만, 배포와 애플리케이션이 Pod가 준비되었을 때와 종료되어야 하는 시점에 대해 일치해야 합니다. 기본 전략은 도움이 되지만, 잘못된 readiness probe, 호환되지 않는 릴리스 또는 진행 중인 요청 손실로부터 사용자를 구해주지는 않습니다.
진정한 무중단을 달성하려면 기본 Kubernetes 구성 이상이 필요합니다. 배포 매니페스트, 애플리케이션의 상태 엔드포인트 및 정상 종료 프로세스 간의 신중한 조정이 필요합니다. 이 가이드는 Kubernetes 배포를 구성하여 애플리케이션 업데이트가 최종 사용자에게 원활하고 보이지 않도록 보장하는 포괄적인 단계별 접근 방식을 제공합니다.
이 가이드는 readiness probe, maxSurge, maxUnavailable 및 정상 종료를 다루어 롤아웃 중에 서비스 용량을 유지합니다.
무중단을 위한 전제 조건
Kubernetes 매니페스트를 구성하기 전에 기본 애플리케이션은 무중단 배포를 지원하기 위해 특정 원칙을 준수해야 합니다.
- 애플리케이션 하위 호환성: 이전 버전과 새 버전의 애플리케이션이 동시에 실행되는 짧은 기간 동안 공유 리소스(데이터베이스, 큐, 캐시)와 호환되어야 합니다.
- 멱등성: 두 버전에서 처리될 수 있는 작업은 부정적인 부작용 없이 반복 가능해야 합니다.
- 정상 종료: 애플리케이션은 Kubernetes가 보내는
SIGTERM신호를 인식하고 종료되기 전에 진행 중인 요청을 완료하면서 새 연결 수락을 정상적으로 중지하도록 프로그래밍되어야 합니다.
Kubernetes 롤링 업데이트 전략 이해
Kubernetes 배포는 기본적으로 RollingUpdate 전략을 사용합니다. 이 방법은 이전 애플리케이션 버전이 새 버전이 작동하기 전에 완전히 중단되지 않도록 하며, 두 가지 기본 매개변수를 사용하여 전환을 관리합니다.
| 매개변수 | 설명 | 무중단 영향 |
|---|---|---|
maxSurge |
원하는 복제본 수보다 초과하여 생성할 수 있는 최대 Pod 수를 정의합니다. 절대 숫자 또는 백분율(기본값: 25%)일 수 있습니다. | 롤아웃 속도를 제어하고 일시적으로 용량 증가를 보장합니다. |
maxUnavailable |
업데이트 중에 사용할 수 없는 최대 Pod 수를 정의합니다. 절대 숫자 또는 백분율(기본값: 25%)일 수 있습니다. | 무중단에 매우 중요합니다. 이 값을 0%로 설정하면 새 Pod가 완전히 Ready 상태가 될 때까지 서빙 중인 Pod가 종료되지 않습니다. |
무중단을 위한 권장 전략
최고의 가용성을 위해 용량 손실 없이 무중단을 보장하는 구성이 가장 좋은 경우가 많습니다.
maxUnavailable: 0(용량이 절대 떨어지지 않도록 보장).maxSurge: 1또는25%(용량이 일시적으로 목표를 초과하도록 허용하여 이전 Pod가 종료되기 전에 새 Pod가 준비되도록 보장).
1단계: Readiness Probe 구현
Readiness Probe는 무중단 업데이트를 보장하기 위한 가장 중요한 메커니즘입니다. Kubernetes는 이 프로브를 사용하여 새 Pod가 사용자 트래픽을 수신할 준비가 되었는지, 이전 Pod가 여전히 활발하게 트래픽을 제공하고 있는지 확인합니다.
Liveness vs. Readiness
- Liveness Probe: 컨테이너가 정상이고 기능하는지 Kubernetes에 알려줍니다. 실패하면 컨테이너가 다시 시작됩니다.
- Readiness Probe: 컨테이너가 요청을 제공할 준비가 되었는지 Kubernetes에 알려줍니다. 실패하면 Pod가 연결된 Service 엔드포인트에서 제거되어 준비될 때까지 트래픽을 우회합니다.
롤링 업데이트의 경우 Readiness Probe는 전환을 제어하는 데 사용됩니다. Kubernetes는 새로 생성된 Pod가 readiness 검사를 성공적으로 통과할 때까지 이전 Pod를 종료하지 않습니다.
# deployment.yaml 발췌
spec:
containers:
- name: my-app
image: myregistry/my-app:v2.0
ports:
- containerPort: 8080
# --- Readiness Probe 구성 ---
readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 15 # 첫 번째 프로브 시도까지 대기 시간
periodSeconds: 5 # 검사 수행 빈도
timeoutSeconds: 3
failureThreshold: 3 # Pod를 준비되지 않음으로 표시하는 연속 실패 횟수
# --- Liveness Probe 구성 (표준 상태 확인) ---
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
팁: 애플리케이션의
/health/ready엔드포인트가 초기화, 데이터베이스 연결 및 기타 외부 종속성이 완전히 작동할 때만 성공 코드(HTTP 200-299)를 반환하는지 확인하세요.
2단계: 배포 전략 구성
진정한 무중단을 강제하려면 사용 가능한 복제본 수가 감소하는 것을 방지하기 위해 롤링 업데이트 전략을 명시적으로 구성합니다.
이 구성에서 Kubernetes는 먼저 새 Pod를 생성합니다(maxSurge: 1). 새 Pod가 readiness 프로브를 통과하면 그제서야 Kubernetes가 이전 Pod를 종료합니다. maxUnavailable이 0이므로 서비스 용량은 목표 복제본 수 아래로 절대 떨어지지 않습니다.
# deployment.yaml 발췌
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web-deployment
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
# 용량이 원하는 복제본 수(4) 아래로 절대 떨어지지 않도록 보장
maxUnavailable: 0
# 롤아웃 중에 하나의 추가 Pod 생성을 허용
maxSurge: 1
template:
# ... 컨테이너 사양 ...
3단계: 정상 종료 보장
강력한 readiness 프로브가 있더라도 애플리케이션이 종료 신호를 받으면 즉시 종료되면 진행 중인 요청이 손실될 위험이 있습니다.
Kubernetes는 특정 종료 순서를 따릅니다.
- Pod가 Terminating으로 표시됩니다.
- Pod가 Service 엔드포인트에서 제거됩니다(트래픽 라우팅 중지).
- 사전 중지 훅(정의된 경우)이 실행됩니다.
- 컨테이너가
SIGTERM신호를 수신합니다. - Kubernetes는
terminationGracePeriodSeconds(기본값: 30초)에 정의된 기간 동안 기다립니다. - 컨테이너가 계속 실행 중이면 비협상적인
SIGKILL을 수신합니다.
정상 종료를 보장하려면 애플리케이션이 SIGTERM을 처리해야 하며, terminationGracePeriodSeconds는 애플리케이션이 기존 요청을 완료할 수 있을 만큼 충분히 길어야 합니다.
# deployment.yaml 발췌, Pod 템플릿 사양 내부
spec:
terminationGracePeriodSeconds: 45 # Pod 수준 설정
containers:
- name: my-app
image: myregistry/my-app:v2.0
lifecycle:
preStop:
exec:
# 엔드포인트 업데이트 및 외부 로드 밸런서가 드레인할 시간을 제공합니다.
command: ["/bin/sh", "-c", "sleep 10"]
모범 사례: 애플리케이션은
SIGTERM을 수신하면 새 작업 수락을 중지하고 종료되기 전에 진행 중인 요청을 완료해야 합니다.terminationGracePeriodSeconds를 45초 또는 60초와 같이 약간 더 길게 설정하면 느린 요청에 대한 강제 종료를 방지하는 데 도움이 됩니다.
4단계: 업데이트 수행 및 모니터링
배포 매니페스트에 최적화된 전략과 강력한 프로브가 포함되면 업데이트 수행은 간단합니다.
이미지 태그 업데이트: 배포 매니페스트를 수정하여 새 이미지 버전(예:
v2.0에서v2.1)을 반영합니다.구성 적용:
kubectl apply -f deployment.yaml또는 이미지를 직접 패치할 수 있습니다.
kubectl set image deployment/my-web-deployment my-app=myregistry/my-app:v2.1롤아웃 상태 모니터링: Kubernetes가 단계를 진행하는 것을 관찰하고 준비된 Pod 수가 원하는 수 아래로 떨어지지 않는지 확인합니다.
kubectl rollout status deployment/my-web-deploymentPod 가용성 확인: Pod 상태를 관찰하여 이전 Pod(v2.0)가 새 Pod(v2.1)가 완전히 준비된 후에만 정상적으로 종료되는지 확인합니다.
kubectl get pods -l app=my-web-deployment -w
고급 고려 사항
Pod 중단 예산(PDB) 사용
배포 전략이 롤아웃을 관리하는 반면, **Pod 중단 예산(PDB)**은 노드 드레인 및 일부 클러스터 유지 관리 작업과 같은 자발적 중단을 제한합니다. 모든 계획되지 않은 실패를 방지하지는 않지만 Kubernetes 및 자동화 도구에 준수해야 할 최소 가용성 목표를 제공합니다.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 75% # 복제본의 최소 75%가 항상 사용 가능하도록 보장
selector:
matchLabels:
app: my-web-deployment
초기 지연의 중요성
애플리케이션이 워밍업하는 데 시간이 걸리는 경우 initialDelaySeconds, periodSeconds 및 failureThreshold를 조정하여 readiness가 실제 시작 동작을 반영하도록 하십시오. 실패하는 readiness 프로브는 Pod를 Service 엔드포인트 밖으로 유지합니다. 실패하는 liveness 프로브는 컨테이너를 다시 시작하고 충돌 루프를 생성할 수 있습니다.
안전하게 롤아웃
Kubernetes에서 진정한 무중단 롤링 업데이트를 달성하는 것은 강력한 플랫폼 구성과 체계적인 애플리케이션 개발의 조합입니다. Readiness Probe를 올바르게 활용하여 운영 상태를 알리고, 배포 전략(maxUnavailable: 0)을 조정하여 용량을 유지하며, 정상 종료 핸들러를 구현함으로써 사용자에게 서비스를 중단하지 않고 안정적으로 애플리케이션 업데이트를 수행할 수 있습니다. 항상 스테이징 환경에서 업데이트 프로세스를 철저히 테스트하여 종료 유예 기간과 프로브 로직을 검증하십시오.