AWS 2025年 DynamoDB の DNS の競合による us-east-1 の障害
攻撃ではない。DynamoDB の DNS を自動で更新する仕組みに、眠っていた競合があった。遅れた1つが古い計画を新しい計画の上に書き、別の1つの掃除がその古い計画を消し、地域の入口の名前から IP が全部消えた。自動化は直せない状態に陥り、人が直した。DynamoDB は約3時間で戻ったが、それに頼る EC2 の仕組みが戻る途中で詰まり、障害は14時間余り続いた。止める所は、書く時に版を比べること、使っている計画を消させないこと、空の記録を拒むこと、戻る時に仕事を絞ることにある。
要点
- DNS Planner が計画を作り、3つのアベイラビリティゾーンで独立に動く DNS Enactor が Route 53 に当てる。Enactor は当て始める前に一度だけ、自分の計画が前に当てた計画より新しいかを確かめていた[1]。
- 遅れた Enactor が、確かめの後に古くなった計画を地域の入口に書いた。新しい計画を当て終えた別の Enactor の掃除が、ずっと古いその計画を消し、入口の IP が全部消えた[1]。
- 使っていた計画が消えたため、どの Enactor も次の計画を当てられない状態になり、人の手が要った[1]。
- DynamoDB に頼る EC2 の物理の機械の管理が、戻る時に仕事の山で詰まり、新しいインスタンスの起動が10時36分まで失敗した。網の設定の遅れから NLB の健全性の確かめが揺れ、接続の誤りが14時09分まで続いた[1]。
- AWS は、自動化の停止のほか、NLB の容量を外す速さの制御、EC2 の回復の手順の試験、待ち行列の長さに応じた絞りを挙げた[1]。
何が起きたか
| 日時 米国太平洋夏時間 | 出来事 |
|---|---|
| 2025年10月19日 23時48分 | 地域の入口 dynamodb.us-east-1.amazonaws.com の DNS の記録が空になる。公開の入口から DynamoDB につなぐ全部の仕組みで、名前の解決が失敗する。社内の仕組みも同じ[1]。同時に、EC2 の物理の機械を管理する仕組みの定期の確かめが失敗し始める[1] |
| 10月20日 0時38分 | DynamoDB の DNS の状態が原因と突き止める[1] |
| 1時15分 | 一時の緩和で、一部の社内の仕組みが DynamoDB につながり、復旧に要る社内の道具が直る[1] |
| 2時25分 | DNS の情報を全部戻す。2時32分に、全部のグローバルテーブルの写しが追いつく[1] |
| 2時25分から40分 | 手元に残った DNS の記録が期限を迎え、利用者が入口を引けるようになる。DynamoDB の主な障害が終わる[1] |
| 2時25分から | EC2 の機械の管理が貸し出しの結び直しを始めるが、数が多く、結び終える前に時間切れになり、やり直しの仕事が積もって進めなくなる[1] |
| 4時14分 | 入ってくる仕事を絞り、管理の機械を選んで再起動する[1] |
| 5時28分 | 全部の物理の機械と結び直し、新しい起動が通り始める。網の設定を新しいインスタンスへ配る仕事の山が残る[1] |
| 5時30分 | 一部の NLB で接続の誤りが増え始める[1] |
| 6時21分 | 網の設定の配布が遅くなり始める[1] |
| 6時52分 | NLB の健全性の確かめの失敗の増加を監視が検知する[1] |
| 9時36分 | NLB の健全性の確かめによる自動の切り替えを止める。接続の誤りが解ける[1] |
| 10時36分 | 網の設定の配布の時間がふだんに戻り、新しいインスタンスの起動がふだんどおり動く[1] |
| 11時23分 | 絞りを緩め始める[1] |
| 13時50分 | EC2 の全部の API と起動がふだんどおりになる[1] |
| 14時09分 | NLB の自動の切り替えを戻す[1] |
| 14時20分 | 障害が終わる[1] |
| 10月21日 4時05分 | 入れ替えの仕事で止まっていた Redshift の群れを戻し終える[1] |
- 動いていた EC2 のインスタンスは、障害の間も影響を受けなかった[1]。止まったのは、新しい起動、状態の変更、それらに頼る仕組みだった。
- 影響を受けた利用者の数や損害の額は、AWS の要約には無い。
起きた仕組み
| 部品 | 役割と、この件で |
|---|---|
| DNS の記録 | DynamoDB は、地域ごとに大きなロードバランサの群れを動かすため、数十万の DNS の記録を持つ。公開の地域の入口のほか、FIPS 用、IPv6 用、アカウントごとの入口も自動化が保つ[1]。 |
| DNS Planner | ロードバランサの健全さと容量を見て、入口ごとのロードバランサと重みの組を、定期に新しい計画として作る。IPv6 の入口と公開の地域の入口で容量を分け合うため、計画は地域で1つにしている[1]。 |
| DNS Enactor | どんな時でも復旧に使えるよう、依存を最小にして作られた。3つのアベイラビリティゾーンで独立に動き、Route 53 のトランザクションで、今の計画を新しい計画に入れ替える。当て始める前に一度だけ、自分の計画が前に当てた計画より新しいかを確かめる。入口ごとに、ほかの Enactor の更新に阻まれれば再試行する[1]。 |
| 競合 | 1つの Enactor が、いくつかの入口の再試行でひどく遅れた。その間に Planner は新しい計画を何世代も作り、別の Enactor が新しい計画を全部の入口に素早く当てた。当て終えた Enactor の掃除が、当てた計画よりずっと古い計画を消す。ちょうどその時、遅れた Enactor が古い計画を地域の入口に書き、新しい計画を上書きした。始めの確かめは古くなっており、止めなかった[1]。 |
| 空の記録 | 掃除が、何世代も古いその計画を消した。使っていた計画が消えたため、地域の入口の IP が全部すぐに消え、どの Enactor も以後の計画を当てられない食い違った状態が残った。人が直すまで戻らなかった[1]。 |
確かめた時と書いた時の差
版の確かめと書き込みが別の時にあり、間に何が起きても書き込みは通った。CWE-367 の、確かめた時と使った時の差の競合に当たる[2]。Route 53 のトランザクションは、1つの入口を一貫した計画で更新することを保つが[1]、どの計画が新しいかまでは見ていなかった。掃除は、自分が当てた計画との世代の差だけで消す計画を選び、ほかの誰かが今それを使っているかを見ていなかった[1]。どちらか1つの守りがあれば、入口は空にならなかった。
広がって長引いた道
| 仕組み | 何があったか |
|---|---|
| EC2 の機械の管理 | DropletWorkflow Manager は、EC2 を載せる物理の機械ごとに貸し出しを持ち、数分ごとに確かめる。この確かめは DynamoDB に頼っており、障害の間に貸し出しが少しずつ切れた。貸し出しの無い機械は新しい起動の候補にならず、API は容量不足を返した[1]。 |
| 戻る時の詰まり | DynamoDB が戻ると結び直しを始めたが、機械の数が多く、結び終える前に時間切れになり、やり直しの仕事が積もった。AWS はこれを、進めなくなった混雑による崩壊の状態と書き、確立した復旧の手順が無かったとする[1]。 |
| 網の設定 | Network Manager は、新しいインスタンスに網の設定を配る。遅れていた分の山を抱え、起動できても通信できないインスタンスが出た[1]。 |
| NLB | 健全性の確かめが、網の設定が届く前の新しいインスタンスを確かめて失敗し、成功と失敗を繰り返した。そのたびに DNS から外して戻し、確かめの仕組み自体も重くなり、ゾーンの自動の切り替えで容量が外れた[1]。 |
| 地域の外 | us-east-1 では、IAM の利用者でのコンソールへのログインが失敗した。地域の外でも、root の資格情報と signin.aws.amazon.com を使う連携のログインが失敗した。Redshift は、利用者のグループを us-east-1 の IAM の API で引く不具合のため、全地域で IAM の利用者の問い合わせが動かなかった[1]。 |
| グローバルテーブル | DynamoDB のグローバルテーブルを使う利用者は、ほかの地域の写しにつなげて読み書きできた。us-east-1 との複製は長く遅れた[1]。 |
どこで止められたか
| 止める所 | この件で | AWS の手当て |
|---|---|---|
| 書く時に版を比べる | 版の確かめは当て始める前の一度だけで、書いた時には古くなっていた[1] | 自動化を再び動かす前に競合を直し、誤った計画を当てない守りを足す[1] |
| 使っている計画を消させない | 掃除は世代の差だけで消し、遅れた Enactor が書いたばかりの計画を消した[1] | 同上。要約は個々の直し方を書いていない |
| 空の記録を拒む | 地域の入口の IP が全部消えても、それを止める段が無かった[1] | 同上 |
| 食い違いから自ら戻れる | 使っていた計画が消えた状態から、どの Enactor も先へ進めず、人の手が要った[1] | DynamoDB の DNS Planner と DNS Enactor の自動化を世界中で止めた[1] |
| 戻る時に仕事を絞る | 機械の管理の結び直しが詰まり、復旧の手順が無かった。NLB は揺れる確かめで容量を外した[1] | EC2 の回復の流れを試す試験を足す。待ち行列の長さで受け付けを絞る。健全性の確かめでゾーンを切り替える時、1つの NLB が外せる容量を限る[1] |
| 1つの地域に隠れて頼らない | グローバルテーブルの利用者は、ほかの地域の写しで読み書きを続けられた。Redshift と一部のログインは、地域の外でも us-east-1 に頼っていた[1] | 同じ型の事象の影響を避ける道と、復旧の時間を縮める道を、全サービスで探すとした[1] |
1か2があれば、入口は空にならなかった。3は、記録を空にする操作が書き込みでも削除でも、最後に止める段になる。4は、空になった後の時間を決めた。5と6は、DNS が戻った後の11時間余りを決めた。この件で長かったのは、原因の DNS よりも、戻る時の詰まりの方である。
守り方
根本の直し方
- 複数の書き手がいる状態は、書く時に版を比べる。確かめと書き込みを分けず、条件付きの書き込みや、比べて入れ替える操作で、今の版より古い物を拒む。
- 掃除は、誰も参照していない物だけを消す。今当たっている計画は、世代がどれほど古く見えても消さない。
- 結果の形に下限を置く。DNS の名前の IP が0件になる、前の版から急に減る、のような変更は当てずに止め、人に知らせる。
- 自動化は、自分が食い違った状態に陥っても、最新の正しい計画を当て直して戻れるようにする。戻れない状態は、試験の中で意図して作って確かめる。
悪い例と直した例。架空の DNS の計画を当てる自動化。名前は example.com、IP は説明用の範囲
# 悪い例 始めに一度だけ比べ、あとは無条件に書く
if plan.gen > store.applied_gen("api.example.com"):
slow_work() # この間に他の書き手が進む
store.put("api.example.com", plan.records)
# 直した例 書く時に比べ、空の記録を拒む
if len(plan.records) == 0 or len(plan.records) < 0.5 * current_count:
alert("plan rejected: too few records"); return
ok = store.put_if("api.example.com", plan.records,
gen=plan.gen, only_if_applied_gen_lt=plan.gen)
if not ok:
return # もっと新しい計画が当たっている
# 掃除 当たっている計画は消さない
for p in store.plans_older_than(keep_gen):
if not store.is_referenced(p.id):
store.delete(p.id)
当てる前と後の名前の解決。架空の入口
$ dig +short api.example.com A
192.0.2.10
192.0.2.11
198.51.100.20
# 計画が消された後
$ dig +short api.example.com A
# 何も返らない。利用者はつなぐ先を失う
- DNS の記録が空になると、手元に残った記録が期限を迎えた順に、利用者がつなげなくなる。この件で利用者が戻ったのも、DNS を戻した後、手元の記録が期限を迎えてからだった[1]。TTL は、壊れた時に広がる速さと、直した時に戻る速さの両方を決める。
- 確かめた時と使った時の差の競合は、テストで滅多に出ない。この件も、まれな遅れが重なった時だけに起きた[1]。書き手を増やした時は、遅れた書き手が古い物を書く場面を、遅れを注入して試す。
緩和の策
- 戻る時の仕事の山を、受け付けの段で絞る。待ち行列の長さに応じて受け付けを減らせば、時間切れのやり直しが積もる崩壊を避けられる[1]。再試行の待ちには、ゆらぎを入れた指数的な待ちを使う[3]。
- 健全性の確かめで容量を外す仕組みには、一度に外せる量の上限を置く。確かめる側が揺れた時に、全部を外さない[1]。
- 利用する側は、DynamoDB のグローバルテーブルのような複数の地域の写しを持てば、1つの地域の入口が引けなくても読み書きを続けられる[1]。
- 自分の仕組みが、どの地域の、どの共通の仕組みに頼っているかを棚卸しする。この件では、ほかの地域の Redshift の問い合わせとコンソールのログインが us-east-1 に頼っていた[1]。
- 確かめと書き込みが分かれた差分は、AIが書いたコードでもよく出る。並行に動く書き手がいる所の差分は、書く時に比べているかを読む。読み方は AIの出力を確かめる にある。競合の設計は A06 安全性を欠いた設計 にもある。
参照
- Summary of the Amazon DynamoDB Service Disruption in the Northern Virginia US-EAST-1 Region AWS、2025年10月。頁に公表の日付の記載は無い
- CWE-367 Time-of-check Time-of-use TOCTOU Race Condition MITRE
- Addressing Cascading Failures Site Reliability Engineering、Google