LabHub
배우기 러닝패스 코스

CNPA — Cloud Native Platform Engineering Associate

Why does the next pod fail after a successful rollback?

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

같은 이미지의 실제 앱에서 설정 변경·롤아웃·롤백·파드 교체를 비교합니다. 변경 가능한 설정을 참조한 롤백의 재발을 관측하고, 버전별 불변 설정을 참조하는 복구는 새 파드에서도 유지되는지 확인합니다.

왜 중요한가

성공한 rollback 명령과 정상 서비스 응답만으로 외부 설정까지 복원됐다고 판단할 수 없습니다. 이전 파드가 정상 응답하는 동안 새 파드는 잘못된 설정을 받을 수 있습니다. 실제 k3s·kubelet·컨테이너를 사용하는 개인 VM이며 KWOK나 가짜 Ready 상태가 아닙니다. 설치에 수분이 걸릴 수 있습니다. 55분 실습이며 더 필요하면 만료 전에 시간을 연장하세요. VM과 파일은 세션 종료 시 회수됩니다. 필요한 기록은 먼저 내려받으세요. 운영 클러스터의 파드를 교체하는 절차가 아닙니다.

준비된 환경과 도구

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 · Deployment 롤백.

기준선의 선언과 응답 연결

capture 1로 /root/cnpa-release/baseline.json을 저장하세요. cnpa-rollback/checkout Deployment의 실제 파드 두 개가 설정 v1을 읽고 준비되어 있는지, 서비스 응답의 파드가 그 Deployment 소유인지 확인합니다.

서비스 응답 하나에 그치지 말고 Pod→ReplicaSet→Deployment의 소유 관계와 개별 준비 응답을 연결하세요.

설정 변경과 기존 환경변수 구분

/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 환경변수는 유지돼야 합니다.

환경변수는 컨테이너가 시작할 때 받습니다. 설정 객체의 현재 내용과 기존 프로세스가 읽은 값을 따로 보세요.

서비스 정상과 새 배포 실패 구분

/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·정상이어야 하며 서비스는 기존 파드로 응답합니다.

템플릿 annotation 변경은 새 롤아웃을 만듭니다. maxUnavailable=0이면 준비되지 않은 새 파드 때문에 기존 정상 용량이 먼저 줄지 않습니다.

성공처럼 보이는 첫 롤백

act 4로 설치 시 관측한 이전 리비전으로 rollback하고 capture 4로 apparent-rollback.json을 저장하세요. rollout status가 성공하고 처음 파드 두 개가 다시 정상인 것과, settings 내용이 여전히 오류 값인 것을 함께 확인합니다.

되돌리는 것은 Pod 템플릿입니다. 리비전 번호는 고정하지 않고 처음 관측한 값을 사용합니다.

대체 파드에서 재발 확인

act 5로 자기 실습의 정상 파드 한 개를 교체하고 capture 5로 replacement-failed.json을 저장하세요. 삭제한 UID는 사라지고 새 UID의 파드가 오류 v2 설정을 받는지 확인합니다. 기존 파드 한 개는 여전히 정상 응답해야 합니다.

처음 파드의 UID와 새로 태어난 파드의 UID를 대조하세요. 정상 파드가 하나 남았다고 전체 복구가 유지된 것은 아닙니다.

불변 설정을 배포 단위로 묶기

/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을 저장합니다.

ConfigMap에는 apiVersion·kind·metadata·data·immutable이 필요합니다. 배포 패치는 전체 Deployment 문서가 아니라 strategic merge patch입니다.

잘못된 버전 참조를 배포

/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 파드 한 개는 준비 실패여야 합니다.

불변 설정은 내용을 고치지 않고 새 이름을 참조합니다. 이 단계는 잘못된 버전을 의도적으로 선택하는 실험입니다.

다음 파드까지 유지되는 복구

act 8로 6단계의 실제 리비전으로 복구한 뒤 정상 파드 한 개를 교체하세요. capture 8로 replacement-ready.json을 저장합니다. 교체된 새 UID도 불변 v1 설정으로 정상이며 settings-v1의 UID와 다른 팀 cnpa-rollback-other/sentinel의 UID·HTTP가 유지되는지 확인합니다.

복구 뒤에도 같은 이름의 새 설정 객체로 바꿔치기하지 마세요. 보존한 UID와 대체 파드의 실제 응답을 함께 봅니다.