2023-01-25 DNS 中断事件

2023 年 2 月 8 日 · Jan David Nose 代表 Rust 基础设施团队

在 2023 年 1 月 25 日星期三 世界协调时 09:15,我们部署了 crates.io 生产基础设施的变更。在部署过程中,`static.crates.io` 的 DNS 记录估计有 10-15 分钟无法解析。在此期间,用户遭遇构建失败,因为 crates 无法下载。世界协调时 9:30 左右,DNS 记录开始重新传播,到世界协调时 9:40,流量已恢复正常水平。

中断事件的根本原因

Rust 基础设施使用 Terraform 管理,Terraform 是一种配置和提供基础设施即代码 (infrastructure-as-code) 的工具。基础设施团队 最近对该配置进行了更改,以分离 crates.io 的 `staging`(预生产/测试)和 `production`(生产)环境,从而使两者可以独立部署。

此功能用于在 `staging` 环境中开发和测试用于 `static.crates.io` 的第二个内容分发网络 (CDN) 的基础设施。配置准备就绪后,我们安排并宣布了 1 月 25 日的上线。

部署到 `production` 包含了两个在 `staging` 环境中单独开发、部署和测试过的变更:当前内容分发网络的新 TLS 证书和更新的 DNS 记录。

当我们将此配置部署到 `production` 环境时,Terraform 首先移除了当前的证书和 DNS 记录。然后它开始颁发新证书,这花费了大约 10 分钟。在此期间,`static.crates.io` 没有 DNS 记录,用户遭遇构建失败。在新证书配置完成后,Terraform 重新创建了 DNS 记录。

解决方案

中断事件在 Terraform 完成部署并为 `static.crates.io` 创建新的 DNS 记录后自行解决。对于一些用户来说,由于其 DNS 服务器中的缓存,中断持续了更长几分钟。

事后分析

通过单独部署 TLS 证书和 DNS 记录的变更,本可以避免这次中断。我们已经确定了两个导致这种情况发生的原因,以及我们从中吸取的教训。

这是我们首次使用围绕环境的新工具来部署变更到 `production`。它的一个特性是 `production` 环境锁定到特定的 Git commit(提交)。过去部署时,我们会将其设置为 `master` 分支的最新提交。这次也是如此,结果是部署同时应用了多个变更。

从另一个角度来看,`production` 和 `staging` 随着时间的推移分歧过大,因为我们在将变更合并到主分支时没有及时部署。如果我们在变更合并到主分支时就进行了部署,我们就能够隔离 DNS 变更。但考虑到 crates.io 对 Rust 生态系统的重要性,我们在未事先向社区宣布变更的情况下,对于多次部署犹豫不决。

我们从本次事件中吸取的教训如下

  • 我们需要记录将变更部署到生产环境的流程,特别是如何选择 Git 提交以及如何审查变更集。定义一个流程将使我们能够随着时间的推移进行迭代和改进,并在未来避免同样的问题。
  • 在 `staging` 环境中独立开发和测试过的变更,应单独按顺序部署到 `production`。我们需要将此添加到文档中。
  • 当我们将变更合并到主分支时,需要确保它们也被部署到 `production` 环境。这避免了 Git 中的配置与已部署的配置之间的偏差。