사례4건
4건 중 1~4번째
IL-0188EKS 롤링 업데이트 때 Kubernetes 는 새 파드가 Ready 가 되자마자 옛 파드를 지웠지만 ALB 는 새 파드를 아직 healthy 로 보지 않아, 배포마다 약 30초 동안 502 가 났다.Yonghyun Kim2025- 증상
새벽 3시에 "배포는 성공했는데, 서비스는 죽었다"는 Slack 메시지가 왔다. 모든 파드는 Ready 였고 Datadog 도 초록불이었지만, 사용자는 계속 오류 화면을 보고 있었다.
- 촉발
롤링 업데이트에서 새 파드가 readinessProbe 를 통과해 Ready 가 되자 Kubernetes 가 곧바로 옛 파드를 지웠다. 그때 ALB 는 새 파드 IP 를 대상 그룹에 막 등록해 initial 상태로 헬스 체크를 하고 있었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
새벽 3시에 "배포는 성공했는데, 서비스는 죽었다"는 Slack 메시지로 알았다. 파드 상태와 Datadog 대시보드는 모두 정상이었고, 장애는 사용자가 보는 화면에만 나타났다.
- 조치
- 네임스페이스에 elbv2.k8s.aws/pod-readiness-gate-inject=enabled 레이블을 붙였다. AWS Load Balancer Controller 의 웹훅이 파드에 ReadinessGate 를 넣었다. 새 파드는 ALB 대상이 healthy 가 된 뒤에야 Ready 가 됐고, 그제야 옛 파드가 지워졌다.
- 교훈
Kubernetes 의 Ready 와 ALB 의 healthy 는 서로 다른 시점에 정해지므로, 둘을 잇는 장치가 없으면 롤링 업데이트 때 502 가 날 수 있다. 파드 상태와 대시보드가 모두 정상이어도 사용자는 오류를 볼 수 있다. terminationGracePeriodSeconds 를 늘려 시간을 버는 방식은 배포만 느리게 하고 새 파드가 뜰 때의 공백은 막지 못한다. ReadinessGate 는 ALB 대상 유형이 ip 일 때만 의미가 있고, instance 모드에서는 노드가 대상이라 쓸 수 없다. ReadinessGate 를 쓰면 파드가 Ready 가 되기까지 30초에서 40초가 더 걸리므로 급한 스케일 아웃에 대비해 레플리카나 HPA 를 넉넉히 잡는다. 웹훅의 failurePolicy 를 Ignore 로 두면 컨트롤러가 죽어도 배포가 막히지 않는다.
IL-0203클러스터 시스템 업데이트 뒤 AWS Load Balancer Controller 가 실패해 새 파드가 ALB 에 등록되지 않았고, Honeycomb EU1 의 수집과 UI 가 11분 동안 멈췄다Honeycomb2024- 증상
4월 9일 22:00:10 UTC 에 Honeycomb EU1 의 이벤트 수집과 웹 UI 가 갑자기 멈췄다. 두 서비스가 거의 같은 시각에 끊겼다. 22:08 UTC 에 상태 페이지에 EU1 인스턴스가 다운됐다는 공지가 올라왔다.
- 촉발
그날 앞서 쿠버네티스 클러스터에 배포한 일상적인 시스템 업데이트가 AWS Load Balancer Controller 를 간헐적으로 실패하게 만들었고, 그 뒤 이어진 서비스 배포가 마지막 옛 파드를 내렸다.
- 원인
- 구성 요소
- 기여 요인
- 감지
상태 페이지 첫 공지는 장애 시작 8분 뒤인 22:08 UTC 에 올라왔고, EU1 인스턴스가 다운돼 조사 중이라는 내용이었다. AWS Load Balancer Controller 에는 알림이 없었다.
- 조치
- AWS Load Balancer Controller 를 재시작해 서비스를 되살렸다.
- 재발을 막으려고 시스템 업데이트를 롤백했다.
- 후속 조치
- 재발을 막고 시스템 업데이트를 안전하게 다시 배포할 수 있도록 실패의 정확한 원인을 밝힌다.
- AWS Load Balancer Controller 에 모니터링과 알림을 추가해, 실패하면 온콜 엔지니어가 바로 알고 배포를 미리 멈출 수 있게 한다.
- 교훈
AWS Load Balancer Controller 는 배포 때마다 새 파드를 ALB 에 등록하는 핵심 구성 요소였다. 이 컨트롤러가 실패해도 서비스는 바로 멈추지 않았고, 다음 배포에서 마지막 옛 파드가 내려갈 때 끊겼다. 개발 환경과 스테이징 환경에서 충분히 시험한 시스템 업데이트도 운영 클러스터의 다른 구성 요소와 부딪칠 수 있다.
IL-0111메인 인그레스 컨트롤러를 Traefik v2 로 바꾸자 X-Forwarded 헤더가 전달되지 않아 Okta 로그인이 깨졌고, DFDS 온라인 예약이 한 시간 넘게 멈췄다DFDS2021- 증상
09:26 UTC 에 한 개발자가 HTTP 307 리다이렉트 응답이 유난히 많다고 알렸다. 특히 Okta 서비스에서 많았다. 6분 뒤인 09:32 UTC 에 온라인 예약 시스템이 다운됐다는 연락이 왔다.
- 촉발
Traefik v1 을 걷어 내는 마이그레이션 작업으로 08:22 UTC 에 AWS 로드밸런서가 새 Traefik v2 리버스 프록시로 요청을 보내도록 바뀌었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
09:26 UTC 에 한 개발자가 HTTP 307 리다이렉트가 많다고 보고하면서 문제가 드러났다. 특히 Okta 서비스에서 많았다. 변경 뒤 64분 만이었다. 09:32 UTC 에는 온라인 예약 시스템이 다운됐다는 연락을 받았다.
- 조치
- 조사보다 롤백을 먼저 하기로 하고 09:48 UTC 에 변경을 롤백했다.
- 후속 조치
- 중요한 공지가 더 잘 보이게 할 방법을 검토한다.
- 시험에 쓴 ALB 를 각 팀에 알려 팀이 자기 시나리오를 직접 시험하게 했어야 하는지 검토한다. 이번에 멈춘 서비스는 ALB 앞에 CloudFront 가 있어서 그렇게 했어도 시험하기 어려웠을 수 있다.
- 교훈
Cloud Engineering 팀이 모든 시나리오를 시험할 수는 없었다. 팀은 자기 애플리케이션 몇 개로 몇 주 동안 시험했지만 Okta 로그인 흐름의 문제는 잡지 못했다. 마이그레이션 전후의 요청 헤더를 비교했다면 미리 알 수 있었을지도 모른다는 물음도 남았다.
- 증상
Datadog 이 스테이징 환경의 정규화한 load average 가 높다고 경보를 보냈다. 팀은 원인을 정상 서비스 하나의 부하 증가로 판단했고, 정상 동작으로 여겼다.
- 촉발
Weave Scope 를 배포할 때 쿠버네티스가 로드 밸런서에 0.0.0.0/0 에서 80 포트로 들어오는 접근을 허용하는 보안 그룹을 연결했다. 팀은 AWS 콘솔에서 이 보안 그룹을 손으로 고쳐 허용 목록 밖의 트래픽을 막았지만, 쿠버네티스가 얼마 뒤 이 수정을 되돌렸다. 그 결과 Weave Scope 대시보드가 인증 없이 인터넷에 열렸고, 자동화된 크롤러가 이를 찾아냈다.
- 원인
- 구성 요소
- 기여 요인
- 감지
Datadog 이 정규화한 load average 경보를 0일 차 21:06 EST 에 스테이징에서, 1일 차 16:53 EST 에 개발 환경에서 보냈다. 팀은 정상 서비스의 부하로 보고 경보를 뮤트했다. 3일 차 17:40 EST 에 부하 증가가 나흘째 이어지자 엔지니어가 노드에 SSH 로 들어가 top 으로 CPU 를 100% 쓰는 gcc 프로세스를 찾았다.
- 조치
- Weave Scope 를 멈추고 모든 쿠버네티스 클러스터에서 그 배포를 지웠다.
- 인스턴스에 무단 접근한 흔적이 있는지 접근 로그를 확인했다.
- gcc 프로세스의 외부 연결을 조사해 마이닝 풀과만 통신한다는 것을 확인했다.
- 영향을 받은 노드 하나를 나중에 조사하려고 클러스터에서 격리했다.
- 모든 클러스터의 노드를 전부 새로 만들어 교체하고 감염을 모두 없앴다.
- 후속 조치
- 모든 쿠버네티스 설정 파일과 사내 배포 YAML, 보안 그룹을 감사해 의도치 않게 외부에 열린 서비스나 잘못된 설정이 없는지 확인했다.
- load 대신 더 의미 있는 모니터를 정하고, 작업량이 늘 때 경보가 쏟아지지 않고 실제 이상을 가려내도록 다듬는다.
- falcon 이나 sysdig 같은 도구로 행위 모니터링과 이상 탐지, 침입 탐지를 할 수 있는지 검토한다.
- Istio 나 Linkerd 로 종단 간 네트워크 트래픽을 파악하고 통제해 무단 접근을 막는 방안을 검토한다.
- Docker 이미지와 컨테이너에서 알려진 취약점을 검사하는 데 드는 계산 비용을 따져 본다.
- 아키텍처 논의 시간 일부를 떼어 컨테이너를 root 로 돌리는 것처럼 예전에 내린 결정을 다시 검토하기로 했다.
- 일부 팀원에게만 있던 정보를 팀 전체와 나눠, 대규모 쿠버네티스 버전 업그레이드 같은 큰 프로젝트를 모든 엔지니어가 볼 수 있게 한다.
- 교훈
load 기반 모니터링은 클러스터의 이상을 가려내는 좋은 지표가 아니었다. 정상 서비스가 낸 경보 소음이 침입 신호를 가렸다. 쿠버네티스가 관리하는 리소스를 손으로 고치면 쿠버네티스가 그 변경을 되돌린다. 로드 밸런서를 내부용으로 정의하거나 보안 그룹 규칙을 쿠버네티스 YAML 에 넣었어야 했다. 인증 없는 내부 대시보드, --privileged 와 root 로 도는 컨테이너, 호스트 파일 시스템 마운트가 겹치면 열린 로드 밸런서 하나로 모든 노드에서 코드가 실행될 수 있다. 컨테이너를 root 로 돌리는 것처럼 예전 인프라에서 물려받은 결정은 다시 검토해야 한다.
이 4건에서 가장 많이 나오는 구성 요소: 클라우드 로드 밸런서, 인그레스 컨트롤러. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.