デプロイ戦略の図:ローリング、ブルーグリーン、カナリア

ローリングアップデート、ブルーグリーン、カナリアリリースを図で比較。トラフィックの移り方、ロールバック、コスト、自動カナリア分析の判断方法を解説。

· 創業者・開発者

公開日:

デプロイ戦略の図:ローリング、ブルーグリーン、カナリア

障害の多くはデプロイから始まります。コードはレビューもテストも通ったのに、本物のトラフィック、本物のデータ、本物の依存先に出会った途端に問題が起きます。デプロイ戦略は、トラフィックのどれだけが一度に新しいバージョンに触れるか、問題にどれだけ早く気づけるか、どれだけ早く元に戻せるかを決めます。

この記事では、多くのチームが選択肢にする 3 つの戦略、ローリングアップデート、ブルーグリーン、カナリアリリースを比較します。それぞれでトラフィックがどう移り、ロールバックがどうなるかを示し、最後に、続行するかロールバックするかの判断を自動化したカナリアリリースの図を紹介します。

ローリングアップデート

旧バージョンのインスタンスを、少しずつ新バージョンに置き換えます。Kubernetes の Deployment はデフォルトでこれを行います。RollingUpdate 戦略 では、maxSurge と maxUnavailable がロールアウト中に許される追加の Pod 数と不足する Pod 数を決め、どちらもデフォルトは 25% です。

  • トラフィック: ロールアウト中は、両方のバージョンがそれぞれの Pod 数に応じた割合で同時にリクエストを処理します。
  • ロールバック: 旧バージョンへのもう一度のローリングアップデートです。秒単位ではなく分単位です。
  • コスト: ほとんど追加なし。多くてもサージ分の容量です。
  • リスク: どのユーザーも早い段階で新バージョンに当たる可能性があり、自動のゲートは readiness probe だけです。起動は問題なくても負荷がかかると失敗するバージョンは、最後まで展開されてしまいます。

ローリングアップデートは、リスクの低い変更や、テストとプローブが整った社内サービスにとって妥当なデフォルトです。readiness probe には、プロセスが起動しているかだけでなく、サービスが動くのに必要なものを確認させましょう。そうしないと、ロールアウトは健全な Pod を壊れた Pod に平然と置き換えていきます。

ブルーグリーン

完全な環境を 2 つ動かします。ブルーが本番を処理し、グリーンには新しいバージョンを入れてその場でテストします。その後、ロードバランサーか DNS がすべてのトラフィックを一度にブルーからグリーンへ切り替えます。Martin Fowler による ブルーグリーンデプロイの説明 が古典的な参考資料です。

  • トラフィック: すべてブルー、その後すべてグリーン。両方に流れることはなく、あっても短時間です。
  • ロールバック: まだ動いているブルーに戻すだけです。秒単位です。
  • コスト: 両方が動いている間は 2 倍の容量が必要です。
  • リスク: 切り替えでユーザーの 100% が一度に移るので、本物のトラフィックでしか現れない問題は全員に影響します。データベースは共有なので、スキーマの変更は両方のバージョンで動く必要があります。

カナリア

本物のトラフィックのごく一部、たとえば 5% を新バージョンに送り、安定版と比較し、問題なければ段階的に割合を広げます。名前は炭鉱のカナリアに由来します。Fowler のサイトの カナリアリリースの記事 を参照してください。

  • トラフィック: 重み、ヘッダー、またはユーザーセグメントで分割します。
  • ロールバック: カナリアの重みをゼロにします。秒単位で済み、影響を受けたユーザーも数パーセントだけです。
  • コスト: 追加の Pod が少し。加えて、トラフィック分割と分析のためのツールが必要です。
  • リスク: 正しいメトリクスを見ていれば、3 つの中で最も低くなります。誰も見ていないカナリアは、遅いローリングアップデートにすぎません。

並べて比較

ローリング ブルーグリーン カナリア
不具合のあるバージョンに触れるユーザー 徐々に、最大で全員 全員、一度に ごく一部
ロールバック時間 数分 数秒 数秒
追加の容量 サージ分のみ 切り替え中は 100% Pod 数個
トラフィック分割の必要性 なし 切り替えスイッチ 重み付きルーティング
データベースの変更 後方互換 後方互換 後方互換

最後の行がどれも同じなのには理由があります。どの戦略でも、ある時点で 2 つのバージョンのコードが同じデータベースに出会うからです。expand-and-contract 方式のマイグレーションを使いましょう。まず新しい列やテーブルを追加し、両方の形で動くコードをデプロイし、古い形は後のリリースで削除します。

カナリアの前のシャドートラフィック

カナリアの前に 1 段階加えるチームもあります。本番リクエストの一部を新バージョンにコピーし、そのレスポンスは捨てるのです。Envoy や Istio はこの方法でトラフィックをミラーリングできます。ユーザーにまったく影響を与えずにクラッシュやレイテンシーの悪化を見つけられますが、使えるのは読み取りと冪等なリクエストだけです。ミラーリングされた書き込みは、メール、決済、在庫の変更といった副作用を繰り返します。書き込みはミラーから外すか、シャドーをサンドボックス化した依存先に向けましょう。

カナリアの判断を自動化する

カナリアの価値は比較にあり、人間は 1 時間もダッシュボードを見続けるのが苦手です。Argo Rollouts や Flagger などのツールは、Kubernetes 上でこれを自動化します。トラフィックを段階的に移し、各段階の間にメトリクスプロバイダーに問い合わせ、あなたが定義したしきい値に基づいて昇格または中止を決めます。

