CNPA — 클라우드 네이티브 플랫폼 엔지니어링 어소시에이트 · 설정까지 재현되는 배포와 복구 · 실습
롤백했는데 새 파드가 왜 다시 고장 날까
목표
같은 이미지의 실제 앱에서 설정 변경·롤아웃·롤백·파드 교체를 비교합니다. 변경 가능한 설정을 참조한 롤백의 재발을 관측하고,
버전별 불변 설정을 참조하는 복구는 새 파드에서도 유지되는지 확인합니다.
왜 중요한가
성공한 rollback 명령과 정상 서비스 응답만으로 외부 설정까지 복원됐다고 판단할 수 없습니다.
이전 파드가 정상 응답하는 동안 새 파드는 잘못된 설정을 받을 수 있습니다. 실제 k3s·kubelet·컨테이너를 사용하는 개인 VM이며
KWOK나 가짜 Ready 상태가 아닙니다. 설치에 수분이 걸릴 수 있습니다. 55분 실습이며 더 필요하면 만료 전에 시간을 연장하세요.
VM과 파일은 세션 종료 시 회수됩니다. 필요한 기록은 먼저 내려받으세요. 운영 클러스터의 파드를 교체하는 절차가 아닙니다.
준비된 환경과 도구
- 자기 앱: cnpa-rollback/checkout, 처음 파드 두 개와 mutable ConfigMap settings. 초기 값은 CONFIG_REVISION=v1, HEALTHY=true입니다.
- 보존 대상: cnpa-rollback-other/sentinel. 다른 팀의 UID와 실제 HTTP를 마지막까지 유지합니다.
- 앱은 고정 이미지 digest, non-root, capability 제거, 자동 서비스 계정 토큰 마운트 끔, 읽기 전용 루트 파일시스템을 사용합니다.
- readiness /readyz는 오류 설정에서 503이고 liveness /livez는 정상입니다. 오류 설정을 프로세스 사망과 혼동하지 않습니다.
- 상태 없는 짧은 GET 앱의 SIGTERM 종료 유예는 5초입니다. 데이터베이스나 긴 요청에 이 값을 일반화하지 마세요.
- 도우미: python3 /opt/fixtures/cnpa_config_lab.py 뒤에 act·capture·observe·grade와 단계 번호를 붙입니다.
act는 명시한 변경만 수행합니다. capture는 최대 75초 관측한 뒤 JSON을 저장하고, observe는 한 번 조회합니다.
grade는 학생 파일이나 자원을 수정하지 않습니다. 완료된 과거 관측은 뒤 단계의 현재 상태로 덮어쓰지 않습니다.
record JSON은 직접 꾸미는 답이 아니라 관측 성공 뒤 저장되는 자료입니다. 입력 JSON만 지정된 값으로 작성하세요.
3·6·7단계의 release JSON은 전체 Deployment가 아닌 strategic merge patch이며 name=app 컨테이너의 나머지 보안 설정을 유지합니다.
단계
1. capture 1로 /root/cnpa-release/baseline.json을 저장하세요. cnpa-rollback/checkout Deployment의 실제 파드 두 개가 설정 v1을 읽고 준비되어 있는지, 서비스 응답의 파드가 그 Deployment 소유인지 확인합니다.
2. /root/cnpa-release/mutable-config.json에 v1 ConfigMap settings(네임스페이스 cnpa-rollback)를 작성하세요. data는 CONFIG_REVISION="v2", HEALTHY="false", immutable=false입니다. act 2로 적용하고 capture 2로 env-unchanged.json을 저장합니다. 설정은 바뀌었지만 처음 파드 두 개의 UID와 실제 v1 환경변수는 유지돼야 합니다.
3. /root/cnpa-release/mutable-release.json에 spec.template.metadata.annotations의 labhub.io/release만 mutable-v2로 설정하는 JSON 패치를 작성하세요. act 3과 capture 3으로 rollout-incomplete.json을 저장합니다. 새 파드 한 개는 v2·준비 503, 기존 두 개는 v1·정상이어야 하며 서비스는 기존 파드로 응답합니다.
4. act 4로 설치 시 관측한 이전 리비전으로 rollback하고 capture 4로 apparent-rollback.json을 저장하세요. rollout status가 성공하고 처음 파드 두 개가 다시 정상인 것과, settings 내용이 여전히 오류 값인 것을 함께 확인합니다.
5. act 5로 자기 실습의 정상 파드 한 개를 교체하고 capture 5로 replacement-failed.json을 저장하세요. 삭제한 UID는 사라지고 새 UID의 파드가 오류 v2 설정을 받는지 확인합니다. 기존 파드 한 개는 여전히 정상 응답해야 합니다.
6. /root/cnpa-release/versioned-configs.json에 v1 List로 ConfigMap 두 개를 작성하세요. cnpa-rollback 네임스페이스의 settings-v1은 CONFIG_REVISION="v1", HEALTHY="true", settings-v2는 CONFIG_REVISION="v2", HEALTHY="false"이고 둘 다 immutable=true입니다. versioned-release.json에는 템플릿 annotation labhub.io/release=versioned-v1과 name=app 컨테이너의 envFrom.configMapRef.name=settings-v1을 지정하는 패치를 작성하세요. act 6으로 적용·불변 수정 거절을 시험하고 capture 6으로 versioned-ready.json을 저장합니다.
7. /root/cnpa-release/bad-release.json에 템플릿 annotation labhub.io/release=versioned-v2와 name=app 컨테이너의 envFrom.configMapRef.name=settings-v2를 지정하는 패치를 작성하세요. act 7과 capture 7로 versioned-incomplete.json을 저장합니다. 기존 불변 v1의 두 파드는 정상, 새 v2 파드 한 개는 준비 실패여야 합니다.
8. act 8로 6단계의 실제 리비전으로 복구한 뒤 정상 파드 한 개를 교체하세요. capture 8로 replacement-ready.json을 저장합니다. 교체된 새 UID도 불변 v1 설정으로 정상이며 settings-v1의 UID와 다른 팀 cnpa-rollback-other/sentinel의 UID·HTTP가 유지되는지 확인합니다.
참고
Deployment 리비전은 Pod 템플릿의 이력이지 외부 설정 내용의 사본이 아닙니다. 번호를 추측하지 않고 관측한 리비전을 사용합니다.
서비스 응답과 개별 파드 응답, 현재 관측 세대, Pod→ReplicaSet→Deployment의 UID를 연결합니다. 종료 중인 파드는 잠시 추가로 보일 수 있습니다.
관측 제한에 걸리면 같은 실행의 조건과 로그를 조사하세요. 타임아웃만으로 실패를 확정하거나 설치를 다시 시작하지 마세요.
불변 ConfigMap도 삭제·재생성이 가능하므로 이전 UID와 내용 보존을 확인합니다. ConfigMap에 비밀값을 넣지 않습니다.
관측 기록은 학습 증거이지 root 사용자를 막는 원격 증명이나 부정행위 방지 장치가 아닙니다.
앞 단계 준비는 없는 이전 입력·관측만 채우고 현재 답을 만들지 않습니다. 이미 진행한 단계나 학생의 미완성 파일을 덮어쓰지 않습니다.
현재 단계 채점은 실제 상태도 보며, 뒤로 진행한 과거 단계는 저장 기록을 봅니다. 최종 단계 이후에는 복구 상태와 다른 팀 정상도 계속 확인합니다.
학습자 파일을 잃으면 사라진 과거 상태를 성공 기록으로 다시 꾸미지 마세요. 해당 실행의 과거 증거가 없음을 남겨야 합니다.
공식 문서: [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) ·
[Deployment 롤백](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-back-a-deployment).
단계 8개
- 기준선의 선언과 응답 연결
- 설정 변경과 기존 환경변수 구분
- 서비스 정상과 새 배포 실패 구분
- 성공처럼 보이는 첫 롤백
- 대체 파드에서 재발 확인
- 불변 설정을 배포 단위로 묶기
- 잘못된 버전 참조를 배포
- 다음 파드까지 유지되는 복구