
Kubernetes에서 계획된 중단(노드 드레인, 클러스터 업그레이드, 오토스케일러에 의한 노드 교체 등)은 “정상 운영”의 일부입니다.
그런데도 배포/드레인 때 5xx가 튀는 서비스가 많습니다. 이유는 대개 하나입니다.
트래픽 드레이닝(서비스 레벨)과 중단 제어(클러스터 레벨)를 따로 생각했기 때문입니다.
이 글은 PodDisruptionBudget(PDB) + eviction(강제 종료가 아닌 퇴거) + readinessProbe를 “한 세트”로 설계해
계획된 중단에서도 5xx를 최소화하는 운영 패턴을 정리합니다.
본문에서 확정하는 동작/주장은 Kubernetes 공식 문서 근거로만 설명합니다.
TL;DR (실무 결론 9줄)
- readinessProbe는 Kubernetes 공식 문서에 따라, 준비되지 않은 Pod를 Service의 백엔드에서 제거하는 신호입니다(트래픽 제어).
- PDB는 Kubernetes 공식 문서에 따라, 자발적(voluntary) 중단이 발생할 때 동시에 중단될 수 있는 Pod 수를 제한합니다.
- Eviction은 Kubernetes에서 “즉시 kill”이 아니라 정책(PDB 등)을 고려한 퇴거 요청입니다(계획된 중단에서 핵심).
- 따라서 “드레인 중에도 5xx를 줄이려면” PDB로 동시 중단을 제한하고, readiness로 트래픽을 먼저 빼고, graceful shutdown으로 in-flight 요청을 완료하게 해야 합니다.
- PDB는 만능이 아닙니다. Kubernetes 공식 문서에 따라 비자발적(involuntary) 중단(노드 장애 등)을 막지 못합니다.
- Replica가 적은 서비스(예: 1개)에서 PDB를 잘못 잡으면, 문서가 설명하는 대로 드레인이 진행되지 않거나(차단) 운영이 어려워질 수 있습니다.
- 운영 체크: drain 시나리오를 스테이징에서 재현하고, Pod event / eviction 이벤트 / Service 엔드포인트 변화를 기록으로 남기세요.
- 문서 기준으로 확정 가능한 값(동작)은 확정하고, 초 단위 타임아웃/threshold 같은 값은 반드시 측정 결과로 확정하세요(추정 금지).
- 결론: “PDB(동시 중단 제한) + readiness(트래픽 드레이닝) + graceful shutdown(요청 완료)” 3개를 분리하지 말고 함께 설계하세요.
1) readinessProbe는 무엇을 보장하나? (공식 문서 기반)
Kubernetes 공식 문서는 kubelet이 readiness probe를 컨테이너가 트래픽을 받을 준비 여부 판단에 사용한다고 설명하며,
Pod가 준비되지 않으면 Service 로드밸런서의 백엔드에서 제거된다고 명시합니다.
즉, readiness는 “지금 트래픽을 받아도 되는가”를 표현하는 신호입니다.
2) PDB의 역할: 자발적(voluntary) 중단을 제한한다 (공식 문서 기반)
Kubernetes 공식 문서는 PodDisruptionBudget이 자발적(voluntary) disruption 상황에서
동시에 중단될 수 있는 Pod 수를 제한하는 데 사용된다고 설명합니다.
또한 PDB는 비자발적(involuntary) disruption(예: 노드 장애)까지 막지 못한다고 명시합니다.
2-1. minAvailable vs maxUnavailable
Kubernetes 공식 문서는 PDB에 minAvailable 또는 maxUnavailable을 설정할 수 있다고 설명합니다.
어느 쪽을 택하든 핵심은 “동시에 사용 불가가 되는 Pod 수/비율”에 상한을 두는 것입니다.
예시 (Deployment 3 replicas에 대한 PDB)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp
공식 문서 링크:
Configure a Pod Disruption Budget
3) drain에서 중요한 건 ‘eviction’이다 (공식 문서 기반)
Kubernetes에서 계획된 중단(예: 노드 드레인)은 일반적으로 Pod를 “그냥 삭제”하는 방식이 아니라
eviction을 통해 진행됩니다. Eviction은 PDB 같은 정책을 고려해 처리될 수 있도록 설계된 퇴거 요청입니다.
(즉, PDB가 허용하지 않으면 드레인이 지연/차단될 수 있습니다.)
4) “한 세트” 설계: PDB(동시 중단 제한) × readiness(트래픽 드레이닝) × graceful shutdown(요청 완료)
4-1. 운영자가 기대하는 시간 순서
- 노드 드레인(계획된 중단) 시작
- eviction 요청이 발생하고, PDB가 허용하는 범위에서 Pod가 순차적으로 퇴거
- Pod 종료가 시작되면 readiness가 먼저 내려가 Service 백엔드에서 제외되고 트래픽이 빠짐
- 애플리케이션은 graceful shutdown으로 in-flight 요청을 마무리
- Pod가 종료되고, 새 Pod가 뜨면 startup/readiness를 통과한 뒤 트래픽을 받음
4-2. 핵심 설계 원칙(문서 동작에 맞춘 결론)
- PDB는 “몇 개까지 동시에 빠져도 되는가”를 정의합니다(자발적 disruption에 한정).
- readiness는 “언제 트래픽을 빼야 하는가”를 정의합니다(Service 백엔드 포함/제거).
- graceful shutdown은 “트래픽을 뺀 뒤 기존 요청을 어떻게 마무리할 것인가”를 정의합니다(애플리케이션 레벨).
5) 운영 체크리스트 (필수 보강요소 1: 체크리스트)
- Replica 수 확인: 2개 미만이면 PDB 설계가 까다롭습니다(드레인 차단 가능성 포함).
- PDB 적용 범위: selector 라벨이 Deployment/StatefulSet의 Pod 라벨과 정확히 일치하는지 확인
- readiness 조건 정의: “DB 연결 성공이면 준비 완료인가?”처럼 운영 정의를 먼저 문서화
- graceful shutdown 준비: 종료 시점에 새 요청을 차단하고 기존 요청을 마무리하도록 애플리케이션 설정 점검
- 드레인 리허설: 스테이징에서 drain을 재현하고 Pod event/eviction/endpoint 변화를 로그로 남김
6) 트러블슈팅 매트릭스 (필수 보강요소 2: 매트릭스)
| 증상 | 관측 포인트 | 가능한 원인(설계 관점) | 대응(공식 동작에 맞춘 조정) |
|---|---|---|---|
| 노드 드레인이 끝나지 않음(대기/차단) | eviction이 반복되거나 drain이 오래 걸림 | PDB가 허용하는 disruption이 0이거나, replica가 너무 적음 | PDB의 minAvailable/maxUnavailable를 서비스 가용성 요구와 replica 수에 맞게 재설계(문서: 자발적 disruption 제한) |
| 드레인 중 5xx 발생 | Ingress/Service 로그에 특정 Pod 종료 시점과 겹치는 5xx | readiness가 종료 전 트래픽 제거를 충분히 빨리/정확히 못함 | readiness를 “트래픽 수신 가능 상태”로 재정의하고, 종료 시점에 readiness가 먼저 내려가도록 설계(문서: 준비 안 된 Pod는 Service 백엔드에서 제거) |
| PDB는 있는데도 노드 장애에서 서비스가 무너짐 | 노드 장애 시 다수 Pod 동시 소실 | PDB는 비자발적 disruption을 막지 못함 | PDB 역할의 한계를 받아들이고, 다중 노드 분산(anti-affinity), replica 확장 등으로 별도 대응(문서: PDB는 involuntary disruption을 막지 못함) |
7) FAQ (필수 보강요소 3: FAQ)
Q1. PDB를 걸어두면 노드 드레인 때 Pod가 ‘절대’ 같이 죽지 않나요?
Kubernetes 공식 문서는 PDB가 자발적(voluntary) disruption을 제한한다고 설명합니다.
즉, PDB는 계획된 중단에서 동시 중단을 줄이는 데 유용하지만, 노드 장애 같은 비자발적(involuntary) disruption까지 막지는 못합니다.
Q2. PDB를 너무 빡세게 잡으면 어떤 일이 생기나요?
PDB는 eviction 같은 자발적 중단 흐름에 영향을 줍니다. 따라서 허용 disruption이 너무 작으면
계획된 중단(예: drain)이 지연되거나 진행되지 않을 수 있습니다.
이런 동작은 “PDB로 자발적 disruption을 제한한다”는 문서적 역할과 일관됩니다.
Q3. readiness만 잘하면 PDB 없이도 되나요?
readiness는 “트래픽 제어(백엔드 포함/제거)”에 직접적으로 도움 됩니다.
하지만 PDB는 “동시에 몇 개까지 빠져도 되는가”를 정의하는 제어 수단입니다.
두 기능은 해결하는 레벨이 다르므로, 둘 중 하나만으로는 운영 요구를 충분히 만족하지 못하는 경우가 많습니다.
8) “추정 금지” 검증 절차 (필수 보강요소 4: 검증 절차)
- 스테이징에서 노드 드레인을 재현하고, eviction 관련 이벤트/로그를 수집합니다.
- 드레인 동안 Service 엔드포인트(백엔드) 변화를 기록합니다(ready/unready 전환이 기대대로인지).
- 애플리케이션 로그에서 종료 시점에 in-flight 요청이 정상 완료되는지 확인합니다.
- 초 단위 값(타임아웃/threshold)은 서비스별로 다르므로, 최종 값은 측정 결과로 확정합니다.
참고(공식 문서)
-
Kubernetes: Configure Liveness, Readiness and Startup Probes
— https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ -
Kubernetes: Configure a Pod Disruption Budget
— https://kubernetes.io/docs/tasks/run-application/configure-pdb/ -
Kubernetes: API-initiated eviction
— https://kubernetes.io/docs/concepts/scheduling-eviction/api-eviction/