PDB(Pod Disruption Budget)의 필요성
Pod Disruption Budget PDB는 k8s에서 불가피한 중단 작업이 발생해도
서비스 가용성을 유지하기 위하여 동시에 사라질 수 있는 pod의 수를 제한하는 규칙이다.
즉 운영중에 안전하게 죽일 수 있는 pod수를 선언하는 것
k8s에서는 여러 상황에서 pod를 강제 종료 시키거나 옮긴다 예를들어
- 노드 커널 업데이트
- 노드 drain
- 오토 스케일러가 노드 축소
- daemon set 롤 아웃
- pdb없는 deployment rolling update
- 스팟 인스턴스 종료
- 장애 노드 자동 정리
문제는 이런 계획된 중단(distruption)이 한번에 여러 파드를 죽여버릴 수 있어
서비스가 순간적으로 다운되거나 readiness failed로 전체 트래픽을 못 받는 상황이 발생할수도 있다는것.
이걸 막는것이 PDB
PDB 동작방식 #
pdb는 아래중 하나로 정의
minAvailable: 최소 몇 개는 살아있어야 한다.maxUnavailable: 동시에 최대 몇개까지 죽여도 된다.
minAvailable: 2라면 k8s에서에서 최소 2개는 살아있어야 한다는 규칙이고 절대 깨지지 않는다.
즉, 노드 drain을 해도 pdb를 위반하는 kill은 실행하지 않는다.
이를 통해서 장애 없는 롤링 업데이트 보정이 가능한데 pod가 3개인데 readiness timeout이 길거나 초기화 시간이 길면
롤링 업데이트 중에 잠시 1개만 남는 상황이 발생할 수 있고 PDB는 이를 막아줄 수 있다.
혹은 노드 장애(drain/cordon)시 서비스 가용성이 유지가 된다.
kubectl drain nodex-xxx --ignore-daemonsets
PDB가 없으면 pod 여러개가 순식간에 evict되고 서비스 중단이 발생하지만
PDB가 존재해서 k8s는 이 파드를 죽이면 pdb에 위반되는구나를 판단해 죽이지 않는다.
결과적으로 관리자가 drain을 할때도 pdb조건 범위내에서 안전하게 순차적으로 이동된다.
그리고 cluster autoscaler와 충돌도 방지되는데
노드 scale in 상황에서도 ca는 핀 노드를 제거하려고 pod를 evict하지만 pdb가 있으면 위반 상태를 감지하고 노드 제거를 하지 않는다.
spot 인스턴스가 종료될때라도 제약을 보장 (stateful set에서 특히 중요)
readiness delay, heavyy init, cache warm up 있는 서비스도 보호하며 초기화가 느린 서비스는 파드 하나 죽었다가 새로 뜨는 과정에서 안정성이 크게 떨어진다.
pdb는 최소 동작 pod 수를 강제해 warm up 중인 pod 때문에 전체 서비스가 흔들리는 것을 막는다.
PDB가 없다면 #
- 노드 drain중에 503 폭발
- 롤링업데이트중 리드니스 타임아웃 -> 전체 서비스 가용성 급락
- CA 스케일인시에 pod대량 evict -> 서비스 소실
- 스팟 노드 비워지는 과정에서 pod 동시 죽음
- redis/elasticsearch 같은 stateful 데이터 손실
- pdb없는 daemonset 간섭으로 다운타임
PDB는 Kubernetes가 Pod를 죽이는 모든 계획된 작업에서 서비스 가용성을 보호하기위한 핵심 기능이기에 가용성때문에 필요한 옵션