GitHubの2026年8月障害から学ぶ、大規模サービスの可用性設計

クラウド

障害が示したのは「単一原因」ではなく、余力不足の連鎖

GitHubは2026年8月、GitHub Actions、Issues、Pull Requests、API、Copilotなど複数のサービスで障害が発生したことを報告しました。

個々の障害には異なるきっかけがありましたが、共通していたのは、平常時には動作していたシステムが、余力の少ない状態で小さな変化を受け、連鎖的に過負荷へ移行したことです。

この報告は、単にGitHubの運用上の問題を紹介するものではありません。クラウド上でマイクロサービスや非同期処理を運用するチームにとって、容量計画、リトライ、キュー、フェイルオーバー、外部依存の設計を見直す材料になります。

2026年8月に発生した主な障害

報告された障害の概要は次のとおりです。

  • 8月6日:GitHub Actionsの実行開始・完了遅延
    • 内部サービスのデプロイで一時的にPod数が減少し、残ったサイトへトラフィックが集中
    • サービスメッシュのサイドカーがCPU制限やメモリ不足に陥り、キャッシュ、DNS、APIへ障害が波及
    • 復旧時には、無効化済みジョブをランナーが再取得し続ける不具合がバックログを増幅
  • 8月17日:Issues、Pull Requests、API、認証などの広範な遅延・エラー
    • 1つのデータセンターでロードバランサーが限界を超過
    • サービスメッシュの同時実行数上限に達したにもかかわらず、十分にスケールしなかった
    • クライアント側のリトライ不具合が認証系エンドポイントへの負荷をさらに増幅
  • 8月20日:Copilot cloud agentのステータス更新遅延
    • 管理データベースの1リージョンで障害が発生
    • データベースへの書き込み遅延によってステータス更新処理がバックログ化
    • フェイルオーバーを妨げるストレージ設定も復旧を長引かせた
  • 8月26日:GitHub Actionsのジョブ開始遅延・失敗
    • 急増したイベントが、すでに高負荷だった共有データベースを限界まで圧迫
    • データベースのプライマリが飽和し、イベントからランナー割り当てまでの処理が停止
    • 手動で流入を絞るまで、キューが増え続けた
  • 8月27日:Copilotの特定モデルでリクエスト失敗
    • 外部モデルプロバイダー側の障害により、Kimi K3を利用するリクエストの多くが失敗
    • 他モデルや別経路は影響を受けなかった

教訓1:オートスケーリングは「ホスト」だけを見てはいけない

8月17日の障害では、ホストやサービス本体だけでなく、サービスメッシュのサイドカーが同時実行数の上限に達しました。しかし、その制約を考慮したスケーリングが行われず、ロードバランサーや認証経路へ負荷が波及しています。

オートスケーリングを導入していても、次のような下位レイヤーの制約が残っていれば、実質的な容量は増えません。

  • サービスメッシュの同時実行数
  • サイドカーのCPU・メモリ上限
  • ロードバランサーのネットワークフロー数
  • コネクションプールの上限
  • DNSやキャッシュの処理能力
  • データベースの接続数とクエリ実行時間

重要なのは、CPU使用率だけでスケール判定しないことです。実際のボトルネックが同時実行数や待ち行列にある場合、CPUが余っていてもリクエストは処理できません。

スケール判定の例

CPU使用率                 だけでなく
リクエスト待ち時間
同時実行数と上限の比率
キューの増加率
接続プール使用率
エラー率とタイムアウト率

また、デプロイ中に一時的に容量が減ることを前提に、ローリング更新の最低稼働数や余剰容量を設計する必要があります。平常時の最大負荷を処理できるだけでは不十分で、デプロイ、ノード障害、トラフィック偏りが重なった状態でも耐えられる余力が求められます。

教訓2:リトライは復旧機能にも、障害増幅器にもなる

8月17日の障害では、部分的な遅延に対してクライアントやゲートウェイがリトライし、認証系エンドポイントへの負荷が増幅しました。8月6日には、無効なジョブの再取得を繰り返すランナーが復旧を遅らせています。

リトライを実装する際は、単に回数を設定するだけでは不十分です。少なくとも次の点をサービス間で統一する必要があります。

  • 指数バックオフとジッターを使う
  • リトライ可能なエラーと不可能なエラーを区別する
  • リクエスト全体の期限を設定する
  • リトライ回数だけでなく、システム全体の予算を管理する
  • 同じ処理を安全に繰り返せるよう冪等性を持たせる
  • 依存先が過負荷のときはサーキットブレーカーで呼び出しを止める

特に危険なのは、サービスAが3回、サービスBが3回、サービスCが3回リトライする構成です。単純化すると、1つの失敗した処理が多数の下流リクエストを生みます。

障害時には、リトライを増やすよりも、新規流入を制御して既存処理を完了させる方が復旧しやすい場合があります。

教訓3:キューは「たまること」より「減らせること」を設計する

GitHub ActionsやCopilot cloud agentの障害では、処理そのものだけでなく、状態更新やジョブ開始のバックログが問題になりました。依存サービスの遅延によって処理速度が落ちると、入力を受け続ける限りキューは拡大します。

非同期処理では、次のメトリクスを監視対象に含めるべきです。

  • キューの長さ
  • キュー滞留時間
  • 到着率と処理率の差
  • oldest itemの経過時間
  • リトライ待ち件数
  • 無効化済み、期限切れ、重複メッセージの件数
  • ワーカーごとの処理成功率

