Dead Env 정리 롤아웃 CrashLoop
이 회고는 더 이상 필요하지 않은 백엔드 환경 변수를 새 이미지가 실제로 배포되기 전에 GitOps가 먼저 제거한 2026년 5월 26일 롤아웃을 다룹니다. Kubernetes가 중단은 막았지만, 이 사고는 중요한 배포 규칙을 분명히 보여줬습니다. 코드 변경에 맞춘 구성 정리는 병합된 커밋만이 아니라 새 이미지 배포까지 기다려야 합니다.
컨텍스트
정리 작업은 모놀리스 안의 Spring AI 경로를 백엔드에서 제거한 뒤 진행되었습니다. 현재 프로덕션 계약은 다음 파일에서 확인할 수 있습니다.
lumie-infra/applications/lumie/backend/common-values.yaml는 여전히CHATBOT_SVC_URL를 설정합니다.- 같은 프로덕션 values 파일은 더 이상
GEMINI_API_KEY또는LUMIE_AI_LANGGRAPH_ENABLED를 설정하지 않습니다. lumie-backend/app/src/main/resources/application.yaml는 여전히lumie.services.chatbot.url를 통해 챗봇 워커 URL을 읽습니다.
의도적으로 남겨둔 환경 차이도 하나 있습니다. lumie-backend/Tiltfile은 개발 컷오버 흐름을 위해 여전히 LUMIE_AI_LANGGRAPH_ENABLED를 전달합니다. 이번 롤아웃에서 깨진 것은 이 개발 경로가 아니라 프로덕션 계약이었습니다.
무엇이 깨졌거나 변경되었는지
Argo CD는 환경 변수 정리를 먼저 적용해 Deployment 포드 템플릿을 바꾸고 즉시 새 ReplicaSet을 만들었습니다. 이미지 태그는 아직 갱신되지 않았으므로 새 서지 포드는 여전히 이전 백엔드 이미지로 시작했습니다.
해당 이전 이미지는 여전히 시작 시 제거된 Spring AI 키를 예상했기 때문에 이전 준비된 포드가 트래픽을 계속 처리하는 동안 새 포드는 CrashLoopBackOff로 들어갔습니다.
롤아웃은 시끄러웠지만, 배포 전략이 다음과 같았기 때문에 사용자는 영향을 받지 않았습니다.
lumie-infra/applications/lumie/backend/common-values.yaml는 여전히maxUnavailable: 0를 사용합니다.- 동일한 파일이 여전히
maxSurge: 1를 사용합니다.
이 전략 덕분에 깨진 서지 포드는 정상 기존 복제본을 대체하지 못했습니다.
근본 원인
확인된 근본 원인은 Helm 구문이나 Argo CD 상태 드리프트가 아니라 타이밍이었습니다.
두 가지 변경 사항에는 서로 다른 준비 조건이 있었습니다.
- 새 백엔드 이미지가 모든 곳에서 실행될 때만 코드 변경이 안전해졌습니다.
- Argo CD가 매니페스트 diff를 적용하자마자 환경 정리가 활성화되었습니다.
이 두 이벤트 사이에는 CI, 빌드, 배포 한 주기만큼의 간격이 있었습니다. 그 사이 Kubernetes는 새 환경 계약을 적용한 상태로 이전 이미지를 실행하려고 했습니다.
해결
현재 저장소의 지속 상태는 사고 후 계약과 일치합니다.
- 프로덕션 values는
CHATBOT_SVC_URL를 유지하고 더 이상 제거된 Spring AI 환경 변수를 전달하지 않습니다. - 애플리케이션 런타임은 여전히
application.yaml의 워커 URL만 읽습니다. - 배포 전략은 롤아웃 중에 사용할 수 없는 포드를 0으로 유지합니다.
lumie-backend/build.gradle.kts가 이제lumieLint를check에 연결하므로 로컬 및 CI 확인이 더 쉬워졌습니다.
사고 중에는 수동 롤백이 필요하지 않았습니다. CI가 최신 백엔드 이미지를 게시하고 GitOps가 정리된 환경 계약과 일치하는 이미지로 배포를 진행하면 롤아웃이 복구되었습니다.
예방
- 시작 바인딩이나 설정 클래스가 코드에서 제거될 때마다 구성 정리를 이미지 종속 작업으로 처리합니다.
- GitOps 매니페스트에서 현재 작동하지 않는 환경 변수를 제거하기 전에 실행 중인 포드 이미지를 확인하세요.
- 깨진 서지 포드가 정상적인 트래픽 제공 복제본을 제거할 수 없도록 준비 상태와 롤링 업데이트 보호 장치를 엄격하게 유지하세요.
- grep 결과가 모순적으로 보일 경우 의도적인 개발/프로덕션 구성 차이를 명시적으로 확인합니다.