LabHub
배우기 러닝패스 코스

CNPA — 클라우드 네이티브 플랫폼 엔지니어링 어소시에이트 · 설정까지 재현되는 배포와 복구 · 이론

롤백 버튼이 설정까지 되돌려 주지는 않는다

LabHub 에서 이어서 보기

한 줄 요약

Deployment를 예전 리비전으로 되돌리는 것과 예전 실행 환경을 복원하는 것은 다릅니다. 되돌린 Pod 템플릿이 같은 이름의 ConfigMap을 가리켜도, 그 이름 뒤의 내용이 바뀌었다면 다음 파드는 다른 설정으로 태어납니다.

왜 이게 필요했나

결제 서비스의 새 배포가 준비되지 않습니다. 운영자는 이전 리비전으로 되돌립니다. rollout status가 성공하고 서비스도 응답합니다. 이제 끝났다고 생각했는데, 잠시 뒤 파드 한 개가 교체되면서 같은 장애가 다시 나타납니다. 이미 되돌렸는데 왜 같은 고장이 반복될까요?

이 질문을 단순한 기억 문제로 남기지 않으려고 실제 개인 클러스터에서 재현했습니다. 이미지와 앱 코드는 고정하고 설정만 바꿨습니다. 처음 파드 두 개는 정상 설정을 환경변수로 읽었습니다. ConfigMap의 내용을 잘못된 값으로 바꿔도 기존 프로세스의 환경변수는 그대로였습니다. 그런데 새 파드는 같은 ConfigMap 이름에서 바뀐 값을 읽어 준비 검사에 실패했습니다.

첫 롤백 직후에는 예전 파드가 살아 있어 정상처럼 보였습니다. 그 파드 한 개를 교체하자 새 파드는 다시 잘못된 설정을 받았습니다. 명령이 거짓말한 것이 아닙니다. 명령이 되돌리는 범위보다 우리가 기대한 범위가 넓었던 것입니다.

어떻게 동작하나

객체의 이름, 내용, 읽은 시점을 나눈다

Pod 템플릿의 envFrom.configMapRef.name은 설정 객체를 가리키는 이름입니다. 설정 내용의 사본이나 지문이 아닙니다. ConfigMap을 환경변수로 사용하는 컨테이너는 시작할 때 값을 받습니다. 이미 실행 중인 프로세스의 환경변수는 ConfigMap을 편집했다고 자동으로 바뀌지 않습니다.

그래서 같은 Pod 템플릿에서 나온 두 파드가 서로 다른 설정으로 실행될 수 있습니다. 먼저 태어난 파드는 변경 전 값, 나중에 태어난 파드는 변경 후 값을 갖게 됩니다. “매니페스트가 같으니 실행도 같다”는 추론에 설정을 읽은 시점이 빠진 셈입니다. 설정의 갱신 방식은 전달 방식에 따라 다르므로 환경변수의 설명을 볼륨 마운트에 그대로 적용하지 마세요.

리비전 이력에 들어 있는 것

Deployment 리비전은 Pod 템플릿의 변경에 연결됩니다. 이미지, 설정 참조 이름, 템플릿 라벨이나 annotation의 변경은 새 배포를 만들 수 있습니다. 외부 ConfigMap의 내용을 바꾸는 것 자체가 Deployment의 Pod 템플릿 변경은 아닙니다.

이전 리비전으로 돌아가면 이전 템플릿이 선택됩니다. 그 템플릿이 여전히 settings를 참조하고, settings의 내용은 오류 값이라면 문제의 원본은 남아 있습니다. 리비전 번호만 기록한 배포 기록으로는 어떤 설정 내용이 실행됐는지 충분히 설명하기 어렵습니다.

설정을 배포 산출물에 포함한다

비교 실험에서는 정상 설정을 settings-v1, 잘못된 설정을 settings-v2로 나눴습니다. 각 객체에 immutable: true를 붙였고 Deployment의 참조 이름도 버전에 따라 바꿨습니다. 이제 이전 Pod 템플릿으로 돌아가면 참조하는 설정 이름도 함께 돌아갑니다.

핵심은 이름 뒤에 숫자를 붙이는 요령이 아닙니다. 이전 실행에 필요한 설정 내용을 보존하고, 선택한 설정과 Pod 템플릿을 한 배포 단위로 연결하는 것입니다. 실제로 정상 불변 설정을 수정하려는 요청은 API가 거절했습니다. 이어서 나쁜 버전에서 이전 참조로 복구한 뒤 파드를 교체해도 새 파드가 정상 설정을 읽었습니다.

현장에서 만나는 모습

팀이 “같은 이미지를 개발계에서 운영계로 승격한다”고 말할 때 이미지 digest만 기록하면 설명이 절반일 수 있습니다. 환경에 따라 달라지는 설정도 검토되고 추적되어야 합니다. 이미지가 같아도 연결 대상, 기능 플래그, 준비 조건이 다르면 동작이 달라집니다. 이번 예제는 그 차이를 작은 정상 여부 값으로 드러낸 것입니다.

불변 객체도 삭제하고 같은 이름으로 다시 만들 수 있습니다. 따라서 삭제 권한, 이전 설정의 보존 기간, 배포 원본의 변경 이력도 필요합니다. 예제의 이름은 이해를 돕는 버전 이름이지 내용 기반 주소나 서명이 아닙니다. 관리자에게도 변조 불가능하다는 보장은 하지 않습니다. 비밀값은 ConfigMap에 넣지 않습니다.

또한 애플리케이션 템플릿을 되돌려도 데이터베이스 스키마나 이미 처리한 외부 요청은 되돌아가지 않습니다. 되돌릴 수 있는 변경과 별도 복구가 필요한 변경을 배포 전에 구분해야 합니다. 플랫폼의 복구 버튼은 그 경계를 숨기는 버튼이 아니라, 필요한 증거와 한계를 보여 주는 인터페이스여야 합니다.

다음 읽기에서 확인할 것

서비스가 응답한다는 증거와 새 배포가 완료됐다는 증거가 왜 다른지 살펴봅니다. 기존 파드가 트래픽을 받는 동안 새 파드가 고장 난 상태를 읽고, 복구 후 대체 파드까지 확인하는 기준을 세웁니다.

공식 문서