さらに、障害時の復旧手順を平常時から検証しておく必要があります。処理能力を増やせば必ず復旧するとは限りません。下流のデータベースが限界に近い状態でワーカーだけ増やせば、再び依存先を圧迫します。

有効なのは、次のような段階的な復旧です。

  1. 新規流入を制限する
  2. 既存の有効な処理を優先する
  3. 無効なジョブや期限切れメッセージを除去する
  4. 下流サービスの状態を見ながらワーカー数を増やす
  5. バックログが減少していることを確認し、流入制限を徐々に解除する

教訓4:フェイルオーバーは「切り替えられる」だけでは足りない

8月20日のCopilot cloud agentでは、データベースのリージョン障害に対してフェイルオーバーを試みたものの、ストレージ設定の影響で切り替えに時間がかかりました。8月26日のActions障害でも、プライマリの切り替えだけでは負荷問題を完全には解消できませんでした。

フェイルオーバー設計では、次の項目を事前に検証する必要があります。

  • 切り替えの開始から完了までの実測時間
  • DNS、接続プール、キャッシュの追従時間
  • 切り替え先リージョンの容量
  • レプリカ遅延がある場合の挙動
  • 書き込み処理と読み取り処理の整合性
  • 切り替え後に元のリージョンへ戻す手順
  • フェイルオーバー自体が負荷を増やさないか

「自動フェイルオーバーがある」ことと、「障害時に短時間でサービスを維持できる」ことは同じではありません。実際の障害条件で、切り替え、接続の再確立、バックログの消化までを一連のシナリオとして訓練することが重要です。

教訓5:外部依存には、機能単位のフォールバックを用意する

8月27日のCopilot障害では、特定の外部モデルプロバイダーに依存するリクエストが失敗しました。一方、他モデルや自動選択の経路は影響を受けませんでした。

外部APIやモデルを利用するシステムでは、依存先が落ちたときにサービス全体を止めない設計が必要です。

  • 代替プロバイダーまたは代替モデルへ切り替える
  • 機能を縮退させ、結果の即時性や精度を一時的に下げる
  • 依存先ごとのタイムアウトとサーキットブレーカーを設ける
  • 依存先別に成功率、遅延、タイムアウトを監視する
  • 利用者が代替経路を選べるようにする
  • 障害時に自動切り替えした場合のコストやデータ取り扱いを定義する

フォールバックは「同じ機能を完全に提供する」必要はありません。重要なのは、依存先の障害をサービス全体の停止へ拡大させず、利用者に許容可能な縮退モードを提供することです。

GitHubが進める改善から読み取れること

GitHubは、8月の障害を受けて、Azureへの移行、データベースプライマリの移行、容量監視、リトライポリシー、コアサービスのレジリエンスを強化しています。

報告によれば、認証系のデータベースコホートを古い共有データベースから移行し、クエリの整理も実施しました。GitHub Actionsではジョブの33%を余剰容量へ移し、ピーク時のキャッシュCPU使用率を98%から80%へ低下させたとしています。これは短期的な封じ込め策であり、恒久的な容量分離やアーキテクチャ改善とは区別されています。

また、Pull Requestの監視では、マージ、レビュー、コメントの失敗を個別に測定するようになりました。読み取りが大量に成功しているために、書き込み経路の障害が見えなくなる問題への対策です。

この点は、監視設計における重要な示唆です。サービス全体の成功率だけでは、重要な操作の失敗を見逃します。読み取りと書き込み、同期処理と非同期処理、主要機能と依存機能を分けて、ユーザー影響を測定する必要があります。

自社システムで実施したいチェックリスト

今回の事例を、自社の設計レビューや障害訓練に落とし込むなら、次の項目が役立ちます。

  • デプロイ中にインスタンス数が減っても、サービスは容量不足にならないか
  • オートスケーリングはサイドカー、ロードバランサー、接続プールの制約を見ているか
  • リトライがサービス間で重複し、負荷を増幅していないか
  • 障害時に新規流入を自動で制限できるか
  • キューの滞留時間とバックログの減少率を監視しているか
  • 無効なジョブや期限切れメッセージを安全に破棄できるか
  • データベースのフェイルオーバーを実負荷に近い条件で検証したか
  • 切り替え先のリージョンやクラスタに十分な容量があるか
  • 外部サービスやモデルプロバイダーの代替経路があるか
  • 読み取り成功率が高くても、重要な書き込み操作の失敗を検知できるか
  • サポート問い合わせなど、テレメトリ以外の顧客影響シグナルも統合しているか

まとめ:機能追加より先に、容量と復旧経路を設計する

GitHubの8月の障害は、単独のバグだけで発生したものではありません。容量の余力不足、スケーリング対象の見落とし、リトライの増幅、バックログ処理の弱さ、フェイルオーバーの遅延、外部依存の集中が組み合わさり、影響を広げました。

大規模サービスの可用性は、正常系の性能だけでは決まりません。障害が起きたときに負荷を減らし、重要な処理を残し、依存先を切り離し、徐々に復旧できるかが本質です。

GitHubが示した「availability、capacity、features」の優先順位は、多くの開発チームにも当てはまります。新機能を増やす前に、デプロイ中の余力、リトライの上限、キューの排出、データベース切り替え、依存サービスのフォールバックを検証する。それが、障害を完全になくせない環境で、障害の影響を小さくするための現実的なアプローチです。

出典: GitHub Blog

タイトルとURLをコピーしました