ToB 巨头 Cloudflare 3.21 故障复盘,吃他人堑长自己智
2025 年 3 月 21 日 ,包括 R2 对象存储 在内的多项 Cloudflare 服务经历了持续 1 小时 7 分钟(UTC 时间 21:38 开始,22:45 结束)的错误率升高情况。在事件发生期间,全球范围内 R2 的 100% 写入操作失败,大约 35% 的读取操作失败。尽管该事件是从 R2 开始的,但它也影响了其他 Cloudflare 服务,包括Cache Reserve、Images、Log Delivery、Stream 和 Vectorize。
在为 R2 Gateway 服务(R2 的 API 前端)轮换用于验证存储基础设施的凭据时,R2 工程团队无意中将新凭据(ID 和密钥对)部署到了服务的开发实例而非生产环境。当旧凭据从我们的存储基础设施中删除时(作为密钥轮换过程的一部分),生产 R2 Gateway 服务无法访问新凭据。这最终导致 R2 的 Gateway 服务无法与我们的存储后端进行身份验证。本事件中没有发生数据丢失或损坏:任何返回成功 HTTP 状态代码的进行中上传或修改操作均已被持久化保存。
一旦确定了根本原因并意识到我们未能将新凭据部署到生产环境的 R2 Gateway 服务,我们立即部署了更新凭据,服务可用性随即恢复。
本事件发生是由于人为错误,而持续时间过长是因为我们对 Gateway Worker 用于验证存储基础设施的凭据缺乏适当的可见性。
对此事件及其给您或您的用户造成的中断,我们深表歉意。我们以高标准要求自己,这样的事件是不可接受的。本文详细说明了此次事件的影响、发生的经过和时间,以及我们为确保此类故障(及类似故障)不再发生而正在采取的措施。
主要事件时段为 21:38 UTC 到 22:45 UTC 之间。
下表详细说明了 R2 和依赖于 R2 或与 R2 交互的 Cloudflare 服务受到的具体影响:
* 仅涉及元数据的操作(如,头部和列表操作)不受影响。 | |
对于启用了 Cache Reserve 的站点,面向用户的资源请求没有发生失败,因为缓存未命中时会故障转移到源站。 | |
Stream Live 在主要事件期间宕机,因为它依赖于对象写入。 | |
注:我们后来发现这两个Wrangler 命令都无意中省略了 --env 参数。这导致凭据被部署到分配给默认环境的 Worker,而不是分配给生产环境的 Worker。 | |
注意:这是一个错误的 Worker,本应显式指定为生产环境。但此时,我们错误地认为已在正确的生产 Worker 上更新了凭据。 | |
R2 可用性指标开始显示出服务性能下降迹象。对 R2 可用性指标的影响是渐进的,不会立即显现出来,因为此前的凭据删除向存储基础设施的传播存在延迟。 | |
R2 工程团队开始查看运营仪表板和日志,以了解影响。 | |
鉴于可用性指标的逐步下降,R2 工程团队怀疑存储基础设施中新凭据的传播存在潜在倒退。 | |
继续监控运营仪表板和日志。 | |
在 deploy 和 secret put 命令中仍然省略了 Environment 参数,因此本次部署仍然指向错误的非生产 Worker。 | |
R2 工程团队通过审查生产 Worker 发布历史记录,发现凭据被部署到非生产 Worker。 | |
将凭据部署到正确的生产 Worker。 R2 可用性恢复。 | |
R2 的架构主要由三部分组成:R2 生产 Gateway Worker(处理来自 S3 API、REST API、Workers API 的请求)、元数据服务和存储基础设施(存储加密的对象数据)。
R2 Gateway Worker 使用凭据 (ID 和密钥对)为我们的分布式存储基础设施进行安全的身份验证。作为最佳安全预防实践,我们会定期轮换这些凭据。
我们的密钥轮换流程涉及以下主要步骤:
为我们的存储基础设施创建一组新的凭据(ID 和密钥对)。在此阶段,旧凭据被保留,以避免在凭据切换期间出现停机。
使用
wrangler secret put命令设置 R2 生产 Gateway Worker 的新凭据密钥。使用
wrangler deploy命令将新的更新凭据 ID 设置为 R2 生产 Gateway Worker 中的环境变量。此时,Gateway Worker 开始使用新的存储凭据。从我们的存储基础设施中移除以前的凭据,以完成凭据轮换过程。
监视运行仪表板和日志以验证切换。
R2 工程团队使用Workers 环境来分隔 R2 Gateway Worker 的生产和开发环境。每个环境都使用单独的环境变量和密钥定义一个单独的隔离 Cloudflare Worker。
关键是,如果不包含 --env 命令行参数,wrangler secret put 和 wrangler deploy 命令都默认指向默认环境。在本例中,由于人为错误,我们无意中忽略了 --env 参数,并将新的存储凭据部署到了错误的 Worker(即 默认环境,而不是生产)。要将存储凭据正确部署到生产 R2 Gateway Worker,我们需要指定 --env production 。
我们在上述第 4 步中执行从存储基础设施中删除旧凭据的操作,导致身份验证错误,因为 R2 Gateway 生产 Worker 仍然拥有旧凭据。这就是最终导致可用性下降的原因。
R2 可用性指标的下降是渐进的,并没有立即显现出来,因为将上一个凭据删除传播到存储基础设施时存在延迟。这是导致我们首次发现问题推迟的原因。在更新旧凭据后,我们不应依赖可用性指标,而是应该显式验证 R2Gateway 服务使用哪个令牌来对 R2 的存储基础设施进行身份验证。
总体而言,由于位于存储前的中间缓存及其继续为请求提供服务,对读取可用性的影响显著降低。
在确定根本原因之后,我们通过将新凭据部署到生产 R2 Gateway Worker 来快速解决事件。这导致 R2 可用性立即恢复。
本事件发生是由于人为错误,而持续时间过长是因为我们对 Gateway Worker 用于验证存储基础设施的凭据缺乏适当的可见性。
我们已立即采取措施防止这一故障(及其他类似故障)再次发生:
添加了日志记录标记,其中包含 R2 Gateway Worker 用于与我们的存储基础设施进行身份认证的凭据 ID 后缀。通过此变更,我们可以显式确认正在使用的凭证。
与上述步骤相关,我们的内部流程现在要求在删除先前的令牌之前,显式确认新令牌 ID 的后缀与我们存储基础设施的日志匹配。
要求密钥轮换通过我们的热修补发布工具进行,而不是依赖可能引入人为错误的手动 wrangler 命令输入。我们的热修补发布部署工具显式强制使用环境配置并包含其他安全检查。
虽然按照隐含标准,这个过程需要至少两个人来验证将进行的更改,但我们已经更新了相关的 SOP(标准操作程序) 以显式包含这一点。
进行中的工作:扩展我们现有的闭环健康检查系统(负责监控端点以测试新密钥),通过我们的告警平台自动报告其状态,并确保在发布 Gateway Worker 之前完成全球传播。
进行中的工作:加快对分布式存储端点未来问题的排查,我们正在更新可观测性平台,加入绕过缓存的上游成功率视图,以更清晰地指示任何原因导致的请求服务问题。
上述列表并非详尽无遗:在我们处理上述项目的过程中,除常规工作外,我们很可能会发现需要对系统、控制和流程进行其他改进,并将应用以提升 R2 的韧性。我们相信这些变化将防止此类故障及相关的凭据轮换故障模式再次发生。我们再次为此事件真诚道歉,并对由此给您或您的用户造成的中断深表歉意。
原文链接:https://blog.cloudflare.com/zh-cn/cloudflare-incident-march-21-2025/- END -
IT168与ITPUB技术社区强强联手,收集数百款主流数据库产品,重磅推出“数据库全景图”,旨在打造一款集知识普及、产品对比、选型参考于一体的综合性资源平台。“数据库全景图(11月版)”可扫描上方左侧二维码回复关键词获取,识别右侧二维码直达“数据库全景图”链接(右上角浏览器打开获取更好体验)。