Incident Library

IL-0232 Wikimedia Foundation · 2024-10-09kubernetesnetworking

codfw WikiKube 클러스터에서 Calico 구성 요소가 자원 한도에 걸려 calico-node 파드가 하나씩 죽고 노드가 차례로 빠지면서 MediaWiki 지연과 오류가 났다

한 운영자가 새 mwscript-k8s 도구로 TimedMediaHandler 의 requeueTranscodes.php 를 돌려 동영상 트랜스코딩을 일괄 정비했다. 작업은 몇 시간 동안 문제없이 돌았지만, mwscript-k8s 는 설계상 스크립트를 실행할 때마다 helm 릴리스 하나를 통째로 배포했다. 그 결과 Calico NetworkPolicy 가 2천 개 가까이 생겼고 그 밖의 리소스도 많이 생겼다. WikiKube 의 모든 Calico 구성 요소가 늘어나는 정책에 맞춰 일을 더 해야 했고, 그중 일부가 자원 한도에 닿아 스로틀링되다가 실패했다. 그러자 하드웨어 노드가 하나씩 서비스에서 빠지는 장애가 천천히 번졌다.

2024-10-09 05:01:36 UTC 부터 주 데이터센터 codfw 의 MediaWiki 노드가 과부하에 걸려, 로그인 사용자의 요청, 편집, API 호출처럼 캐시되지 않은 요청이 약 한 시간 동안 높은 지연이나 오류를 겪었다. 자동 모니터링의 알림을 받은 당직 SRE 가 대응했고, calico-kube-controllers 의 크래시 루프와 쿠버네티스 API 타임아웃, 줄어드는 calico-node 파드를 확인했다. 05:50 UTC 에 장애를 선언했다. 대응자들은 calico 와 typha 파드가 자원 한도에 닿은 것을 보고 한도를 올리는 변경을 CI 를 기다리지 않고 바로 반영해 06:05 UTC 에 helmfile 로 적용했다. 06:07 UTC 에 ready 인 calico-node 가 212개로 돌아왔고, 06:10 UTC 에 Calico 가 회복되어 사용자 영향이 끝났다. 대응자 중 한 사람은 한도를 올린 것보다 모든 calico 파드를 한꺼번에 다시 배포한 것이 회복에 더 도움이 되었을 수 있다고 보았다.

회복 뒤 원인을 찾았다. etcd 의 configmap 객체가 몇 시간 사이에 두 배로 늘었고, 이는 jobs.batch 객체와 그 NetworkPolicy 의 증가와 정확히 맞았다. mw-script 네임스페이스의 job 은 1791개였다. 대응자 한 사람은 calico 가 내려가면 파드가 다시 배치되고, 다시 배치된 파드가 calico 에 부담을 더 주는 되먹임이 생겼다고 추정했다. 이 장애는 2024-04-03 calico/typha 장애와 비슷하다고 기록되었다.

심각도
–
영향 범위
For about one hour after 05:00 UTC some uncached MediaWiki requests, such as those from logged-in users, edits and API calls, saw high latency or errors from overloaded MediaWiki nodes in the primary datacenter
영향 사용자
Logged-in users, editors and API clients making uncached requests
지역
codfw
감지까지
–
복구까지
1h 8m

증상

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 알림이 울렸다.

KubernetesCalicoDown 알림 수가 꾸준히 늘었다. kubectl -n kube-system get po -l k8s-app=calico-kube-controllers 로 보니 calico-kube-controllers-57c75d4867-cgzpc 가 0/1 CrashLoopBackOff 였고 21번 재시작한 상태였다. calico-node 파드도 많은 수가 calico-node-s89nl 0/1 CrashLoopBackOff 처럼 크래시 루프에 빠지거나, Running 이지만 ready 가 아니었다. calico-node 파드의 liveness probe 도 실패했다. 06:04 UTC 에는 calico-node 파드가 온전히 동작하는 노드가 25대뿐이었다.

calico-kube-controllers 로그에는 쿠버네티스 API 호출이 타임아웃되는 줄이 찍혔다. 그 줄은 [ERROR][1] client.go 272: Error getting cluster information config ClusterInformation="default" error=Get "https://10.192.72.1:443/apis/crd.projectcalico.org /v1/clusterinformations/default": context deadline exceeded 과 [FATAL][1] main.go 124: Failed to initialize Calico datastore error=Get "https://10.192.72.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default": context deadline exceeded 였다. typha 는 사용할 수 있는 상태로 보였다. calico-node 로그에는 눈에 띄는 것이 거의 없었고, 가장 이상한 줄은 bird: I/O loop cycle took 7808 ms for 6 events 였다. 나중에는 felix/health.go 211: Reporter is not ready. name="int_dataplane" 경고도 나왔다.

지표에서는 calico 와 typha 파드가 자원 한도에 닿아 있었다. 쿠버네티스 API 의 get 과 list 호출은 03:00 과 04:00 UTC 사이부터 크게 늘어 있었다. calico typha 가 도는 노드의 수신 트래픽도 04:00 쯤부터 급격히 늘었고, 그 크기는 초당 약 7MB 였다. etcd 의 configmap 객체는 02:00 과 06:00 사이에 6천 개에서 1만 2천 개로 두 배가 되었고, jobs.batch 객체와 그에 딸린 NetworkPolicy 도 같이 늘었다. kubectl -n mw-script get jobs |wc -l 의 결과는 1791 이었다.

MediaWiki 쪽 영향은 application-servers-red-k8s 대시보드에서 잘 드러나지 않았다. 가장 뚜렷한 신호는 200 응답이 약 5분 동안 4천에서 3천으로 25% 줄어든 것이었고, 지연도 잠깐 늘었다.

대응자들은 처음에 etcd 문제를 의심했다. 호스트별 CPU 사용량은 조금 늘었지만 CPU 가 꽉 찬 서버는 없었다. 대응자들은 이 증가가 파드 재시작 때문이라고 보았다. 앞서 울린 KubernetesAPILatency 알림이 관련 있는지도 따져 보았다. 자원 한도를 올리는 수정이 듣지 않으면 트래픽을 eqiad 로 되돌리자는 의견이 나왔다. 하지만 데이터베이스 팀이 먼저 할 일이 있는지 몰라 대응자들은 바로 전환할 수 있을지 확신하지 못했다.

증상 오류율 상승지연 시간 증가컨테이너 재시작 반복프로브 실패컨트롤 플레인 지연

원인

촉발
한 운영자가 새 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 알림이 울렸다.

조치

후속 조치

교훈

완전한 장애 직전까지 갔다. 자동 모니터링이 장애를 잡았다. 새로 들어온 여러 사람이 함께 본 덕에 근본 원인을 찾았다. 미주 SRE 에서 EMEA SRE 로 장애 대응을 문제없이 넘겼다. 반면 최종 사용자에게 영향이 갔고, 비상시에 eqiad 로 전환할 수 있는지 확신하지 못했다.

운도 따랐다. 장애는 미주 SRE 근무가 끝나고 EMEA SRE 근무가 시작되기 바로 전에 발견되었다. 이 시간대는 오래전부터 대응 인력이 비는 때로 알려져 있었다. 트랜스코딩 작업을 미국의 금요일 저녁에 넣지 않은 것도 다행이었다.

출처

참고 문서

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: Calico, Helm, 잡과 크론잡. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.