一言で言えば、カナリア リリースの背後にある考え方は、新しいソフトウェア バージョンを一部のユーザーにのみ配信し、結果を分析して、さらに続行するかどうかを決定することです。結果が期待と一致しない場合は、ロールバックします。存在する場合は、すべてのユーザーが新しいバージョンの恩恵を受けるまで、公開されるユーザーの数を増やします。
この投稿では、この導入について簡単に詳しく説明し、分数を定義するさまざまな方法を説明し、 Apache APISIX でそれを実行する方法を示したいと思います。
「カナリア」という用語は石炭鉱業に由来します。採掘中に有毒ガスが放出されることは珍しいことではありません。狭い密閉空間では、即死を意味する可能性があります。さらに悪いことに、ガスは無臭である可能性があるため、鉱山労働者は立ち去るには手遅れになるまでそれを吸い込むことになります。一酸化炭素は炭鉱では非常に一般的ですが、人間の感覚では検出できません。
このため、鉱山労働者はカナリアを地下に連れて行きました。カナリアが突然落ちて死んだ場合は、そのようなガスポケットが突破された可能性が高く、その場を離れる時期が来ています。
数年前、私たちはこのアプローチを新しいソフトウェア バージョンのリリースに導入しました。アナロジーは次のようになります。マイナーはバージョンをデプロイする運用チーム、カナリアはリリースの影響を測定するすべてのツールで構成され、ガスは (重大な) バグです。
最も重要な部分は、失敗率、HTTP ステータス コードなどを含むリリースの影響を測定し、以前のバージョンの影響と比較する必要があることです。これはこの投稿の範囲外ですが、カナリア リリースのメリットを享受したい場合には、繰り返しになりますが、これは重要です。 2 番目に重要な部分は、新しいバージョンにバグがある場合に迅速にロールバックできる機能です。
新しいコードをリリースするリスクを管理する方法はカナリア リリースだけではないことに注意してください。たとえば、機能フラグもよく使われる方法です。
機能フラグは、ロールバックに対する (言葉の本当の意味で) より機敏なアプローチを表します。 10 の機能のうち 1 つの機能にバグがある場合、新しいバージョンのデプロイを取り消す必要はありません。バグのある機能を無効にするだけです。ただし、このスーパーパワーには、サードパーティ製品に依存するか自分で実装するかに関係なく、コードベースがさらに複雑になるという代償が伴います。
一方、Canary では、自由にデプロイおよびアンデプロイできるように、成熟したデプロイメント パイプラインが必要です。
カナリア リリースの背後にある考え方は、一部のユーザーのみが新しいバージョンにアクセスできるようにすることです。ほとんどのカナリア定義では、「割合」をユーザーの割合としてのみ定義します。ただし、それだけではありません。
最初のステップは、実稼働環境での展開が期待どおりに機能するかどうかを、精査されたユーザーのみにチェックできるようにすることです。この場合、テスターなどの特定の内部ユーザーのセットのみを新しいバージョンに転送できます。事前に人物がわかっていて、システムがユーザーを認証する場合は、ID によって構成できます。そうでない場合は、HTTP ヘッダー - X-Canary: Let-Me-Go-To-v2
一般的な方法にフォールバックする必要があります。
矛盾を確認するには、古いシステムと新しいシステムを監視する必要があることに注意してください。何も表示されない場合は、新しいバージョンに転送されるユーザーのプールを増やすのに最適な時期です。あなたは自分でドッグフードを食べていると思います。チームメンバーは、開発中のソフトウェアを使用します。たとえば、高級車の e コマース サイト以外の場合は、このセクションを飛ばしていただいても問題ありません。
リスクを制限しながらユーザーの割合を拡大するために、内部ユーザーに新しいバージョンを無差別に提供できるようになりました。これを行うには、クライアント IP に基づいて新しいバージョンに転送するようにシステムを構成できます。人々がオンサイトで作業していた時代は、IP が特定の範囲内にあったため、作業は簡単でした。ユーザーはおそらく VPN 経由で会社のネットワークにアクセスするため、リモートはあまり変わりません。
もう一度、この時点で監視して比較してください。
この時点で、少数または全員の内部ユーザーに対してすべてが期待どおりに動作するはずです。しかし、敵と接触した場合に生き残る計画がないのと同じように、運用ワークロードの多様性全体を模倣することはできません。つまり、通常のユーザーが新しいバージョンにアクセスできるようにする必要がありますが、これまでユーザー数を徐々に増やしてきたのと同じように、制御された方法で、小さな部分から始めて監視し、すべてが順調であればその部分を増やします。 。
Apache APISIX を使用してこれを行う方法は次のとおりです。 Apache APISIX はプラグイン ベースのアーキテクチャを提供し、ニーズを満たすプラグイン、つまりtraffic-split
プラグインを提供します。
traffic-split
プラグインを使用すると、トラフィックの一部をさまざまなアップストリーム サービスに動的に転送できます。これは、トラフィックを分割するためのカスタム ルールである
match
と、トラフィックを送信するアップストリームのセットであるweighted_upstreams
を構成することによって行われます。
--トラフィック分割
バージョンごとに 1 つずつ、いくつかの基本的なアップストリームから始めましょう。
upstreams: - id: v1 nodes: "v1:8080": 1 - id: v2 nodes: "v2:8080": 1
traffic-split
プラグインを使用すると、トラフィックの大部分を v1 に転送し、一部を v2 に転送できます。
routes: - id: 1 uri: "*" #1 upstream_id: v1 plugins: traffic-split: rules: - weighted_upstreams: #2 - upstream_id: v2 #3 weight: 1 #3 - weight: 99 #3
繰り返しますが、私たちはすべてを監視し、結果が期待どおりであることを確認します。次に、v2 に転送されるトラフィックの割合を増やすことができます。例:
routes: - id: 1 uri: "*" upstream_id: v1 plugins: traffic-split: rules: - weighted_upstreams: - upstream_id: v2 weight: 5 #1 - weight: 95 #1
Apache APISIX は上記のファイルへの変更を 1 秒ごとにリロードすることに注意してください。したがって、ほぼリアルタイムでトラフィックを分割します。あるいは、Admin API を使用して同じことを実現できます。
上記では、内部ユーザーから一部の外部ユーザーに移行しました。おそらく、すべての内部ユーザーにリリースすることは組織にとってリスクが大きすぎるため、さらに強力な制御が必要になるでしょう。この場合、 traffic-split
プラグインをさらに構成できることに注意してください。
routes: - id: 1 uri: /* upstream_id: v1 plugins: traffic-split: rules: - match: - vars: [["http_X-Canary","~=","Let-Me-Go-To-v2"]] #1 - weighted_upstreams: - upstream_id: v2 weight: 5 - weight: 95
X-Canary
HTTP ヘッダーに設定された値がある場合にのみ、トラフィックを分割します。
次のコマンドは常に v1 に転送します。
curl http://localhost:9080
次のコマンドも常に v1 に転送します。
curl -H 'X-Canary: Let-Me-Go-To-v1' http://localhost:9080
次のコマンドは、設定された重み、つまり95/5 に従ってトラフィックを分割します。
curl -H 'X-Canary: Let-Me-Go-To-v2' http://localhost:9080
この投稿では、カナリア リリースと、Apache APISIX 経由でカナリア リリースを構成する方法について説明しました。優先度の異なる複数のルートから始めて、 traffic-split
プラグインに進むことができます。後者は、より複雑なユースケースを可能にするためにさらに構成することもできます。
この投稿の完全なソース コードはGitHubにあります。
さらに進むには:
初出は 2023 年 12 月 3 日にA Java Geekで公開されました