カナリアデプロイとテスト:あらゆる規模で自信を持ってリリースする

Yunhao Jiao
カナリアデプロイとテスト:あらゆる規模で自信を持ってリリースする カバー

カナリアデプロイとは、新バージョンのソフトウェアを全ユーザーに展開する前に、ごく一部のユーザーへ段階的にロールアウトするリリース戦略です。カナリアグループで問題が見られなければ——エラーレートの増加も、パフォーマンスの低下も、ユーザーからの報告もなければ——ロールアウトを続行します。問題が発生した場合は、大多数のユーザーへの影響が生じる前にデプロイをロールバックします。

この名称は、炭鉱でカナリアを持ち込んで有毒ガスを検知するという慣行に由来しています——カナリアが早期警告シグナルを提供するのです。ソフトウェアにおける「カナリア」とは、リリースを安全に進めてよいかどうかの早期シグナルを提供する、最初の小規模なデプロイを指します。

カナリアデプロイが重要な理由

包括的なテストスイートを用意していても、本番環境の条件下でしか表れない障害があります。実際のユーザートラフィックパターン、本番データのボリューム、特定のユーザーデバイスの組み合わせ、テスト環境では再現できないネットワーク状態などがその例です。テスト環境が本番環境を完全に再現することはありません。

カナリアデプロイは、新バージョンが全ユーザーに届く前の最後の防衛ラインです。「このバージョンは実際の本番トラフィックで正しく動作するか?」という問いに答えるものです。

テストとの関係

カナリアデプロイとテストは、どちらかの代替ではなく、互いを補完するものです。テスト(自動E2Eテストを含む)はデプロイする自信を与え、カナリア戦略はテストで見逃した問題があった場合の影響範囲を限定します。

その関係性:

  1. デプロイ前のテストがバグの大半を検出する——TestSpriteの自動テストスイートはすべてのPRで実行され、テストが失敗するとマージをブロックする
  2. カナリアデプロイが残りの本番固有の問題を検出する
  3. 本番モニタリングが大規模化や時間経過によって初めて現れる問題を検出する

強力な自動テストを持つチームは、デプロイ前にほとんどのバグが検出済みであるという確信があるため、迅速なロールアウトスケジュールで自信を持ってカナリアをデプロイできます。自動テストを持たないチームは、各リリースへの確信が低いため、カナリアのロールアウト速度を非常に慎重に設定する必要があります。

カナリアデプロイの実践的な仕組み

トラフィックの分割

カナリアデプロイは、受信トラフィックを安定バージョンと新バージョンに分割します。分割は小さな割合(1〜5%)から始まり、信頼性が高まるにつれて徐々に増やしていきます。

主要なクラウドプラットフォームやCDNはトラフィック分割をサポートしています:

AWS:ALBの重み付きターゲットグループまたはRoute 53の重み付きルーティングを使用

Vercel:Edge ConfigおよびミドルウェアベースのA/Bルーティング

Cloudflare:Workersのトラフィック分割ロジック

Kubernetes:自動プログレッシブデリバリーのためのArgo RolloutsまたはFlagger

フィーチャーフラグ:LaunchDarkly、Split、またはカスタムフラグシステムでアプリケーションレベルのカナリアロジックを実装

自動ロールバックの基準

効果的なカナリアデプロイの鍵は自動ロールバックです——メトリクスがしきい値を超えた場合、人間の介入なしにデプロイが自動的にロールバックされます。しきい値には一般的に以下が含まれます:

  • エラーレート:カナリアグループのHTTP 5xxエラーレートがベースラインをX%以上超えた場合
  • レイテンシ:p95またはp99のレイテンシが安定バージョンと比較してY%以上増加した場合
  • ビジネスメトリクス:コンバージョン率、チェックアウト完了率、その他の主要メトリクスが大幅に低下した場合
  • カスタムシグナル:デプロイされた変更に関連するアプリケーション固有のヘルスシグナル

カナリアロールアウト中のモニタリング

効果的なカナリアデプロイメントには、バージョン別にメトリクスを分類できるモニタリングインフラが必要です。

  • デプロイメントバージョン別のエラー率
  • デプロイメントバージョン別のレイテンシパーセンタイル
  • デプロイメントバージョン別のビジネスKPI
  • デプロイメントバージョン別のカスタムアプリケーションメトリクス

バージョン別に分類されたメトリクスがなければ、カナリアデプロイメントは早期警告の役割を果たしません。問題がカナリア集団から発生しているのか、安定版集団から発生しているのかを判別できないためです。

カナリアデプロイメント自体のテスト

カナリアデプロイメントが提供する本番トラフィックの検証に加え、カナリアデプロイメントに対して実施すべき具体的なテストがあります。

カナリアバージョンに対するスモークテスト:実際のトラフィックをカナリアにルーティングする前に、スモークテストスイートを実行します。TestSpriteの本番モニタリングは、実際のトラフィックが到達する前に、カナリアデプロイメントのURLに対してクリティカルパステストを実行できます。

合成モニタリング:ロールアウト中、カナリアバージョンと安定版の両方に対して合成トランザクションを継続的に実行します。バージョン間の成功率を自動的に比較することで、早期シグナルを得ることができます。

互換性テスト:カナリアバージョンが安定版から開始されたリクエストを正しく処理できるか、またその逆も確認します。部分的なロールアウト期間中、データベーススキーマの変更、セッション形式、APIコントラクトが後方互換性を維持している必要があります。

データベースマイグレーションにおけるカナリアテスト

データベースマイグレーションは、カナリアデプロイメントにおいて最もリスクの高い側面です。テーブル構造を変更するマイグレーションは、ロールアウト期間中、古いアプリケーションバージョンと新しいアプリケーションバージョンの両方と同時に互換性を保つ必要があります。

安全なパターン:

  1. 拡張(Expand):既存の構造を維持しながら、新しいカラム/テーブルを追加するマイグレーションを実行する(非破壊的)
  2. カナリアのデプロイ:新しいコードが古い構造と新しい構造の両方に書き込む
  3. ロールアウト完了:すべてのトラフィックが新バージョンに移行
  4. 縮小(Contract):古い構造を削除するマイグレーションを実行する

各フェーズを明示的にテストする:古いコードと新しいコードが同一データベースに対して同時稼働している場合に、アプリケーションが正常に動作するかを確認する

カナリアデプロイメントを使用すべき場面

カナリアデプロイメントは運用上の複雑さを増大させます。特に有効なのは以下の場合です。

  • アプリケーションのトラフィックが十分に多く、5%のカナリアが統計的に意味のあるシグナルを提供できる場合(1日あたり数万人のアクティブユーザーが存在する場合)
  • バージョン別にメトリクスを分類できるモニタリングインフラが整っている場合
  • トラフィックを確実に分割できるデプロイメントインフラが整っている場合
  • ユーザーベースの大部分に影響を与える可能性のある変更をデプロイする場合

トラフィックの少ない初期段階のアプリケーションでは、カナリアデプロイメントの運用オーバーヘッドが正当化されない場合があります。強力な自動テスト(すべてのPRでTestSpriteを実行)は、小規模なデプロイメントに対して適切なレベルの信頼性を提供します。

TestSpriteでカナリアデプロイメント前の信頼性を高める →