良い分析メトリクスは少数で、ユーザーに近いものです。

  • カナリアのエラー率(5xx レスポンス)を安定版と比較したもの。
  • p99 のような高いパーセンタイルでのレイテンシー。
  • 可能なら業務上のシグナルを 1 つ。たとえば 1 分あたりの決済完了数です。

カナリアは固定の数値ではなく安定版と比較します。そうすれば、依存先の調子が悪い夜でも、すべてのリリースが失敗することはありません。

アーキテクチャ図

CI がイメージ v2 をロールアウトコントローラーに渡します。Ingress はトラフィックの 95% を安定版の v1 に、5% をカナリアの v2 に送り、両方がメトリクスに報告し、メトリクスがコントローラーに入力されます。判断ノードでカナリアを確認し、はいなら 25、50、100% へ進み、いいえなら中止してすべてのトラフィックを v1 に戻します。

11 個のコンポーネント · 11 個の接続

Archboard で開く
ダイアグラムの内容
  • CI pipeline
  • Rollout controller
  • Users
  • Ingress
  • Stable v1
  • Canary v2
  • Metrics
  • Canary within thresholds?
  • Next step: 25, 50, 100 percent
  • Abort: all traffic to v1
  • image v2
  • 95%
  • 5%
  • error rate, p99 latency
  • yes
  • no
  • set weights
Kubernetes 上のカナリアリリース。Ingress がトラフィックの 5% を新しいバージョンに送り、ロールアウトコントローラーがそのエラー率とレイテンシーを安定版と比較して、段階的に昇格させるか、すべてのトラフィックを v1 に戻します。

図の読み方は次のとおりです。

  • 上、トラフィックの経路: ユーザーは Ingress に到達し、Ingress はリクエストの 95% を安定版の ReplicaSet に、5% をカナリアに送ります。両方がメトリクスに報告します。
  • 下、制御ループ: CI が新しいイメージをロールアウトコントローラーに渡します。コントローラーは Ingress の重みを設定し(破線のエッジ)、両バージョンのエラー率と p99 レイテンシーを読み取って判断します。
  • 判断: しきい値の範囲内なら次の段階へ進み、範囲外なら中止してすべてのトラフィックを v1 に戻します。
  • Markdown ブロック には段階と中止のルールを並べています。これは各サービスのロールアウト設定のレビューに含めるべき内容です。

フィーチャーフラグは 4 つ目の戦略

デプロイ戦略は、どのサーバーが新しいコードを実行するかを制御します。フィーチャーフラグは、デプロイとは独立に、どのユーザーが新しい振る舞いを目にするかを制御します。頻繁にリリースするチームは両方を組み合わせます。ローリングアップデートかカナリアでデプロイし、リスクのある機能はフラグの裏に置いて、フラグを段階的にオンにします。何も再デプロイしなくて済むので、フラグのほうが速いロールバック手段です。

デプロイの図に描くべきこと

  • エッジ上のトラフィックの割合。 ロールアウト中に変わるので、最初の段階を示します。
  • 誰が重みを変えるか。 コントローラー、パイプライン、または人です。
  • 中止の基準。 「調子が悪そうなら」ではなく数値で書きます。
  • データベース: スキーマ変更は expand-and-contract で行うことを書き添えます。

これより前のビルドとテストの段階は CI/CD パイプラインの図 で、クラスターについては Kubernetes のアーキテクチャ図 で、メトリクスの出どころは オブザーバビリティのアーキテクチャ図 で扱っています。

Archboard で作る

  1. Google または GitHub でサインインし、図を作成します。
  2. ユーザー用に 人物 を追加し、Kubernetes パックから Ingress を 1 つと、安定版とカナリア用に ReplicaSet ノードを 2 つ追加します。
  3. DevOps パックから メトリクス と パイプライン を、ロールアウトコントローラー用に C4 モデルパックから コンテナ を追加します。
  4. 昇格と中止のために、フローチャートパックから 判断、処理、開始 / 終了 を追加します。
  5. Ingress のエッジにトラフィックの重みをラベルとして付け、重みの変更を破線のエッジで描き、段階を書いた基本パックの Markdown ブロックを追加します。

この例で使うダイアグラムノードは 11 個で、Free プランの範囲に収まります。

よくある質問

最適なデプロイ戦略はどれですか? リスクとツール次第です。ローリングアップデートはリスクの低い変更の大半に、カナリアは不具合のあるリリースのコストが高いユーザー向けサービスに、ブルーグリーンは瞬時に全体を切り替える必要があり、2 倍の容量をまかなえるシステムに向いています。

ブルーグリーンとカナリアの違いは何ですか? ブルーグリーンはすべてのトラフィックを一度に切り替え、即座にロールバックできるよう古い環境を残しておきます。カナリアはまずトラフィックのごく一部を移し、新バージョンが問題ないと確認できてから割合を広げます。

デプロイ中のデータベースマイグレーションはどう扱えばいいですか? すべてのスキーマ変更を後方互換にします。まず拡張し、両方の形で動くコードをデプロイし、後のリリースで縮小します。

カナリア分析ではどのメトリクスを使うべきですか? 安定版と比較したエラー率と高パーセンタイルのレイテンシー、それに素早く測れるなら業務メトリクスを 1 つ加えます。

フィーチャーフラグはデプロイ戦略ですか? リリース戦略です。機能をオンにすることをコードのデプロイから切り離すもので、3 つのデプロイ戦略のどれとも組み合わせやすいものです。

無料で始める — 1 シート、クレジットカード不要。

関連記事

← ブログに戻る

1分でキャンバスを開く

Google または GitHub でサインイン。1シートは無料で、チームが加わったらアップグレード。