사례6건
6건 중 1~5번째
- 증상
이구위크가 시작되고 얼마 지나지 않아 검색 결과와 상품 리스팅 같은 전시 도메인을 맡은 서버에 이상 징후가 나타났다. 파드 일부가 다운되어 트래픽을 받지 못했고, 남은 파드도 처리할 수 있는 양을 넘어 Netty 이벤트 루프가 포화됐다.
- 촉발
2025년 11월 3일 29CM 최대 규모의 블랙프라이데이 행사인 이구위크가 시작되면서 트래픽이 몰렸다.
- 원인
- 구성 요소
- 기여 요인
- 감지
팀은 이구위크가 시작되고 얼마 지나지 않아 전시 서버의 파드 일부가 다운되고 Netty 이벤트 루프가 포화된 것을 보고 이상을 알아챘다. 원인을 분석하던 중 Redis 헬스체크 실패 로그를 보고 네트워크 지표에서 대역폭 초과를 찾았다.
- 조치
- 원인을 찾은 즉시 Redis 노드를 cache.r7g.large 에서 기본 대역폭이 1.875Gbps 로 약 2배인 cache.r7g.2xlarge 로 스케일업했다.
- 후속 조치
- 네트워크 In/Out 대역폭의 초과 여부를 실시간으로 볼 수 있게 모니터링 대시보드를 강화했다. 주요 지표는 aws.elasticache.network_bytes_in, aws.elasticache.network_bytes_out, aws.elasticache.network_bandwidth_in_allowance_exceeded, aws.elasticache.network_bandwidth_out_allowance_exceeded, aws.elasticache.traffic_management_active 다.
- 네트워크 대역폭이 임계치를 넘으면 곧바로 알림이 오도록 Datadog Alert 를 연동했다.
- 응답이 자주 바뀌지 않는 데이터를 중심으로 Redis 하나에 기대던 구조를 Caffeine 로컬 캐시, Redis 원격 캐시, DB 로 이어지는 캐시 계층 구조로 바꿨다.
- Redis 네트워크 대역폭 사용량을 줄이려고 CPU 사용량이 적고 압축과 해제가 빠른 Snappy 로 캐시 데이터를 압축하는 방안을 검토한다.
- JSON 으로 저장하던 캐시 데이터를 Protocol Buffers 형식으로 바꾸는 방안을 검토한다. 팀이 캐싱 중인 Item Document 데이터로 재 본 결과, Snappy 압축과 protobuf 를 함께 쓰면 용량을 약 73% 줄일 수 있을 것으로 예상됐다.
- 캐시 구조 개선, 모니터링 고도화, 읽기 분리 적용으로 기술 부채를 해소했고, 이를 바탕으로 트래픽 증가에 대비한 아키텍처 개선을 진행한다.
- 교훈
CPU 와 Memory 지표만으로는 Redis 대역폭 초과를 알아채기 어려웠고, 팀은 네트워크 관점의 모니터링이 필요하다는 것을 다시 느꼈다. 버스트 크레딧 구간이 있으면 Baseline 을 넘은 시점과 Throttling 이 시작된 시점 사이에 시간이 벌어져 원인을 찾기가 늦어진다. 트래픽이 더 늘면 스케일업만으로는 같은 문제가 되풀이될 수 있어 근본적인 재발 방지가 필요하다고 봤다.
- 증상
2024-10-09 05:01:36 UTC 에 codfw 의 rest-gateway 에서 page-analytics_cluster 의 5xx 오류가 늘었다는 GatewayBackendErrorsHigh 알림이 울렸다. 05:03:32 UTC 에는 KubernetesCalicoDown 알림이 16건 묶여 울렸고, 알림 문구는 kubernetes2037.codfw.wmnet is not running calico-node Pod 였다. 05:04:15 UTC 에는 MediaWiki memcached 오류율이 전 세계에서 올랐다는 MediaWikiMemcachedHighErrorRate 알림이 울렸다.
- 촉발
한 운영자가 새 mwscript-k8s 도구로 TimedMediaHandler 의 requeueTranscodes.php 를 돌려 동영상 트랜스코딩을 일괄 정비했다. mwscript-k8s 는 스크립트를 실행할 때마다 helm 릴리스를 통째로 배포하므로, 이 작업이 몇 시간 동안 리소스를 계속 만들었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
자동 모니터링이 알아채고 당직 SRE 가 대응했다. 05:01:36 UTC 에 GatewayBackendErrorsHigh, 05:03:32 UTC 에 KubernetesCalicoDown 16건, 05:04:15 UTC 에 MediaWikiMemcachedHighErrorRate 알림이 울렸다.
- 조치
- calico 와 typha 의 자원 한도를 올리는 변경을 CI 를 기다리지 않고 반영하고, helmfile -e codfw --selector name=calico apply -i --context 5 로 적용했다. 적용 중 새 calico 파드가 정상으로 떴고, 06:10 UTC 에 Calico 가 회복되었다.
- 후속 조치
- mwscript-k8s 가 리소스를 너무 많이 만드는 문제를 해결한다.
- 교훈
완전한 장애 직전까지 갔다. 자동 모니터링이 장애를 잡았다. 새로 들어온 여러 사람이 함께 본 덕에 근본 원인을 찾았다. 미주 SRE 에서 EMEA SRE 로 장애 대응을 문제없이 넘겼다. 반면 최종 사용자에게 영향이 갔고, 비상시에 eqiad 로 전환할 수 있는지 확신하지 못했다. 운도 따랐다. 장애는 미주 SRE 근무가 끝나고 EMEA SRE 근무가 시작되기 바로 전에 발견되었다. 이 시간대는 오래전부터 대응 인력이 비는 때로 알려져 있었다. 트랜스코딩 작업을 미국의 금요일 저녁에 넣지 않은 것도 다행이었다.
IL-0044kube-prometheus-stack 업그레이드 뒤 Prometheus 가 WAL 재생 중 메모리를 50Gi 넘게 써서 시작할 때마다 OOMKilled 로 죽었다Saifeddine Rajhi2024- 증상
kube-prometheus-stack 헬름 차트를 업그레이드하는 중에 여러 파드가 Ready 가 되지 않았다. 그중 prometheus-prometheus-operator-prometheus-0 파드는 3/4 Running 상태였고 최근에 OOMKilled 로 종료된 기록이 있었다.
- 촉발
kube-prometheus-stack 헬름 차트를 업그레이드하던 중 Prometheus 가 시작하면서 WAL 을 재생했고, 이 과정에서 메모리 사용량이 메모리 제한을 넘었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
팀은 kube-prometheus-stack 헬름 차트를 업그레이드하던 중 Prometheus 파드를 포함한 여러 파드가 Ready 가 되지 않는 것을 보았다. kubectl describe pod 와 Prometheus 로그로 OOMKilled 를 확인했다.
- 조치
- Prometheus 파드에 kubectl exec 로 들어가 promtool tsdb analyze . 를 실행해 haproxy_server_http_responses_total 처럼 카디널리티가 높은 지표를 찾았다.
- 후속 조치
- WAL 재생 중 메모리 오버헤드가 10% 에서 15% 정도의 허용 범위 안에 있는지 확인하고, Prometheus 를 메모리 제한에 가깝게 운영하지 않는다.
- Prometheus 의 저장, 스크레이프, remote write 설정을 정기적으로 최적화하고, 최적화가 들어간 새 릴리스로 업그레이드한다.
- OOM 크래시 루프에서 자동으로 복구하는 장치를 만든다. 예를 들어 OOM 이벤트가 나면 WAL 을 자동으로 지운다.
- 메모리 사용량이 일정 기준을 넘으면 스크레이프를 멈추는 강제 스크레이프 제한을 둔다.
- 교훈
Prometheus 를 메모리 제한에 가깝게 운영하면 WAL 재생 중의 작은 오버헤드로도 OOM 이 난다. 가비지 컬렉션은 들쭉날쭉하고 카디널리티나 쿼리는 갑자기 늘 수 있으므로 메모리에 여유를 둔다. Prometheus 메모리 문제의 상당 부분은 카디널리티에서 온다. Prometheus 가 떠 있지 않을 때는 promtool tsdb analyze 로 카디널리티가 높은 지표를 찾는다. 메모리 제한만 올려서는 답이 되지 않았다. 메모리가 치솟는 것은 재생 단계뿐이었기 때문이다.
- 증상
2024-04-15 12:32 에 계획된 Prometheus 변경을 적용한 뒤 Prometheus 를 쓸 수 없게 되었다. 팀은 prometheus 파드가 여러 번 재시작한 것을 보았다. 그동안 Cloud Platform 에는 모니터링이 없었고 지표가 빠졌다.
- 촉발
계획된 변경으로 Prometheus 를 재시작했는데 그때 WAL 수가 평소보다 많아, WAL 다시 읽기가 startupProbe 기본 허용 시간인 15분 안에 끝나지 않았다.
- 원인
- 구성 요소
- 기여 요인
- 감지
계획된 Prometheus 변경 뒤 팀이 prometheus 파드가 여러 번 재시작한 것을 보고 알았다. 처음 감지한 시각은 2024-04-15 12:32 였다.
- 조치
- startupProbe 허용 시간을 기본값 15분에서 30분으로 늘려 WAL 다시 읽기가 끝날 때까지 기다리게 했다.
- 후속 조치
- 팀은 계획된 Prometheus 재시작을 WAL 수가 적을 때 해서 재시작 시간을 줄이는 방안을 논의했다.
- Prometheus 의 기본 CPU 와 메모리 요청값을 최대 사용량에 맞춰 설정했다.
- 운영 환경의 WAL 수를 재현하는 테스트 환경을 만든다.
- memory-snapshot-on-shutdown 과 auto-gomaxprocs 기능 플래그를 검토한다.
- WAL 파일을 다른 위치의 원격 저장소에 두는 방법을 검토한다.
- 운영과 같은 구성의 블루그린 Prometheus 를 만들어 운영에 적용하기 전에 변경을 시험하는 방안을 알아본다.
- Amazon Managed Prometheus 를 간단히 조사한다.
IL-0176시계열 급증으로 호스트 메모리가 바닥나자 oom_score_adj 999 를 받은 Prometheus 컨테이너가 커널 OOM Killer 에게 먼저 죽어 CrashLoopBackOff 에 빠졌다.LINE2020- 증상
어느 월요일 아침, 엔지니어가 쿠버네티스 클러스터 경고를 보려고 Prometheus 대시보드를 열었는데 접속되지 않았다. Prometheus 서버 파드는 CrashLoopBackOff 상태였다.
- 촉발
Prometheus 가 시작한 지 5분 만에 시계열 수가 2,162,256 까지 급증해 메모리 8GB 호스트의 메모리를 거의 다 썼다.
- 원인
- 구성 요소
- 기여 요인
- 감지
월요일 아침 엔지니어가 클러스터 경고를 확인하려고 Prometheus 대시보드를 열었다가 접속되지 않는 것을 보고 알았다.
- 조치
- Prometheus configMap 에서 불필요한 설정 대부분을 지워 컨테이너가 더 이상 비정상 종료되지 않게 했다.
- 후속 조치
- Prometheus 파드의 requests 와 limits 를 알맞게 고친다. 지금 문제를 완전히 풀지는 못해도 비슷한 문제를 막아 해결 시간을 줄인다.
- 불필요한 수집 지표를 줄이도록 수집 대상이나 수집 간격을 조정한다.
- Prometheus 에 필요한 메모리를 예측해 새 호스트를 마련하고 deploy-topology: Prometheus 같은 노드 레이블을 붙인 뒤, 매니페스트에 nodeSelector 를 넣어 Prometheus 파드가 그 호스트에만 배치되게 한다.
- 교훈
원인은 둘이었다. 첫째, Prometheus 파드의 requests 와 limits 를 잘못 잡아 Prometheus 서버 컨테이너가 높은 oom_score_adj 를 받았다. 둘째, 대규모 클러스터에서 Prometheus 가 쓸 메모리를 미리 예측하지 않았다. 쿠버네티스에서 파드의 QoS 클래스는 메모리가 모자랄 때 어느 컨테이너가 먼저 죽는지에 영향을 준다. 커널의 OOM Killer 는 메모리 사용량과 oom_score_adj 로 점수를 매기고, kubelet 은 QoS 클래스에 따라 oom_score_adj 를 정한다.
이 6건에서 가장 많이 나오는 구성 요소: Prometheus, 컨테이너 메모리 한도. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별1
용량 한계6건
- 구성 요소
- 기여 요인
IL-0581이구위크 첫날 Redis 커넥션이 실패하며 29CM 상품 전시 서버의 파드가 다운되고 Netty 이벤트 루프가 포화됐다MUSINSA2025IL-0232codfw WikiKube 클러스터에서 Calico 구성 요소가 자원 한도에 걸려 calico-node 파드가 하나씩 죽고 노드가 차례로 빠지면서 MediaWiki 지연과 오류가 났다IL-0044kube-prometheus-stack 업그레이드 뒤 Prometheus 가 WAL 재생 중 메모리를 50Gi 넘게 써서 시작할 때마다 OOMKilled 로 죽었다Saifeddine Rajhi2024IL-0046계획된 재시작 뒤 Prometheus 가 WAL 을 다 읽기 전에 startupProbe 에 걸려 재시작을 반복했고 지표가 빠졌다IL-0176시계열 급증으로 호스트 메모리가 바닥나자 oom_score_adj 999 를 받은 Prometheus 컨테이너가 커널 OOM Killer 에게 먼저 죽어 CrashLoopBackOff 에 빠졌다.LINE2020IL-0503GKE 노드의 메모리가 바닥나 mybinder.org 의 proxy 파드가 OOM 으로 죽고 새 서버 실행이 실패했다Binder Project2017