LabHub
배우기 러닝패스 코스

KCNA — 쿠버네티스·클라우드 네이티브 입문 · 배포·준비 실패·롤백의 증거 읽기 · 이론

준비 실패와 수동 롤백이 남기는 것

LabHub 에서 이어서 보기

한 줄 요약

진도 실패 조건은 자동 복구 명령이 아니며, Deployment 롤백은 외부 설정과 데이터까지 되돌리는 거래가 아닙니다.

왜 이게 필요했나

새 v3 앱은 프로세스도 살아 있고 포트도 열립니다. 하지만 readiness와 업무 경로가 503을 반환합니다. 새 버전만 남기고 옛 Pod를 먼저 지웠다면 사용자는 오류를 받았을 것입니다. 이번 실험은 정상 v2 두 개를 유지하면서 준비 안 된 v3 하나만 추가합니다. “새 버전을 빨리 늘리는 것”과 “현재 사용자의 요청을 지키는 것”이 충돌하는 장면입니다.

서비스가 계속 v2를 전달하면 운영자는 잠깐 숨을 돌릴 수 있습니다. 하지만 기다리기만 하면 반드시 고쳐진다고 가정해서는 안 됩니다. 프로브가 올바르게 실패하고 있는 상황에서 probe를 삭제해 초록불을 만드는 것도 복구가 아닙니다. 필요한 일은 어떤 버전과 설정으로 되돌릴지 판단하고, 실제 요청이 그 상태로 돌아왔는지 확인하는 것입니다.

어떻게 동작하나

이 Deployment는 복제본 2개, maxSurge 1, maxUnavailable 0을 사용합니다. 롤링 업데이트 중 원하는 수보다 하나를 추가할 수 있지만, 업데이트가 기존 가용 복제본을 임의로 줄이는 여유는 주지 않습니다. 새 Pod가 준비되지 않으면 컨트롤러는 계속 정상인 옛 Pod 두 개를 유지할 수 있습니다. 따라서 desired는 2인데 실제 Pod는 3이고, available은 2인 상태가 가능합니다. 정수 설정을 쓰는 실험이며 퍼센트의 반올림 규칙까지 여기 숫자로 일반화하지 않습니다.

readiness는 요청을 받을 준비를 판단합니다. 이 합성 앱의 liveness는 계속 정상이라, v3의 준비 실패만으로 컨테이너를 반복 재시작시키지 않습니다. Pod UID·컨테이너 ID·재시작 횟수와 직접 HTTP 응답을 함께 읽으면 “실행 중이지만 준비 안 됨”을 확인할 수 있습니다. Service는 준비된 v2로 요청을 전달하고 v3는 제외해야 합니다. maxUnavailable 0도 외부 장애, 노드 장애, 잘못된 프로브까지 모두 막는 무중단 보장은 아닙니다.

progressDeadlineSeconds는 배포가 진행하지 못하는 상황을 판별하는 예산입니다. 이 실험은 관측 시간을 줄이기 위해 20초를 쓰지만, 운영의 적절한 값은 이미지 다운로드·앱 시작·최소 준비 시간 등 실제 예산에 따라 정해야 합니다. 기한을 넘기면 Progressing 조건이 False이고 reason이 ProgressDeadlineExceeded인 상태를 관측할 수 있습니다. 이것은 새 버전이 정상으로 바뀌었다는 뜻도, Kubernetes가 알아서 옛 템플릿으로 되돌렸다는 뜻도 아닙니다.

실패 조건이 나타난 뒤에도 spec.template은 v3인지, 정상 v2의 UID와 컨테이너는 그대로인지, 새 v3가 아직 준비되지 않았는지 확인합니다. 마지막 정상 revision을 조사해 수동으로 되돌리는 것은 그다음 결정입니다. 실습에서는 이미 관측한 v2 revision을 선택하며 단순히 가장 작은 번호나 가장 최근 번호를 외우지 않습니다.

kubectl -n kcna-delivery rollout history deployment/webkubectl -n kcna-delivery describe deployment web# 조사한 정상 번호를 사용합니다. 아래 N은 그대로 실행하는 값이 아닙니다.kubectl -n kcna-delivery rollout undo deployment/web --to-revision=N

롤백은 이전 템플릿으로 돌아가는 새로운 변경입니다. 이력 번호가 과거 숫자로 그대로 줄어든다고 기대하지 마세요. 또 이 실험에서는 남아 있던 정상 v2 ReplicaSet과 Pod를 재사용할 수 있습니다. 모든 롤백이 새 Pod를 만들어야 한다거나, 항상 기존 Pod를 유지한다고 일반화하지 않습니다. 어떤 ReplicaSet이 남아 있고 몇 개의 복제본이 살아 있는지에 따라 실제 전이가 달라집니다.

현장에서 만나는 모습

코드 롤백이 성공했는데도 사고가 끝나지 않는 이유 중 하나는 외부 상태입니다. 이 실험에서는 v3를 배포하기 전에 ConfigMap을 purple로 바꿉니다. 기존 v2 프로세스는 환경변수 green을 보존하고 있지만 설정 객체 자체는 purple입니다. Deployment를 v2로 되돌려도 ConfigMap은 purple로 남습니다. 당장 응답이 green이라 괜찮다고 넘기면, 나중에 대체 Pod가 생길 때 purple을 받을 수 있습니다. 그래서 롤백 뒤에는 선언된 설정과 실행 중인 설정도 함께 조사합니다.

데이터베이스 스키마, 외부 서비스의 설정, 이미 발송한 메시지는 더 큰 경계입니다. Deployment 이력은 이들을 원자적으로 되감지 않습니다. 이전 코드와 새 스키마가 함께 살아야 하는 롤링 업데이트라면 호환성 설계가 먼저 필요합니다. 새 컬럼 추가, 코드 이동, 불필요한 컬럼 제거를 단계적으로 배포하는 접근이 필요한 이유입니다. 이 실험은 데이터베이스 마이그레이션의 안전성까지 증명하지 않습니다.

GitOps로 관리하는 운영 환경에서는 원하는 복구 상태도 Git의 선언에 반영해야 합니다. 수동 변경만 하고 Git을 그대로 두면 조정기가 다시 적용할 수 있습니다. 여기 개인 k3s에는 ArgoCD를 설치하지 않았으므로 실제로 self-heal이 되돌리는 장면을 봤다고 주장하지 않습니다. 우선 Deployment의 동작 경계를 분리해 배우고, GitOps 실습에서 원하는 상태의 원본을 더합니다.

다음 실습에서 할 것

정상 v2로 바뀐 뒤 준비 실패 v3를 넣고, 기한 초과 후에도 자동 롤백되지 않았음을 기록합니다. 정상 revision으로 수동 복구한 다음 ConfigMap이 purple로 남았는지 확인하고 green으로 별도 복원합니다. 정책을 삭제하거나 정상 비교군을 건드리지 않고, 실제 응답·객체 신원·설정의 세 증거를 비교합니다.

공식 근거: [Deployment의 롤백과 진도 조건](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) · [ConfigMap의 소비 방식](https://kubernetes.io/docs/concepts/configuration/configmap/).