OpenAI 【2024 年 12 月 11 日】停服事件复盘
原文
https://status.openai.com/incidents/ctrsv3lwd797
省流分析
K8s 控制面过载了,但是 coredns 依赖了控制面,所以最后导致数据平面也出问题了。
参考:https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/
API Server 宕机后的影响
TTL 过期前:如果某条 DNS 记录已经被缓存(TTL 未过期),CoreDNS 可以继续返回这条缓存记录,即使 API Server 宕机也不会有问题。
TTL 过期后:如果 API Server 宕机且 CoreDNS 的缓存过期,CoreDNS 将无法从 API Server 获取新数据,最终会返回查询失败。
引言
这篇事后分析详细描述了 2024 年 12 月 11 日发生的一起事件,当时所有 OpenAI 服务都经历了显著的停机时间。问题源于一个新的**遥测服务(telemetry service)**部署,该服务无意中压垮了 Kubernetes 控制平面(API Server、ETCD等),导致关键系统出现连锁故障。在这篇来自官方的文章中,我们分解了根本原因,概述了采取的补救措施,并分享了我们正在实施的措施,以防止未来发生类似事件。
影响
在 2024 年 12 月 11 日的太平洋标准时间下午 3:16 至晚上 7:38 之间,所有 OpenAI 服务都经历了显著的退化(译者:服务降级)或完全不可用。这一事件是由于内部变更导致的,目的是在机群中推出新的遥测服务,并非由安全事件或最近的发布引起。所有产品在下午 3:16 开始退化。
• ChatGPT: 在太平洋标准时间下午 5:45 左右实现了实质性恢复,在晚上 7:01 完全恢复。
• API: 在太平洋标准时间下午 5:36 左右实现了实质性恢复,在晚上 7:38 所有模型完全恢复。
• Sora: 在晚上 7:01 完全恢复。
根本原因
OpenAI 全球运营着数百个 Kubernetes 集群。Kubernetes 有一个负责集群管理的控制平面,以及一个实际提供工作负载(如模型推理)的数据平面。
作为提高组织可靠性的一部分,我们一直在努力改进我们的集群级可观察性工具,以加强对系统状态的可见性。在太平洋标准时间下午 3:12,我们部署了一个新的遥测服务来收集详细的 Kubernetes 控制平面指标。
遥测服务的覆盖范围非常广泛,因此这个新服务的配置无意中导致每个集群中的每个节点执行资源密集型的 Kubernetes API 操作,其成本随着集群的大小而增加。随着数千个节点同时执行这些操作,Kubernetes API 服务器不堪重负,导致我们大多数大型集群的 Kubernetes 控制平面瘫痪。这个问题在我们的最大集群中最为明显,因此我们的测试没有捕捉到它——而 DNS 缓存使得问题在全舰队范围的部署开始之前变得不那么明显。
Kubernetes 数据平面可以在很大程度上独立于控制平面运行,但 DNS 依赖于控制平面——服务不知道如何在没有 Kubernetes 控制平面的情况下相互联系。
简而言之,根本原因是一个新的遥测服务配置意外地在大型集群中产生了巨大的 Kubernetes API 负载,压垮了控制平面并破坏了基于 DNS 的服务发现。
测试与部署
变更在暂存集群中进行了测试,没有观察到问题。影响特定于超过一定大小的集群,我们每个节点上的 DNS 缓存延迟了可见故障,使得变更得以继续进行。
我们在部署前的主要可靠性担忧是新遥测服务的资源消耗。在部署之前,我们评估了所有集群中的资源利用指标(CPU/内存),以确保部署不会干扰正在运行的服务。虽然资源请求在每个集群的基础上进行了调整,但没有采取预防措施来评估 Kubernetes API 服务器负载。这个变更过程监控了服务健康,但缺乏足够的集群健康监控协议。
Kubernetes 数据平面(负责处理用户请求)设计上可以独立于控制平面运行。然而,Kubernetes API 服务器需要用于 DNS 解析,这是我们许多服务的关键依赖。
DNS 缓存通过提供过时但功能正常的 DNS 记录暂时减轻了影响。然而,随着缓存记录在接下来的 20 分钟内过期,服务开始失败,因为它们依赖于实时 DNS 解析。这个时间点很关键,因为它延迟了问题的可见性,允许变更在问题的全部范围被理解之前继续进行。一旦 DNS 缓存为空,DNS 服务器的负载就会增加,给控制平面增加了更多负载,并进一步复杂化了立即缓解的措施。
补救措施
监控部署并回滚冒犯性的变更通常是直接的,我们有工具来检测并回滚不良部署。在这种情况下,我们的检测工具工作正常,我们在客户开始看到影响之前几分钟就检测到了问题。但解决这个问题需要我们移除冒犯性的服务。为了进行这个修复,我们需要访问 Kubernetes 控制平面——由于 Kubernetes API 服务器的负载增加,我们无法做到这一点。
我们在几分钟内识别出了问题,并立即启动了多个工作流程,探索不同的方法快速将我们的集群重新上线:
1. 缩小集群规模:减少了总体
Kubernetes API负载。2. 阻止对
Kubernetes管理API的网络访问:阻止了新的昂贵请求,给API服务器恢复的时间。3. 扩大
Kubernetes API服务器:增加了可用资源以处理待处理请求,使我们能够应用修复。
通过并行推进这三项措施,我们最终恢复了足够的控制,移除了冒犯性的服务。
一旦我们重新获得了一些 Kubernetes 控制平面的访问权限,我们立即看到了恢复。在可能的情况下,我们将流量转移到健康的集群,同时努力补救其他集群。由于许多服务同时尝试下载资源,饱和了资源限制,一些集群仍然处于降级状态,需要额外的手动干预。
这是一个多个系统和流程同时失败并以意想不到的方式相互作用的汇合点。具体来说:
• 我们的测试没有捕捉到变更对
Kubernetes控制平面的影响。•
DNS缓存在变更实施和服务开始失败之间增加了延迟。• 由于锁定效应,补救非常缓慢。
时间线
• 2024 年 12 月 10 日:新的遥测服务被部署到暂存集群并验证按预期工作。
• 2024 年 12 月 11 日下午 2:23:引入新服务的变更被合并,部署管道被触发。
• 下午 2:51 至 3:20:变更被应用于所有集群。
• 下午 3:13:警报触发,通知工程师。
• 下午 3:16:客户开始受到影响。
• 下午 3:16:确定根本原因。
• 下午 3:27:工程师开始将流量从受影响的集群转移。
• 下午 3:40:客户影响最大。
• 下午 4:36:第一个集群恢复。
• 晚上 7:38:所有集群恢复。
预防措施
为了防止类似事件的发生,我们正在实施以下措施:
1. 稳健的分阶段推出
我们将继续改进分阶段推出工作,并对所有基础设施变更进行更好的监控,以确保任何故障的影响有限,并在早期被检测到。所有与基础设施相关的配置变更将遵循稳健的分阶段推出流程,并进行改进的持续监控,确保服务工作负载和集群(包括 Kubernetes 控制平面)都是健康的。
2. 故障注入测试
Kubernetes 数据平面应该能够在没有控制平面的情况下生存更长时间,我们将运行明确锻炼这一场景的测试。我们还将运行测试,故意推出不良变更,以确保我们的系统能够检测并回滚。
3. 紧急 Kubernetes 控制平面访问
我们还没有机制来确保在数据平面对控制平面施加太多压力时访问 API 服务器。我们将实施应急机制,以确保工程师在任何情况下都能访问 Kubernetes API 服务器。
4. 解耦 Kubernetes 数据平面和控制平面
我们对 Kubernetes DNS 的依赖用于服务发现,这在 Kubernetes 数据平面和控制平面之间创建了一个链接。我们正在投资系统,以将 Kubernetes 数据平面从控制平面解耦,以便控制平面不承担处理关键服务和产品工作负载的负载。
5. 更快的恢复
我们将实施改进的缓存和动态速率限制器,用于集群启动所必需的资源,并定期进行练习,我们迅速替换整个集群,目标是快速且正确的启动。
结论
我们为这次事件给所有客户带来的影响道歉——从 ChatGPT 用户到开发者到依赖 OpenAI 产品的企业。我们没有达到自己的期望。我们认识到向你们所有人提供高度可靠的服务至关重要,并将优先考虑上述预防措施,以继续提高可靠性。感谢您在这次中断期间的耐心。