从2023年11月2日星期四UTC时间11:43开始,Cloudflare的控制面板和分析服务发生了故障。Cloudflare的控制面板主要包括面向客户的所有服务的界面,包括我们的网站和API。我们的分析服务包括日志记录和分析报告。
事件从UTC时间11月2日11:44持续到 UTC时间11月4日04:25。截至UTC时间11月2日17:57,我们已经能够在我们的灾难恢复设施中恢复大部分的控制平面。在灾难恢复设施上线之后,许多客户在使用我们的大多数产品时不会遇到问题。然而,其他服务恢复时间较长,使用这些服务的客户可能会在我们完全解决事件之前遇到问题。在事件发生期间,我们的原始日志服务对大多数客户不可用。
现在所有客户的服务已经恢复。在整个事件中,Cloudflare的网络和安全服务仍然正常工作。虽然有时客户无法更改这些服务,但我们的网络流量没有受到影响。
本文概述了导致此事件发生的事件、我们为防止此类问题而制定的体系结构、哪些部分失败了、哪些部分起了作用、以及我们根据过去36小时所学到的知识所进行的更改。
首先,这本不应该发生。我们认为已经实施了高可用性系统,即使其中一个核心数据中心提供商遭到灾难性故障,也应该能够阻止此次停机事件。虽然许多系统确实按设计在线,但一些关键系统具有非显而易见的依赖关系,使其不可用。对于此次事件以及对我们的客户和团队所造成的痛苦,我感到抱歉和尴尬。
Intended Design
Cloudflare的控制平面和分析系统主要运行在位于俄勒冈州希尔斯伯勒周围的三个数据中心的服务器上。三个数据中心相互独立,每个都有多个公用事业电力供应,并且每个都有多个冗余和独立的网络连接。
这些设施是故意选择距离相隔一定距离的位置,以最小化自然灾害造成三个设施全部受到影响的可能性,但仍足够接近,使它们能够同时运行活动-活动冗余数据集群。这意味着它们在三个设施之间持续同步数据。按设计,如果任何一个设施离线,则其余的设施能够继续操作。
这是一个系统设计,我们在四年前开始实施。尽管我们的大部分关键控制面系统已经迁移到高可用集群,但一些服务,尤其是一些较新的产品的服务,还没有添加到高可用集群中。
另外,我们的日志系统故意不包含在高可用性集群中。这个决策的逻辑是,日志已经是一个分布式问题,日志会在我们的网络边缘排队,然后发送回俄勒冈的核心(或者为使用区域服务进行日志记录的客户提供其他区域设施)。如果我们的日志设备离线,那么分析日志将在我们的网络边缘排队,直到它恢复。我们确定,分析被延迟是可以接受的。
Flexential Data Center Power Failure
俄勒冈三个设施中最大的由Flexential运营。我们称之为“PDX-DC04”。Cloudflare在PDX-04租赁空间,我们在那里设有最大的分析集群以及我们高可用性集群三分之一以上的机器。它也是尚未上线到我们高可用性集群的服务的默认位置。我们是该设施的相对较大的客户,占用其总能力的约10%。
11月2日08:50 UTC,服务于PDX-04的公用事业公司波特兰通用电气(PGE)发生了一次非计划的维护事件,影响到了建筑物中一条独立电源馈线。该事件导致PDX-04的一条馈线被切断。数据中心拥有多个馈线,其中一些具有一定的独立性以供电该设施。然而,Flexential启动了他们的发电机,有效地补充了被切断的馈线。
与最佳实践相反,Flexential并没有通知Cloudflare他们已经转向了发电机电源。我们的可观测性工具都不能检测到电源的改变。如果他们告知我们,我们将组建一个团队密切监测该设施,并在其降级时移动依赖该设施的控制平面服务。
同时运行唯一存留的公共事业供电线路和发电机也是不寻常的。在能源需求高峰期,公共事业通常要求数据中心脱离电网,独自运行发电机供电。Flexential运营着10台发电机,包括备用机组,能够支持设施全负载。Flexential也可以只从唯一存留的公共事业供电线路运行设施。我们并没有得到其为什么同时运行公共事业供电和发电机供电的明确答复。
Informed Speculation On What Happened Next
从这个决定开始,我们还没有从Flexential那里得到根本原因或一些决定或事件的清晰度。我们将在从Flexential以及PGE得到更多信息时更新此帖子,并根据最有可能的事件序列以及个别Flexential员工非官方地与我们分享的内容提出一些基于信息的猜测。
他们可能让这条公用事业线路保持运行的原因之一是因为Flexential是与PGE参与的DSG计划的一部分。DSG允许当地公用事业公司运行数据中心的发电机以帮助为电网提供额外的电力。作为交换,电力公司帮助维护发电机并提供燃料。我们无法找到任何Flexential通知我们DSG计划的记录。我们已经询问DSG是否在当时活跃,并且没有收到答案。我们不知道它是否对Flexential做出的决策有所贡献,但它可能解释了为什么在发电机启动后公用事业线路仍然保持在线状态。
大约在11:40 UTC,PDX-04的一台PGE变压器出现接地故障。我们认为,但没有得到Flexential或PGE的确认,这就是从电网步下电力的第二个供电线路进入数据中心的变压器。尽管我们没有得到Flexential或PGE的确认,但似乎接地故障是由PGE正在执行的影响第一条供电线路的非计划维护引起的,或者这只是一个非常不幸的巧合。
高压(12,470伏)电力线出现接地故障是非常糟糕的事情。电气系统旨在在发生故障时快速关闭以防止损坏。不幸的是,在这种情况下,保护措施也关闭了PDX-04的所有发电机。这意味着该设施的两个发电源 - 冗余公用事业线以及10个发电机 - 都处于离线状态。
幸运的是,除了发电机之外,PDX-04还配备了一组UPS电池。据说这些电池足以为设施供电约10分钟。这段时间被认为足以填补停电和发电机自动启动之间的空白。如果Flexential能够在10分钟内恢复发电机或公用事业供电,那么就不会出现中断。事实上,根据我们观察到的设备故障情况,只经过了4分钟,电池就开始失效了。而Flexential要花费的时间远远超过了10分钟才能恢复发电机。
Attempting to Restore Power
虽然我们还没有得到官方证实,但员工们告诉我们,导致发电机无法重新运行的原因有三个。首先,由于接地故障触发了电路,需要物理接触和手动重新启动。其次,Flexential的访问控制系统没有由备用电池供电,因此处于离线状态。第三,现场夜班没有包括经验丰富的运营或电气专家,夜班由保安和一个刚上班一周的单独技术人员组成。
在11:44至12:01的UTC期间,由于发电机没有完全重新启动,UPS电池耗尽了电力,数据中心的所有客户都失去了电力。在此期间,Flexential从未通知Cloudflare在该设施中存在任何问题。我们第一次被通知发生了数据中心问题是在11:44 UTC,当连接该设施与世界其他地方的两个路由器离线时。当我们不能直接或通过带外管理联系到路由器时,我们试图联系Flexential并派遣我们的本地团队前往该设施。我们从Flexential收到的第一条消息是在12:28 UTC,称他们遇到了问题。
我们目前在[PDX-04]遇到了一个电力问题,这个问题开始于大约0500AM PT [12:00 UTC]。工程师正在积极解决问题并恢复服务。我们将每30分钟或在更多信息可用时,向您通报进展以及预计的恢复时间。感谢您的耐心和理解。
Designing for Data Center Level Failure
尽管 PDX-04 的设计在建造前已通过了 Tier III 认证,并预计能够提供高可用性的 SLA,但我们考虑到了它有可能离线的可能性。即使是管理得非常好的设施也可能会出现问题。我们已经有所准备。在那种情况下,我们期望发生的是我们的分析系统会离线,日志会在边缘被排队并延迟,一些低优先级的服务也会暂时离线,直到它们可以在另一个设施中恢复。
该地区的其他两个数据中心将接管高可用性集群的责任,保持重要服务在线。通常情况下,这项工作顺利进行。不幸的是,我们发现一些本应在高可用性集群中运行的服务有依赖于仅在PDX-04中运行的服务。
特别是,用于处理日志和支持分析的两项关键服务——Kafka和ClickHouse——只在PDX-04中可用,但依赖于它们的服务正运行在高可用集群中。这些依赖关系不应该这么紧密,应该更优雅地进行故障处理,并且我们应该意识到这一点。
我们曾对我们的高可用性集群进行了测试,通过将其他两个数据中心设施全部离线进行测试。我们还测试了将PDX-04的高可用性部分离线。然而,我们从未全面测试过完全将整个PDX-04设施离线。因此,我们忽视了数据平面中某些依赖关系的重要性。
我们对于要求新产品以及相关数据库与高可用性集群整合的要求过于宽松。Cloudflare允许多个团队快速创新。因此,产品通常会采取不同的路径以达到其初稿。尽管随着时间的推移,我们的做法是将这些服务的后端迁移到我们的最佳实践中,但我们并没有正式要求在产品宣布普及(GA)之前完成此工作。那是一个错误,因为这意味着我们所拥有的冗余保护协议在不同的产品上工作不一致。
此外,我们的太多服务都依赖于核心设施的可用性。虽然这是许多软件服务创建的方式,但它并不发挥Cloudflare的优势。我们擅长分布式系统。在此次事件中,我们的全球网络继续按预期表现。虽然我们的某些产品和功能可以通过网络边缘进行配置和维护,而不需要核心设施,但今天失败的服务太多了,如果核心设施不可用。我们需要使用我们为所有客户提供的分布式系统产品为所有服务提供支持,这样即使我们的核心设施受到干扰,它们仍然可以大部分正常运行。
Disaster Recovery
在12:48协调世界时,Flexential成功重新启动了发电机,数据中心的部分区域恢复了电力。为了不给系统造成压力,在数据中心重新通电时,通常会逐步地逐个电路地重新启动。像家庭用的断路器一样,每个客户都由冗余断路器服务。当Flexential试图重新启动Cloudflare的电路时,发现断路器出现了故障。我们不知道断路器是由于接地故障或其他事件导致的电源涌现,或者之前就存在问题,在断电后才被发现。
Flexential开始更换故障跳闸器。这要求他们寻找新的跳闸器,因为坏的数量超过了他们在设施内手头所持有的数量。由于掉线的服务比我们预期的更多,并且Flexential无法告诉我们服务恢复的时间,因此我们在13:40 UTC决定切换到Cloudflare在欧洲的灾难恢复站点。幸运的是,我们只需要切换少量Cloudflare整体控制平面。我们大部分服务继续在两个活动核心数据中心的高可用性系统上运行。
我们于UTC时间13:43启用了灾难恢复站点上的首个服务。Cloudflare的灾难恢复站点为关键的控制平面服务提供了支持,以备灾害发生。虽然灾难恢复站点不支持我们的某些日志处理服务,但它被设计为支持我们控制平面的其余部分。
当我们在那里升级服务时,出现了一个雷鸣般的问题,API调用失败导致我们的服务不堪重负。我们实施了速率限制以控制请求量。在此期间,大多数产品的客户在通过我们的仪表板或API 进行修改时会看到间歇性错误。到17:57 UTC,已成功移动到灾难恢复站点的服务已经稳定,大多数客户不再直接受到影响。但是,有些系统仍需要手动配置(例如 Magic WAN),一些与日志处理和一些定制API相关的服务仍然无法使用,直到我们能够恢复PDX-04。
Some Products and Features Delayed Restart
少数产品没有被正确地配置在我们的灾难恢复站点上。这些产品往往是较新的产品,在这些产品上,我们尚未完全实施和测试灾难恢复程序。其中包括我们的流视频上传服务和一些其他服务。我们的团队同时展开了两条工作线路,以恢复这些服务:1)在我们的灾难恢复站点上重新实施它们;2)将它们迁移到我们的高可用集群。
Flexential 更换了我们失效的断路器,恢复了两个公用电源,并在22:48 UTC确认了清洁电源。我们的团队全力以赴,整天都在应急中工作,所以我做出了大多数人需要休息,并在第二天开始搬回 PDX-04 的决定。这个决定延迟了我们的完全恢复,但我相信这样做不太可能使我们犯下额外的错误。
11月3日凌晨,我们的团队开始恢复PDX-04的服务。首先要做的是物理启动我们的网络设备,然后启动数千台服务器并恢复它们的服务。由于我们认为在事故期间可能发生了多次电源循环,因此数据中心的服务状态是未知的。我们唯一安全的恢复过程是对整个设施进行完整的引导启动。
这需要手动处理,将我们的配置管理服务器联机以开始恢复设施。重建这些需要3小时。从那里开始,我们的团队能够引导重建驱动我们服务的其余服务器。每台服务器重建需要10分钟到2小时不等的时间。虽然我们能够在多台服务器上并行运行这个过程,但服务之间存在固有的依赖关系,需要按顺序重新联机一些服务。
截至2023年11月4日04:25 UTC,服务已完全恢复。对于大多数客户来说,由于我们还在我们的欧洲核心数据中心存储分析数据,因此在我们的仪表板和API的大多数分析数据中,您不应该看到任何数据丢失。但是,一些未在欧盟复制的数据集将有持久的间隙。对于使用我们的日志推送功能的客户,大部分事件的日志将未被处理,因此您未收到的任何内容将无法恢复。
Lessons and Remediation
我们有一些需要从Flexential解答的问题。但我们也必须意识到整个数据中心可能会失效。谷歌采取了一种流程,当出现重大事件或危机时,他们可以呼叫代码黄或代码红。在这些情况下,大部分或所有工程资源都会转移到解决手头的问题上。
我们过去没有这样的流程,但现在很明显我们需要实施自己的版本:橙色代码。我们将所有非关键的工程职能转向确保我们的控制平面具有高可靠性。作为其中的一部分,我们预计以下变化:
将所有服务的控制平面配置,从我们核心数据中心的依赖中解放出来,并在可能的情况下将其转移到由我们分布式网络首先提供动力的地方
即使我们所有核心数据中心都离线,也要确保在网络上运行的控制平面仍然能够正常工作
要求所有被指定为“普遍可用”的产品和功能必须依赖于高可用集群(如果它们依赖于我们的任何核心数据中心),而没有任何特定设施上的软件依赖关系
要求所有被指定为“普遍可用”的产品和功能都有可靠的灾难恢复计划,并经过测试
测试系统失败的爆炸半径,最小化受影响的服务数量
对所有数据中心功能实施更严格的混沌测试,包括完全拆除我们的每个核心数据中心设施
彻底审计所有核心数据中心,并制定重新审计计划以确保其符合我们的标准
日志和分析灾难恢复计划可以保证,在我们所有核心设施都发生故障的情况下,不会丢失任何日志
正如我之前所说的,我对这件事感到抱歉和尴尬,对我们的客户和团队造成了痛苦。我们有正确的系统和程序,能够承受甚至是在我们的数据中心供应商出现连锁的故障,但我们需要更加严格地执行和测试那些未知依赖的程序。这将得到我的全力关注,以及我们团队大部分的关注,直到本年度结束。而过去几天的痛苦将使我们变得更好。