IL-0187 Yonghyun Kim · 2025-10-11 (게시일)kubernetes
글쓴이가 이전 회사에서 겪은 장애다. 회사는 Spring Cloud Config Server 를 운영했고, 업무용 애플리케이션은 모두 Spring Cloud Config Client 라이브러리를 넣어 설정을 동적으로 받아 왔다. 한 쿠버네티스 환경의 앱에는 Liveness Probe 가 기본으로 설정돼 있었다.
Spring Boot 앱은 보통 actuator 로 Health Indicator 를 켠다. Config Client 라이브러리가 들어 있으면 외부 Config Server 의 상태도 자동으로 헬스 체크에 포함된다. 그래서 Config Server 업그레이드 중 짧은 다운타임이 생기자 모든 클라이언트 앱의 헬스 체크가 실패했다. 쿠버네티스는 외부 의존성 때문에 실패한 헬스 체크를 보고 멀쩡한 파드를 죽이고 다시 띄웠고, 파드는 재시작 루프에 빠졌다. 그 결과 한 계열사의 서비스가 마비됐다.
Config Server 업그레이드로 서버가 잠깐 응답하지 않는 동안, 클라이언트 앱 전부가 Liveness Probe 요청에 Config Server 와 연결되지 않는다며 실패로 응답했다.
쿠버네티스는 이 실패만 보고 파드를 비정상으로 판단해 강제로 종료하고 다시 띄웠다. 앱 자체에는 아무 문제가 없었고 Config Server 도 곧 돌아올 예정이었다. 그런데도 파드는 다시 뜨자마자 또 죽는 재시작 루프에 빠졌고, 회복할 틈이 없었다. 결국 한 계열사의 서비스가 마비됐다.
원인 ? 의존성 장애
–
–
–
Liveness Probe 가 앱 자신이 아니라 외부 의존성의 상태까지 판단하면, 잠깐의 외부 장애나 네트워크 문제에도 쿠버네티스가 멀쩡한 앱을 죽인다. 일시적인 부하나 외부 서버 다운은 앱을 죽일 이유가 아니며, Readiness Probe 로 잠시 트래픽만 막으면 된다. 글쓴이는 특별한 이유가 없으면 Liveness Probe 를 끄라고 권한다. 꼭 써야 한다면 헬스 체크 경로에서 DataSourceHealthIndicator, ConfigServerHealthIndicator 같은 외부 Health Indicator 를 빼거나 /healthz 같은 별도 경로를 만들어야 한다. initialDelaySeconds 는 앱이 뜨는 데 걸리는 최대 시간보다 길게, failureThreshold 와 periodSeconds 는 넉넉하게 잡는다. 예를 들어 failureThreshold: 10, periodSeconds: 6 이면 60초 동안 연속으로 실패해야 재시작된다. 글쓴이가 운영한 레브잇 환경은 Liveness Probe 없이 2년 동안 안정적으로 서비스했다.
–