{"id":"IL-0005","org":"OpenAI","date":"2024-12-11","docs":[],"title":{"en":"A new telemetry service overloaded the Kubernetes API servers of large clusters and broke DNS-based service discovery for all OpenAI services","ko":"새 텔레메트리 서비스가 모든 노드에서 무거운 쿠버네티스 API 요청을 보내 대형 클러스터의 컨트롤 플레인이 무너졌고, DNS 기반 서비스 디스커버리가 깨져 OpenAI 의 모든 서비스가 멈췄다"},"domain":["kubernetes"],"impact":{"scope":"all OpenAI services, including ChatGPT, the API and Sora; control planes of most large clusters","users":"unknown","region":"global"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Several systems and processes failed at once and interacted in unexpected ways: tests did not catch the change's effect on the Kubernetes control plane, DNS caching put a delay between the change and the failures, and being locked out of the control plane made remediation very slow. Because service discovery used Kubernetes DNS, the control plane was carrying load for product traffic even though the data plane was meant to be independent of it.","ko":"이 장애는 여러 시스템과 절차가 동시에 실패하며 예상하지 못한 방식으로 얽혀 생겼다. 테스트는 이 변경이 쿠버네티스 컨트롤 플레인에 주는 영향을 잡지 못했다. DNS 캐시 때문에 변경과 서비스 실패 사이에 시간 차가 생겼다. 컨트롤 플레인에 접근할 수 없게 되면서 복구가 매우 느렸다.\n\n데이터 플레인이 컨트롤 플레인과 따로 돌도록 설계되어 있어도, DNS 기반 서비스 디스커버리가 컨트롤 플레인에 기대면 컨트롤 플레인 장애가 서비스 장애로 번진다. 배포 전 점검은 클러스터의 CPU 와 메모리 사용량만 봤고 API 서버 부하는 보지 않았다."},"related":[],"sources":[{"url":"https://status.openai.com/incidents/ctrsv3lwd797","kind":"official-status","license":"unknown","archived":"http://web.archive.org/web/20260512184336/https://status.openai.com/incidents/ctrsv3lwd797"}],"summary":{"en":"OpenAI runs hundreds of Kubernetes clusters around the world. As part of a reliability effort it deployed a new telemetry service to collect detailed Kubernetes control plane metrics. The service's configuration made every node in each cluster run resource-intensive Kubernetes API operations whose cost grew with the size of the cluster. With thousands of nodes doing this at once, the API servers were overwhelmed and the control plane went down in most large clusters, which also broke DNS-based service discovery.\n\nThe change had been tested in a staging cluster on 10 December without problems, because the effect only appears in clusters above a certain size. Before the rollout the team checked CPU and memory utilization in every cluster so the new service would not disrupt running services, and tuned resource requests per cluster, but took no precautions about API server load; the rollout monitored service health but lacked sufficient cluster health monitoring. The DNS cache on each node delayed visible failures long enough for the change to reach the whole fleet.\n\nAlerts fired a few minutes before customers were affected, but the fix, removing the service, needed the Kubernetes control plane, which the load had locked engineers out of. Teams worked in parallel: they scaled clusters down to cut the total API load, blocked network access to the Kubernetes admin APIs so that no new expensive requests arrived, and scaled up the API servers. Together this restored enough control to remove the service. Where possible, traffic was moved to healthy clusters; the first cluster recovered at 4:36 PM. Some clusters needed further manual work because many services downloading resources at once saturated resource limits.\n\nThe API recovered substantially at 5:36 PM and fully across all models at 7:38 PM PST. ChatGPT recovered substantially at 5:45 PM and fully at 7:01 PM, and Sora fully at 7:01 PM. OpenAI states that the outage was caused by this internal change, not by a security incident or a launch.","ko":"OpenAI 는 전 세계에서 수백 개의 쿠버네티스 클러스터를 운영한다. 신뢰성을 높이는 작업의 하나로 클러스터 관측 도구를 개선하고 있었고, 2024년 12월 11일 쿠버네티스 컨트롤 플레인 지표를 자세히 모으는 새 텔레메트리 서비스를 배포했다. 텔레메트리 서비스는 모든 노드에 깔린다. 새 설정 때문에 노드마다 쿠버네티스 API 요청을 보냈는데, 이 요청은 클러스터가 클수록 비용이 커진다. 노드 수천 대가 동시에 이 요청을 보내자 API 서버가 무너졌고, 대형 클러스터 대부분의 컨트롤 플레인이 멈췄다.\n\n데이터 플레인은 컨트롤 플레인과 대체로 따로 돌도록 설계되어 있다. 하지만 DNS 해석에는 쿠버네티스 API 서버가 필요하고, 서비스들은 DNS 로 서로를 찾는다. 서비스들은 노드의 DNS 캐시에 남은 오래된 레코드로 한동안 버텼지만, 20분에 걸쳐 레코드가 만료되자 실패했다. 이 지연 때문에 문제의 전체 범위를 알기 전에 배포가 계속 진행됐다.\n\n변경은 12월 10일 스테이징 클러스터에서 시험했고 문제가 보이지 않았다. 문제는 일정 크기를 넘는 클러스터에서만 나타났다. 배포 전에는 모든 클러스터에서 CPU 와 메모리 사용량을 점검해 새 서비스가 돌던 서비스를 방해하지 않는지 확인했지만, API 서버 부하는 따져 보지 않았다. 배포 과정에서 서비스 상태는 감시했지만, 클러스터 상태를 감시하는 절차는 부족했다.\n\n탐지 도구는 고객 영향 몇 분 전에 문제를 잡았다. 하지만 고치려면 문제 서비스를 지워야 했고, 그러려면 과부하 상태의 컨트롤 플레인에 접근해야 했다. 팀은 클러스터 규모를 줄이고, 쿠버네티스 관리 API 로 가는 네트워크를 막고, API 서버를 늘리는 일을 동시에 해서 문제 서비스를 지울 수 있을 만큼 제어권을 되찾았다. 일부 클러스터에서는 많은 서비스가 동시에 자원을 내려받다가 자원 한도가 차서 손으로 추가 조치를 해야 했다. ChatGPT 는 오후 5시 45분에 상당 부분, 7시 1분에 완전히 회복했다. API 는 5시 36분에 상당 부분, 7시 38분에 모든 모델에서 완전히 회복했다. Sora 는 7시 1분에 완전히 회복했다."},"trigger":{"en":"At 2:23 PM PST a change introducing a new telemetry service, which collects detailed Kubernetes control plane metrics, was merged and the deployment pipeline started. Between 2:51 PM and 3:20 PM the change was applied to all clusters.","ko":"오후 3시 12분 PST 에 쿠버네티스 컨트롤 플레인 지표를 자세히 수집하는 새 텔레메트리 서비스를 배포했다. 이 서비스의 설정 때문에 각 클러스터의 모든 노드가 무거운 쿠버네티스 API 요청을 보냈다. 이 요청은 클러스터가 클수록 비용이 커진다. 변경은 오후 2시 51분부터 3시 20분 사이에 모든 클러스터에 적용됐다."},"severity":"unknown","symptoms":["service-unavailable","high-error-rate","control-plane-unresponsive","dns-resolution-failures"],"timeline":{"detected_after":"22m","resolved_after":"4h22m"},"date_kind":"incident","detection":{"en":"OpenAI's detection tools worked: alerts fired at 3:13 PM PST, a few minutes before customer impact began at 3:16 PM, and the root cause was identified at 3:16 PM.","ko":"변경이 모든 클러스터에 적용되던 오후 3시 13분 PST 에 알림이 울려 엔지니어들에게 전달됐다. 탐지 도구는 고객이 영향을 받기 몇 분 전에 문제를 잡았고, 엔지니어들은 3시 16분에 원인을 찾았다. 다만 노드의 DNS 캐시가 실제 실패를 늦춰, 문제의 전체 범위가 보이기 전에 배포가 계속 진행됐다."},"components":["kube-apiserver","dns-resolver","telemetry-agent"],"root_cause":"config-change","remediation":[{"text":{"en":"Scaled clusters down to reduce the total Kubernetes API load","ko":"클러스터 규모를 줄여 쿠버네티스 API 부하의 총량을 낮췄다."}},{"text":{"en":"Blocked network access to the Kubernetes admin APIs so no new expensive requests arrived","ko":"쿠버네티스 관리 API 로 가는 네트워크 접근을 막아 새로 들어오는 무거운 요청을 차단하고 API 서버가 회복할 시간을 벌었다."}},{"text":{"en":"Scaled up the Kubernetes API servers","ko":"쿠버네티스 API 서버를 증설해 밀린 요청을 처리할 자원을 늘리고 수정을 적용할 수 있게 했다."}},{"text":{"en":"Removed the telemetry service once enough control was back","ko":"컨트롤 플레인 제어권을 되찾은 뒤 문제의 텔레메트리 서비스를 지웠다."}},{"text":{"en":"Moved traffic from impacted clusters to healthy ones","ko":"오후 3시 27분부터 영향받은 클러스터에서 트래픽을 빼기 시작했고, 가능한 곳에서는 트래픽을 정상 클러스터로 옮겼다."}},{"text":{"en":"Intervened manually in clusters where simultaneous resource downloads saturated resource limits","ko":"많은 서비스가 동시에 자원을 내려받아 자원 한도가 찬 클러스터에는 추가로 수동 조치를 했다."}}],"action_items":[{"text":{"en":"Put every infrastructure configuration change through a phased rollout with continuous monitoring of both the service workloads and the clusters, including the Kubernetes control plane","ko":"모든 인프라 설정 변경에 단계적 배포를 적용하고, 서비스 워크로드와 쿠버네티스 컨트롤 플레인을 포함한 클러스터 상태를 계속 감시한다."}},{"text":{"en":"Run fault injection tests in which the data plane runs without the control plane for longer, and tests that roll out bad changes on purpose to check detection and rollback","ko":"데이터 플레인이 컨트롤 플레인 없이 버티는 상황과 잘못된 변경을 일부러 배포하는 상황을 시험하는 장애 주입 테스트를 돌린다."}},{"text":{"en":"Build break-glass mechanisms so engineers can reach the Kubernetes API servers in any circumstances","ko":"데이터 플레인이 컨트롤 플레인을 지나치게 압박할 때도 엔지니어가 쿠버네티스 API 서버에 접근할 수 있는 비상 접근 수단을 만든다."}},{"text":{"en":"Decouple the Kubernetes data plane from the control plane so that service discovery for critical workloads does not depend on the control plane","ko":"데이터 플레인과 컨트롤 플레인을 분리한다. 서비스 디스커버리가 쿠버네티스 DNS 에 묶여 있는 구조를 풀어, 핵심 서비스가 요청을 처리할 때 컨트롤 플레인에 기대지 않게 한다."}},{"text":{"en":"Speed up recovery with better caching and dynamic rate limiters for resources needed at cluster startup, and regular drills that rapidly replace an entire cluster","ko":"클러스터 기동에 필요한 자원에 캐시와 동적 속도 제한을 더하고, 클러스터 하나를 통째로 빠르게 교체하는 훈련을 정기적으로 한다."}}],"contributing":["staging-not-representative","no-staged-rollout","failure-delayed-by-cache","monitoring-blind-spot","limited-debug-access"],"recurrence_of":null,"symptoms_text":{"en":"Alerts fired at 3:13 PM PST on 11 December 2024, and from 3:16 PM every OpenAI service was significantly degraded or completely unavailable, including ChatGPT, the API and Sora. The status page reported API calls returning errors and difficulties logging in to platform.openai.com and ChatGPT. Customer impact peaked at 3:40 PM.\n\nThe Kubernetes API servers in most of OpenAI's large clusters were overwhelmed and the control plane went down. The data plane, which serves workloads such as model inference, can run largely without the control plane, but DNS-based service discovery depends on it, so services could no longer find each other.\n\nThe failure showed up gradually. The DNS cache on each node kept serving stale but working records, so services kept running at first while the rollout continued. As the cached records expired over the following 20 minutes, services that need live DNS resolution began to fail, and once the caches were empty the load on the DNS servers multiplied and added still more load to the control plane.\n\nEngineers found the cause within minutes, but could not remove the offending service: that required the Kubernetes API, which was too overloaded to answer. Even after access came back, some clusters stayed degraded because many services tried to download resources at the same time and saturated resource limits.","ko":"2024년 12월 11일 오후 3시 13분 PST 에 알림이 울려 엔지니어들에게 전달됐다. 3시 16분부터 ChatGPT, API, Sora 를 포함한 OpenAI 의 모든 서비스가 크게 느려지거나 완전히 멈췄다.\n\n상태 페이지에는 API 호출이 오류를 내고 platform.openai.com 과 ChatGPT 에 로그인하기 어렵다는 보고가 올라왔다. 영향받은 구성 요소는 Chat Completions, Fine-tuning, Embeddings, Images, Batch, Audio, Moderations, Realtime, Files, Conversations, Login, Search, File uploads, Voice mode 였다.\n\n대형 클러스터 대부분에서 쿠버네티스 API 서버가 과부하로 무너져 컨트롤 플레인이 멈췄다. 서비스들은 노드마다 있는 DNS 캐시에 남은 오래된 레코드로 한동안 버텼다. 캐시된 레코드가 다음 20분에 걸쳐 만료되면서 실시간 DNS 해석에 의존하는 서비스들이 실패하기 시작했다. 캐시가 비자 DNS 서버 부하가 몇 배로 늘었고 컨트롤 플레인 부하도 더 커졌다. 고객 영향은 3시 40분에 가장 컸다.\n\n엔지니어들은 3시 16분에 원인을 찾았다. 문제 서비스를 지우려면 쿠버네티스 컨트롤 플레인에 접근해야 했지만, API 서버 과부하 때문에 접근할 수 없었다."},"updated_at":"2026-11-10T00:00:31.448812Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0005","org_slug":"openai"}