CKAD — Kubernetes Application Developer
Measure Whether the Deployment Is Really Zero-Downtime
한국어 원문으로 표시합니다.
이 실습은 진짜로 파드가 뜨고 죽는 클러스터에서 합니다
VM 안에 진짜 k3s 가 떠 있습니다. 롤링 업데이트가 정말로 한 대씩 교체되고,
실패한 롤아웃은 정말로 멈추며, kubectl drain 은 PodDisruptionBudget 에
정말로 막힙니다.
CKAD 과정의 다른 롤아웃 실습이 도는 가짜 클러스터에서는 파드가 실행되지 않으므로 "무중단이었는가" 를 잴 방법이 없습니다.
처음 뜨는 데 2분쯤 걸립니다.
예상 70분입니다. 세션은 기본 60분이므로 만료 전에 +시간으로 연장하세요 (최대 180분). 세션이 끝나면 VM과 파일이 회수되므로 필요한 결과는 따로 보관하세요.
목표
배포 교체 전·중·후에 요청을 계속 보내며 HTTP 실패를 실제로 세고, 실패한 롤아웃이 어떻게 멈추는지, 되돌리기가 무엇을 되돌리는지를 봅니다.
왜 중요한가
"무중단 배포" 는 전략 이름을 고르는 일이 아니라 여러 설정이 맞물려야 성립하는 결과입니다. 하나만 빠져도 조용히 깨집니다.
readinessProbe가 없으면 새 파드가 뜨자마자 트래픽을 받습니다. 아직 준비가 안 됐는데도.maxUnavailable이 크면 한꺼번에 내려가 용량이 부족해집니다.- 종료 유예(
terminationGracePeriodSeconds) 가 짧으면 처리 중이던 요청이 잘립니다.
그리고 깨졌는지 아닌지는 재 봐야 압니다. 배포가 끝난 뒤에 확인하면 언제나 정상으로 보입니다.
단계
모든 것은 crol 네임스페이스에 만듭니다.
webDeployment(레플리카 3, nginx, readinessProbe 포함)를 만들되maxSurge와maxUnavailable을 명시하세요./root/crol/rolling.txt에 담습니다.- replicas=3, maxSurge=1, maxUnavailable=0과 readinessProbe를 둔 web에서
python3 /opt/fixtures/ckad_rollout_observer.py capture로 두 실제 롤아웃을 관측하세요. 처음 Pod에는 preStop이 없어야 합니다./root/crol/nodowntime.txt에total,failed,total_before_prestop,failed_before_prestop을 key=value로 쓰고scope=single-vm-rollout-sample,hook_not_retroactive=yes를 함께 적으세요. 실패 수는 관측대로 기록합니다. - 없는 이미지로 업데이트해 롤아웃이 멈추는 것을 확인하고, 그동안 옛 파드가 살아 있다는 것도 함께
/root/crol/stuck.txt에 담으세요. rollout undo로 되돌리고 결과를/root/crol/undo.txt에 담으세요.revisionHistoryLimit도 명시합니다.rollout pause와resume으로 일부만 교체된 상태를 만들어 보고/root/crol/pause.txt에 담으세요.web-pdbPodDisruptionBudget 을 만들고, 지금 몇 개까지 중단할 수 있는지와 PDB 가 막지 못하는 것을/root/crol/pdb.txt에 담으세요.legacyDeployment 를Recreate전략으로 만들고, 왜 그런 전략이 필요한지를/root/crol/recreate.txt에 담으세요./root/crol/report.md에downtime_requests_failed=,recreate_causes_downtime=,pdb_min_available=세 줄과 설명을 쓰세요.
참고
- 2번의 도우미는 같은 이미지에서 템플릿 주석을 바꿔 실제 롤아웃을 일으킵니다. 훅 없는 롤아웃 → 훅 설치 완료 → 훅 있는 Pod들의 별도 롤아웃 순서입니다. 새 템플릿의 훅을 옛 Pod에 소급 적용했다고 해석하면 안 됩니다.
rollout-observation.json은 실제 요청과 교체 전후 Pod UID·훅 표식을 보존합니다. HTTP 500·리다이렉트·잘못된 본문·전송 오류는 실패로 셉니다. 보고서의 값을 맞추려고 관측 파일을 고치지 마세요. 완료한 capture는 다시 배포하지 않고 기존 관측을 보존합니다.- 실패가 두 번 모두 0이거나 차이가 없어도 관측대로 쓰세요. 이 표본만으로 훅의 효과나 외부 로드밸런서·긴 연결까지 포함한 전체 서비스 무중단을 입증할 수 없습니다. 중단된 관측은 자동으로 덮어쓰지 않으며 새 세션에서 다시 진행합니다.
- 롤아웃 상태는
kubectl -n crol rollout status deploy/web으로 보고, 멈춘 이유는.status.conditions에 있습니다. 정답 예시는 정상 기동에 60초, 의도적인 이미지 실패 실험에만 15초 마감을 쓰고 복구 뒤 60초로 돌립니다. 운영 서비스의 권장값이 아니라 짧은 교육 실험을 위한 선택입니다. - 정답 보기와 단계 준비는 기존 답안을 덮지 않습니다. 이미 있는 답이 틀렸다면 실패 이유를 보고 직접 고치세요. 두 기능을 동시에 실행하면 먼저 실행 중인 명령을 기다린 뒤 다시 시도합니다.
rollout undo는--to-revision으로 특정 판을 고를 수 있고, 남아 있는 판은rollout history로 봅니다.- PDB 의 현재 여유는
.status.disruptionsAllowed입니다. 파드 수가 부족하면 0 이 되어 drain 이 막힙니다. - 흔한 실수 1:
readinessProbe없이 무중단을 기대하는 것. 새 파드가 뜨자마자 엔드포인트에 들어가 아직 준비가 안 된 상태로 트래픽을 받습니다. - 흔한 실수 2: PDB 가 노드 장애도 막아 준다고 생각하는 것. 자발적 중단(drain, eviction)만 막습니다. 노드가 갑자기 죽는 것은 못 막습니다.
두 숫자가 교체 속도를 정한다
web Deployment(레플리카 3, nginx, readinessProbe 포함)를 만들되 maxSurge 와 maxUnavailable 을 명시하세요. /root/crol/rolling.txt 에 담습니다.
maxSurge 는 목표보다 몇 개를 더 띄울 수 있나, maxUnavailable 은 몇 개까지 없어도 되나 입니다.
무중단인지 숫자로 잰다
web의 replicas=3, maxSurge=1, maxUnavailable=0, readinessProbe를 준비하세요. 처음 Pod에는 preStop이 없어야 합니다. python3 /opt/fixtures/ckad_rollout_observer.py capture로 실제 두 롤아웃을 관측한 뒤 /root/crol/nodowntime.txt에 total, failed, total_before_prestop, failed_before_prestop을 key=value로 쓰세요. scope=single-vm-rollout-sample, hook_not_retroactive=yes를 함께 적고 결과를 설명하세요. 실패 수는 0을 가정하지 말고 관측대로 기록합니다.
rollout-observation.json의 trials는 without_hook, with_hook 순서입니다. 각 requests의 HTTP 상태 200과 nginx 본문, error 유무를 함께 봅니다. 훅 설치 롤아웃은 측정과 별도로 끝내며, 두 번째 측정의 before Pod들에 훅이 있는지 확인하세요.
실패한 롤아웃은 멈춘다
없는 이미지로 업데이트해 롤아웃이 멈추는 것을 확인하고, 그동안 옛 파드가 살아 있다는 것도 함께 /root/crol/stuck.txt 에 담으세요.
없는 이미지로 업데이트하면 새 파드가 안 뜨고 progressDeadlineSeconds 뒤에 멈춥니다. 그동안 옛 파드를 보세요.
되돌리기는 무엇을 되돌리나
rollout undo 로 되돌리고 결과를 /root/crol/undo.txt 에 담으세요. revisionHistoryLimit 도 명시합니다.
rollout undo 는 직전 판으로 돌립니다. 남아 있는 판의 개수는 revisionHistoryLimit 이 정합니다.
일부만 바꿔 두고 본다
rollout pause 와 resume 으로 일부만 교체된 상태를 만들어 보고 /root/crol/pause.txt 에 담으세요.
rollout pause 뒤에 이미지를 바꾸면 아무 일도 안 일어납니다. 여러 변경을 모아 한 번에 굴릴 때 씁니다.
한꺼번에 내려가지 못하게 한다
web-pdb PodDisruptionBudget 을 만들고, 지금 몇 개까지 중단할 수 있는지와 PDB 가 막지 못하는 것을 /root/crol/pdb.txt 에 담으세요.
PDB 는 자발적 중단만 막습니다. disruptionsAllowed 가 지금 몇 개까지 허용되는지 알려 줍니다.
일부러 중단하는 전략
legacy Deployment 를 Recreate 전략으로 만들고, 왜 그런 전략이 필요한지를 /root/crol/recreate.txt 에 담으세요.
Recreate 는 옛 것을 다 내리고 나서 새 것을 띄웁니다. 두 판이 절대 공존하면 안 될 때 씁니다.
무엇을 배웠나
/root/crol/report.md 에 downtime_requests_failed=, recreate_causes_downtime=, pdb_min_available= 세 줄과 설명을 쓰세요.
downtime_requests_failed=, recreate_causes_downtime=, pdb_min_available= 세 줄과 설명을 쓰세요.