CKAD — 쿠버네티스 애플리케이션 개발자 · 파드 퇴근 실험실 — 기존 요청과 종료 유예 · 실습
파드 퇴근시키기 — 응답은 끝내고 나가요
목표
개인 k3s VM에서 이미 처리 중인 HTTP 요청을 남긴 채 Pod를 종료하고, 앱의 종료 처리·EndpointSlice·종료 유예를 연결해 설명합니다. 실제 프로세스를 쓰며 kwok 상태 시뮬레이션이 아닙니다.
왜 중요한가
Deployment의 성공 표시는 처리 중이던 요청의 완료를 보장하지 않습니다. 여기서는 읽기 전용 코드로 실행되는 작은 HTTP 서버를 두고, 학생이 작성한 Pod 선언을 도우미가 그대로 생성합니다. 먼저 Service 경로와 요청 수락을 확인하고 Pod watch를 시작한 상태에서 삭제하므로 같은 UID의 응답·단절·종료 코드를 연결할 수 있습니다.
일반 종료와 유예 부족을 비교하되 소수점 시간을 맞히는 실습은 아닙니다. 입력 파일이나 관측 파일을 복사해 성공 문장을 만드는 것이 아니라, 실제 실행과 그 해석이 맞는지 확인합니다. 새 요청 제외와 기존 연결 종료는 같은 사건이 아니며, 이 실험이 외부 로드밸런서를 포함한 서비스 전체의 무중단을 보증하지도 않습니다.
예상 80분입니다. 세션은 기본 60분이므로 만료 전에 +시간으로 연장하세요(최대 180분). 세션이 끝나면 VM과 파일이 회수됩니다. 필요한 결과는 종료 전에 별도로 보관하세요.
단계
1. 개인 VM의 node_name, server_version, namespace_uid, image를 /root/ckad-inflight-termination/environment.json에 기록하고 run 1을 실행하세요. namespace는 ckad-inflight-termination, image는 제공된 pod-template.json의 서버 이미지입니다.
2. immediate.json을 만드세요. Pod 이름·case 라벨 immediate, MODE immediate, WORK_SECONDS 문자열 8, terminationGracePeriodSeconds 정수 15, lifecycle 없음입니다. run 2로 서버가 수락한 요청을 종료 중 관측하세요.
3. immediate-analysis.json에 관측한 pod_uid, client_error, exit_code와 accepted_before_delete, readiness_alone_drains_requests 판단을 적고 run 3을 실행하세요. 삭제 전 수락됐는지와 readiness만으로 요청을 끝낼 수 있는지 구분합니다.
4. graceful.json을 만드세요. 이름·case 라벨 graceful, MODE graceful, WORK_SECONDS 문자열 8, 유예 정수 15입니다. 템플릿의 preStop을 유지해 /drain 호출 뒤 2초 기다리게 하고 run 4를 실행하세요.
5. graceful-analysis.json에 pod_uid와 첫 terminating endpoint의 conditions 전체를 first_terminating_conditions로 적으세요. hook_before_term, accepted_response_complete, endpoint_ready_false_means_connection_closed를 관측과 연결해 판단하고 run 5를 실행하세요.
6. exhausted.json을 만드세요. 이름·case 라벨 exhausted, MODE graceful, WORK_SECONDS 문자열 10, 유예 정수 5입니다. preStop의 /drain 뒤 sleep만 3초로 바꾸고 run 6을 실행하세요. 종료 모드가 같아도 요청 결과가 달라지는지 봅니다.
7. repaired.json을 만드세요. 이름·case 라벨 repaired, MODE graceful, WORK_SECONDS 문자열 10, 유예 정수 15, preStop은 /drain 뒤 3초입니다. run 7로 실제 완료 응답을 확인하세요. 기존 관측 파일은 고치지 않습니다.
8. comparison.json의 outcomes에 immediate·graceful·exhausted·repaired별 pod_uid, client_completed, exit_code를 기록하세요. grace_includes_prestop, api_delete_is_exact_deadline, service_zero_downtime_proven을 판단하고 run 8을 실행하세요.
참고
- 작업 폴더는 /root/ckad-inflight-termination입니다. 모든 단계의 실행은 python3 /opt/fixtures/ckad_termination_lab.py run 단계번호입니다. 채점은 관측을 재실행하지 않고 보존 파일을 읽습니다.
- pod-template.json을 복사해 필요한 필드만 바꾸세요. image·command·보안 설정·run 라벨은 실험의 통제 조건입니다. Pod를 kubectl apply로 미리 만들지 마세요. run이 학생 선언으로 생성·요청·삭제를 한 흐름에서 관측합니다.
- JSON은 Kubernetes가 받는 매니페스트 형식입니다. 환경 변수 WORK_SECONDS는 문자열, 종료 유예는 정수입니다. 샘플 JSON으로 템플릿 원본을 덮어쓰지 마세요.
- preStop의 exec 명령은 템플릿에 있습니다. /drain 호출은 유지하고 마지막 time.sleep의 숫자를 단계 요구대로 바꿉니다. 즉시 종료 단계에서는 lifecycle 자체를 제거합니다.
- 앞 단계 준비는 prepare 단계번호입니다. 현재 단계의 답은 만들지 않으며, 이미 작성한 학생 파일도 덮어쓰지 않습니다. 잘못 작성한 앞 단계 파일이 있으면 먼저 고치세요.
- 중단된 관측의 재실행은 이전 Pod를 복구하지 못합니다. 오류 이력은 보존하고, 도우미가 새 실습을 요구하면 임의로 표식을 지우지 말고 환경을 새로 시작하세요.
- 종료 코드 17은 이 서버가 고른 비교 표식입니다. 137 하나만으로 OOM이나 유예 부족을 단정하지 말고 watch의 reason·실제 설정·hook과 term을 함께 봅니다.
- 참고: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ · https://kubernetes.io/docs/tutorials/services/pods-and-endpoint-termination-flow/
단계 8개
- 진짜 주방인지 확인한다
- 손님을 남기고 바로 퇴근한다
- 준비 표시가 주문을 끝내 주지는 않는다
- 받은 주문까지 끝내고 퇴근한다
- 문은 닫혔는데 응답은 도착한다
- 종료 유예를 너무 짧게 준다
- 유예를 보완하고 다시 관측한다
- 관측한 만큼만 결론을 쓴다