カナリアリリース
Canary Release ・ かなりありりーす
新しい版を一部のトラフィックにだけ流し、指標で健全を確かめながら段階的に広げるデプロイ手法。
✦ 30秒で試す — 航海全員に配る前に、ほんの数%の利用者で毒見をする失敗の割合は2倍。新しい版は悪くなったと言える?予想してみる概要
カナリアリリースは、新しい版をいきなり全員に公開するのではなく、まず全体のごく一部(たとえば5%)のトラフィックだけに流して様子を見て、問題がなければ 25% → 50% → 100% と段階的に広げていくデプロイ手法です。名前は、炭鉱夫が有毒ガスを早く察知するためにカナリアを連れて坑道に入った故事に由来します。人より先にカナリアが異変を示したように、少数のリクエストに「先に新しい版を踏んでもらう」ことで、全体に被害が広がる前に問題に気づこうというわけです。
CI/CD で自動デプロイが日常になっても、「本番で初めて分かる問題」はなくなりません。テスト環境では再現しない負荷、実データの偏り、特定の端末や地域でだけ起きる不具合。こうした本番でしか分からないことを、影響の範囲をわざと小さく絞った状態で確かめるのがカナリアリリースの役割です。ロードバランサ、Kubernetes の周辺ツール、サービスメッシュが「重みを付けて振り分ける」機能を標準で持つようになり、大規模なサービスでは当たり前の手法になりました。
ただし「一部に流す」だけでは半分です。流した一部の結果を見て、新しい版が本当に悪くなっているのかを判断しなければなりません。数%のトラフィックで得られる件数は少なく、判断には統計の考え方が要ります。カナリアリリースは、流す比率の決め方と判定のしかたを組にして初めて機能します。
なぜ生まれたか
かつてのデプロイは一斉の切り替えでした。すべてのサーバのプログラムを新しい版に入れ替えた瞬間、全員が同時に新しいコードを踏みます。そこに重大なバグがあれば影響はすぐ全員に及び、気づいて戻すまでの数分から数十分がまるごと障害の時間になります。テストをどれだけ充実させても、実際のトラフィックの量と中身、実データ、ほかのシステムとの相互作用を完全には再現できません。「デプロイは毎回、全員を巻き込む賭け」という構図から抜け出せなかったのです。
カナリアリリースは、この賭けの掛け金を小さくする発想です。「バグをゼロにしてから出す」のではなく、「バグは出るものと認め、出たときの被害の範囲(ブラスト半径)を小さくする」ほうへ問題を組み替えました。全体の5%で異常が出たなら、被害はその5%で止まり、残りの95%は旧版を使い続けられます。この手法は Google や Netflix のような大規模サービスで早くから使われ、2014年に Danilo Sato が Martin Fowler のサイトで「CanaryRelease」として整理したことで広く知られるようになりました。SRE が掲げる「信頼性はリスクの管理である」という考え方の実践であり、エラーバジェットを無駄に使わないためのリリースの設計でもあります。
詳細
仕組み — 重み付きの振り分けと段階的な拡大
土台は、旧版(stable)と新しい版(canary)を本番に同時に動かし、ロードバランサやリバースプロキシがトラフィックに重みを付けて振り分けることです。最初は canary に 5% ほどだけを流し、メトリクスを観察して問題がなければ比率を上げ、最後に 100% にして旧版を退役させます。
進め方を状態の遷移で書くと、次のようになります。各段階で「分析」をはさみ、合格なら次へ、不合格ならその場で 0% へ戻します。
振り分けの実装にはいくつかの方式があります。いちばん単純なのはサーバの台数比(10台のうち1台だけ新しい版にする)ですが、リクエストごとにばらばらに振り分けると、同じ利用者が新旧の版を行き来してしまいます。そのため実務では、ユーザー ID や Cookie をもとに同じ人をいつも同じ側へ送る「スティッキー」な振り分けがよく使われます。「社内の利用者だけ」「特定の地域だけ」といった属性で対象を選ぶカナリアもあり、この場合は割合ではなく対象の集団を段階的に広げます。
判定 — 何件あれば「悪くなった」と言えるか
カナリアの成否を分けるのは、「canary は健全か」を何でどう判定するかです。エラー率・レイテンシ・資源の使用量といったメトリクスを canary と比較対象とで比べ、canary が統計的に悪くなっていれば自動で戻す。この「メトリクスによる自動の昇格とロールバック」を実現するのが、Argo Rollouts、Flagger、Spinnaker(判定エンジンの Kayenta)といったプログレッシブデリバリーの道具です。
難しいのは、件数が少ないうちは何も言えないことです。平常のエラー率が 0.5% のサービスで、canary に 200 件流して失敗が 2 件(1%)だったとします。一見倍に悪化していますが、200 件で 1〜2 件の失敗は偶然でも普通に起きます。「平常 0.5% と悪化後 1.0% を見分ける」には、よく使われる目安の式(有意水準 5%・検出力 80% のとき、1 群あたりの件数 ≈ 16 × p(1−p) ÷ 差²。p は両群の平均の失敗率)で見積もると、1 群あたり約 4,800 件が必要です。毎秒 100 件のサービスで canary に 5% を流すなら、canary に届くのは毎秒 5 件なので、判定まで 16 分ほどかかります。比率を 25% に上げれば 3 分ほどで済みますが、その間に巻き込む人数は5倍です。まれなバグほど、差が小さいほど、判定には時間か比率のどちらかを払うことになります。
判定をもう1つ難しくするのが、メトリクスの遅れです。指標は数十秒から数分ごとに集計されて届くので、悪化に気づいた時点で、その遅れの間に流れた分の被害はすでに出ています。比率が大きいほど、この「気づくまでの被害」は大きくなります。
下の部品で、canary へ流す比率のつまみを動かしてみてください。紫の帯(失敗率の95%区間)が閾値の線より上に抜けると「悪化」と判定されて自動で 0% に戻ります。5% と 50% で、判定までの時間と失敗の件数を比べてください。
canary(新しい版 v2)にはまだ何も流れていません。ロードバランサの下のつまみをつかんで 5% まで動かし、新しい版に少しだけ流してください。
比べる相手の選び方も大切です。canary の失敗率を「過去の平常値」と比べると、時間帯による変動やトラフィックの偏りに惑わされます。同じ時間帯に同じ種類のトラフィックを受けている相手と比べるのが原則です。さらに Kayenta の推奨する方法では、長く動いている旧版の本番群全体ではなく、canary と同時に同じ台数で起動し直した旧版(baseline)と比べます。起動したばかりのサーバはキャッシュが温まっていないなど条件が違うので、「新しいから遅い」のか「版が悪いから遅い」のかを分けるためです。判定の材料をそろえるには、監視の基盤が新旧の版をラベルで区別して指標を集められることが前提で、判定の基準は SLO とそろえておくのが定石です。
落とし穴と設計上の注意
新旧の版が本番に同時に存在するので、両者は互換でなければなりません。特にデータベースのスキーマ変更は、新旧どちらのコードからも読み書きできる形で行う必要があります(一度に変えず、足す → 移す → 消すと段階を踏むのが定石です)。新旧の版が互いに API を呼び合う場合も、どちらの組み合わせでも動くことが必要です。
また、カナリアで見つけられるのは「メトリクスに現れる問題」だけです。計算結果が静かに間違っている、特定の操作をしたときだけデータが壊れる、といった不具合はエラー率にもレイテンシにも出ません。何を観測すれば異常と言えるかを設計するオブザーバビリティの成熟度が、そのままカナリアの検出力を決めます。発生率の低いバグは少ない比率では検出しにくいので、5% で「問題なし」と判定しても 100% で表に出ることがあります。慎重にしすぎると、1回のリリースに何日もかかるという運用の重さも生じます。比率・観察時間・閾値は、この検出力と速さの綱引きの中で決めることになります。
ブルーグリーンデプロイ・フィーチャーフラグとの使い分け
ブルーグリーンデプロイは環境を丸ごと2系統用意して一気に切り替える手法で、切り替えも切り戻しも一瞬ですが、「一部に流して様子を見る」段階がありません。カナリアは逆に、確かめる丁寧さと引き換えに、リリースが終わるまでの時間が延びます。障害時の切り戻しの速さを最優先するならブルーグリーン、本番のトラフィックでの検証を重視するならカナリア、と目的で使い分けます。両者を組み合わせて、グリーンへの切り替えを重みの段階で行う折衷もあります。
フィーチャーフラグは、似た効果をアプリケーションのコードの中で実現する仕組みで、「デプロイの単位」ではなく「機能の単位」で公開の範囲を制御できます。インフラ層のカナリアは版全体の健全さを、フィーチャーフラグは個々の機能の是非を確かめる、と役割が分かれており、実務では併用されることが多い関係です。
試問
利用者のリクエストが、ロードバランサで古い版(stable、平常の失敗率 0.5%)と新しい版(canary)に振り分けられます。つまみで canary に流す比率を 0〜100% の段階で選び、閾値を選びます。canary の失敗率の95%区間(本当の失敗率としてあり得る幅)の下端が閾値を超えると「悪化」と判定され、自動で 0% に戻ります。
canary(新しい版 v2)にはまだ何も流れていません。ロードバランサの下のつまみをつかんで 5% まで動かし、新しい版に少しだけ流してください。
