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

カナリアデプロイとは、新バージョンのソフトウェアを全ユーザーに展開する前に、少数のユーザーへ段階的にリリースするデプロイ戦略です。カナリアグループで問題が見られない場合(エラー率の上昇なし、パフォーマンスの低下なし、ユーザーからの報告なし)、ロールアウトを継続します。問題が発生した場合は、大多数のユーザーへの影響が及ぶ前にデプロイをロールバックします。
この名称は、炭鉱でカナリアを使って有毒ガスを検知するという採掘の慣行に由来しています。カナリアは早期警告シグナルを提供します。ソフトウェアにおける「カナリア」とは、リリースを安全に進めてよいかどうかの早期シグナルを提供する、最初の小規模デプロイを指します。
カナリアデプロイが重要な理由
包括的なテストスイートを用いていても、実際のユーザートラフィックパターン、本番環境のデータ量、特定のユーザーデバイスの組み合わせ、テストでは再現されないネットワーク状況など、本番環境でのみ表面化する障害があります。テスト環境が本番環境を完全に再現することは不可能です。
カナリアデプロイは、新バージョンが全ユーザーに届く前の最後の防衛ラインです。「このバージョンは実際の本番トラフィックに対して正常に動作するか?」という問いに答えます。
テストとの関係
カナリアデプロイとテストは代替関係ではなく、補完関係にあります。テスト(自動化されたE2Eテストを含む)はデプロイに踏み切るための自信を与え、カナリア戦略はテストが見逃した場合の影響範囲を限定します。
その関係性:
- デプロイ前テストはバグの大多数を検出します。TestSpriteの自動テストスイートはすべてのPRで実行され、テストが失敗するとマージをブロックします。
- カナリアデプロイは残りの本番環境固有の問題を検出します。
- 本番監視は、大規模環境や時間経過によってのみ現れる問題を検出します。
強固な自動テストを持つチームは、ほとんどのバグがデプロイ前に検出されていると分かっているため、迅速なロールアウトスケジュールで自信を持ってカナリアをデプロイできます。自動テストのないチームは、各リリースへの信頼性が低いため、カナリアのロールアウト速度について非常に慎重に対応する必要があります。
カナリアデプロイの実際の仕組み
トラフィックの分割
カナリアデプロイは、受信トラフィックを安定バージョンと新バージョンに分割します。分割は小さく(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コントラクトは後方互換性を保つ必要があります。
データベースマイグレーションのカナリアテスト
データベースマイグレーションは、カナリアデプロイにおいて最も危険な側面です。テーブル構造を変更するマイグレーションは、ロールアウト期間中、古いアプリケーションバージョンと新しいアプリケーションバージョンの両方と同時に互換性を保つ必要があります。
安全なパターン:
- 拡張:古い構造を維持しながら、新しいカラム/テーブルを追加するマイグレーションを実行する(非破壊的)
- カナリアのデプロイ:新しいコードが古い構造と新しい構造の両方に書き込む
- ロールアウトの完了:すべてのトラフィックが新しいバージョンに移行
- 縮小:古い構造を削除するマイグレーションを実行する
各フェーズを明示的にテストする:同じデータベースに対して古いコードと新しいコードが同時に実行されている場合、アプリケーションは正しく動作するか?
カナリアデプロイを使うべき状況
カナリアデプロイは運用上の複雑さを増加させます。以下の状況で最も効果を発揮します:
- アプリケーションが十分なトラフィックを処理しており、5%のカナリアが統計的に意味のあるシグナルを提供できる場合(デイリーアクティブユーザーが数万人規模)
- バージョン別にメトリクスをセグメント化できるモニタリングインフラが整っている場合
- トラフィックを確実に分割できるデプロイインフラが整っている場合
- ユーザーベースの大部分に影響を与える可能性がある変更をデプロイする場合
トラフィックが少ない初期段階のアプリケーションでは、カナリアデプロイの運用オーバーヘッドが正当化されない場合があります。強力な自動テスト(すべてのPRでTestSpriteを実行)は、小規模なデプロイに適した信頼性を提供します。
TestSpriteでカナリアデプロイ前に信頼性を高める →