{"id":"IL-0232","org":"Wikimedia Foundation","date":"2024-10-09","docs":["https://wikitech.wikimedia.org/wiki/Application_servers/Runbook","https://wikitech.wikimedia.org/wiki/API_Gateway#How_to_debug_it","https://wikitech.wikimedia.org/wiki/Calico#Operations"],"title":{"en":"Calico pods in the codfw WikiKube cluster hit their resource limits and crash-looped, taking nodes out one by one","ko":"codfw WikiKube 클러스터에서 Calico 구성 요소가 자원 한도에 걸려 calico-node 파드가 하나씩 죽고 노드가 차례로 빠지면서 MediaWiki 지연과 오류가 났다"},"domain":["kubernetes","networking"],"impact":{"scope":"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","users":"Logged-in users, editors and API clients making uncached requests","region":"codfw"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"The incident came close to a full outage. Automated monitoring caught it and many responders found the cause, but end users were affected and responders were unsure whether they could switch over to eqiad. The problem was noticed just before the hand-off from Americas to EMEA SRE shifts, a period with a long-known lack of coverage, and it helped that the transcodes were not queued on a Friday evening in the US.","ko":"완전한 장애 직전까지 갔다. 자동 모니터링이 장애를 잡았다. 새로 들어온 여러 사람이 함께 본 덕에 근본 원인을 찾았다. 미주 SRE 에서 EMEA SRE 로 장애 대응을 문제없이 넘겼다. 반면 최종 사용자에게 영향이 갔고, 비상시에 eqiad 로 전환할 수 있는지 확신하지 못했다.\n\n운도 따랐다. 장애는 미주 SRE 근무가 끝나고 EMEA SRE 근무가 시작되기 바로 전에 발견되었다. 이 시간대는 오래전부터 대응 인력이 비는 때로 알려져 있었다. 트랜스코딩 작업을 미국의 금요일 저녁에 넣지 않은 것도 다행이었다."},"related":[],"sources":[{"url":"https://wikitech.wikimedia.org/wiki/Incidents/2024-10-09_calico-codfw","kind":"runbook","archived":"https://web.archive.org/web/20260115055441/https://wikitech.wikimedia.org/wiki/Incidents/2024-10-09_calico-codfw"}],"summary":{"en":"Wikimedia's mwscript-k8s utility runs MediaWiki maintenance scripts on the WikiKube Kubernetes cluster and, by design, deploys an entire helm release for each script invocation. An operator used it for a batch of video transcode requeues. The batch ran without trouble for hours while the number of resources it created grew steadily: close to 2k Calico NetworkPolicies, 1791 jobs in the mw-script namespace and a doubling of ConfigMaps in etcd. Every Calico component in WikiKube had to process the growing number of NetworkPolicies, and some of them reached their resource limits, were throttled and then failed. calico-node pods crash-looped or stopped being ready, the Calico controller's API calls timed out, and hardware nodes in codfw dropped out of service one after another. MediaWiki nodes in the primary datacenter were overloaded and uncached requests saw high latency and errors from 05:01 UTC.\n\nResponders saw the Calico and Typha pods at their resource limits and prepared a change to raise them. While it was being applied with helmfile at about 06:05 UTC, the team also discussed moving traffic for everything except MediaWiki read-write to eqiad but was unsure whether a switchover was possible. The helmfile apply replaced the Calico pods with new healthy ones, 212 calico-node pods were ready by 06:07 UTC, and Calico had recovered by 06:10 UTC. One responder noted that the recovery may have come from redeploying all Calico pods at once rather than from the higher limits. Only afterwards did the team link the growth of objects to the mwscript-k8s jobs and find the requeueTranscodes.php invocation behind them. A responder linked the similar earlier incident \"2024-04-03 calico/typha down\", and the incident scorecard records that this incident was not different enough from earlier ones to be ruled out as a repeat.","ko":"한 운영자가 새 mwscript-k8s 도구로 TimedMediaHandler 의 requeueTranscodes.php 를 돌려 동영상 트랜스코딩을 일괄 정비했다. 작업은 몇 시간 동안 문제없이 돌았지만, mwscript-k8s 는 설계상 스크립트를 실행할 때마다 helm 릴리스 하나를 통째로 배포했다. 그 결과 Calico NetworkPolicy 가 2천 개 가까이 생겼고 그 밖의 리소스도 많이 생겼다. WikiKube 의 모든 Calico 구성 요소가 늘어나는 정책에 맞춰 일을 더 해야 했고, 그중 일부가 자원 한도에 닿아 스로틀링되다가 실패했다. 그러자 하드웨어 노드가 하나씩 서비스에서 빠지는 장애가 천천히 번졌다.\n\n2024-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 파드를 한꺼번에 다시 배포한 것이 회복에 더 도움이 되었을 수 있다고 보았다.\n\n회복 뒤 원인을 찾았다. etcd 의 configmap 객체가 몇 시간 사이에 두 배로 늘었고, 이는 jobs.batch 객체와 그 NetworkPolicy 의 증가와 정확히 맞았다. mw-script 네임스페이스의 job 은 1791개였다. 대응자 한 사람은 calico 가 내려가면 파드가 다시 배치되고, 다시 배치된 파드가 calico 에 부담을 더 주는 되먹임이 생겼다고 추정했다. 이 장애는 2024-04-03 calico/typha 장애와 비슷하다고 기록되었다."},"trigger":{"en":"An operator used the new mwscript-k8s utility to run a batch of video transcode maintenance, the TimedMediaHandler requeueTranscodes.php script. mwscript-k8s deploys a whole helm release for every script invocation, so the batch created close to 2k Calico NetworkPolicies along with many other resources over several hours.","ko":"한 운영자가 새 mwscript-k8s 도구로 TimedMediaHandler 의 requeueTranscodes.php 를 돌려 동영상 트랜스코딩을 일괄 정비했다. mwscript-k8s 는 스크립트를 실행할 때마다 helm 릴리스를 통째로 배포하므로, 이 작업이 몇 시간 동안 리소스를 계속 만들었다."},"severity":"unknown","symptoms":["high-error-rate","high-latency","crash-loop","readiness-probe-failures","control-plane-slow"],"timeline":{"detected_after":null,"resolved_after":"1h 8m"},"date_kind":"incident","detection":{"en":"Automated monitoring detected the issue and paged the on-call SRE: GatewayBackendErrorsHigh at 05:01:36 UTC, 16 KubernetesCalicoDown alerts at 05:03:32 UTC and MediaWikiMemcachedHighErrorRate at 05:04:15 UTC.","ko":"자동 모니터링이 알아채고 당직 SRE 가 대응했다. 05:01:36 UTC 에 GatewayBackendErrorsHigh, 05:03:32 UTC 에 KubernetesCalicoDown 16건, 05:04:15 UTC 에 MediaWikiMemcachedHighErrorRate 알림이 울렸다."},"components":["calico","helm","job-controller"],"root_cause":"capacity","remediation":[{"text":{"en":"Raised the resource limits of the Calico and Typha pods and applied the change with helmfile, which redeployed all Calico pods","ko":"calico 와 typha 의 자원 한도를 올리는 변경을 CI 를 기다리지 않고 반영하고, helmfile -e codfw --selector name=calico apply -i --context 5 로 적용했다. 적용 중 새 calico 파드가 정상으로 떴고, 06:10 UTC 에 Calico 가 회복되었다."}}],"action_items":[{"text":{"en":"Stop mwscript-k8s from creating so many resources","ko":"mwscript-k8s 가 리소스를 너무 많이 만드는 문제를 해결한다."}}],"contributing":["delayed-effect-change","no-runbook"],"recurrence_of":null,"symptoms_text":{"en":"At 05:01 UTC on 9 October 2024 a page fired for GatewayBackendErrorsHigh, elevated 5xx errors from page-analytics_cluster in codfw, followed by a growing number of KubernetesCalicoDown alerts for WikiKube nodes not running the calico-node pod and by MediaWikiMemcachedHighErrorRate. For about an hour uncached MediaWiki requests, such as those of logged-in users, edits and API calls, saw high latency or errors.\n\nkubectl showed calico-kube-controllers in CrashLoopBackOff with 21 restarts. Its log ended in \"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\" and then \"[FATAL][1] main.go 124: Failed to initialize Calico datastore\", so the Kubernetes API calls of the Calico controller were timing out. Typha looked available. calico-node pods failed their liveness probes and went into CrashLoopBackOff or stayed Running but not ready; their logs showed \"bird: I/O loop cycle took 7808 ms for 6 events\" and later \"felix/health.go 211: Reporter is not ready. name=\"int_dataplane\"\". At 06:04 UTC only 25 nodes still had fully working calico-node pods.\n\nResponders first asked whether etcd was the problem, found a rise in host CPU without any pegged machine and put it down to pod restarts, and saw nothing unusual in the Calico pod logs. A dashboard then showed the Calico and Typha pods hitting their resource limits. GET and LIST calls to the Kubernetes API had been rising since between 03:00 and 04:00 UTC, mostly for node and endpoint objects, and nodes running Typha saw a sharp rise in received traffic, about 7MB/s, from around 04:00 UTC. The effect on MediaWiki was hard to see on the application server dashboard: successful 200 responses fell by 25%, from 4k to 3k, for about five minutes, and latency rose briefly.\n\nAfter recovery, ConfigMaps in the codfw etcd were found to have roughly doubled from 6k to 12k between 02:00 and 06:00 UTC, matching the count of jobs.batch objects and their network policies. `kubectl -n mw-script get jobs |wc -l` returned 1791, all younger than eight hours.","ko":"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 알림이 울렸다.\n\nKubernetesCalicoDown 알림 수가 꾸준히 늘었다. 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대뿐이었다.\n\ncalico-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\" 경고도 나왔다.\n\n지표에서는 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 이었다.\n\nMediaWiki 쪽 영향은 application-servers-red-k8s 대시보드에서 잘 드러나지 않았다. 가장 뚜렷한 신호는 200 응답이 약 5분 동안 4천에서 3천으로 25% 줄어든 것이었고, 지연도 잠깐 늘었다.\n\n대응자들은 처음에 etcd 문제를 의심했다. 호스트별 CPU 사용량은 조금 늘었지만 CPU 가 꽉 찬 서버는 없었다. 대응자들은 이 증가가 파드 재시작 때문이라고 보았다. 앞서 울린 KubernetesAPILatency 알림이 관련 있는지도 따져 보았다. 자원 한도를 올리는 수정이 듣지 않으면 트래픽을 eqiad 로 되돌리자는 의견이 나왔다. 하지만 데이터베이스 팀이 먼저 할 일이 있는지 몰라 대응자들은 바로 전환할 수 있을지 확신하지 못했다."},"updated_at":"2026-11-14T05:53:45.025066Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0232","org_slug":"wikimedia-foundation"}