好きな技術を布教したい 😗

〜 沼のまわりに餌をまく 〜

【Istio⛵️】Istioを安全にアップグレードするカナリア方式とその仕組み


この記事から得られる知識

この記事を読むと、以下を "完全に理解" できます✌️

  • Istioのアップグレード手法の種類について
  • 安全なカナリア方式の仕組みについて



01. はじめに


隠しません。

有吉弘行のサンデーナイトドリーマー が生きがいです。

istio-icon


さて、最近の業務でIstio⛵️をひたすらアップグレードしています。

今回は、採用したアップグレード手法の紹介も兼ねて、Istioの安全なアップグレード手法の仕組みを記事で解説しました。

Istioのアップグレード手法には変遷があり、解説するのは執筆時点 (2023/02/26) で最新の 1.14 系のアップグレード手法です。

それでは、もりもり布教していきます😗

記事中のこのボックスは、補足情報を記載しています。

飛ばしていただいても大丈夫ですが、読んでもらえるとより理解が深まるはずです👍


02. なぜ安全なアップグレードが必要なのか

起こりうる問題

そもそも、なぜIstioで安全なアップグレードを採用する必要があるのでしょうか。

Istioで問題が起こると、Pod内のistio-proxyコンテナが正しく稼働せず、システムに大きな影響を与える可能性があります。

例えば、istio-proxyコンテナのPodへのインジェクションがずっと完了せず、アプリコンテナへの通信が全て遮断されるといったことが起こることがあります。

istio_istio_incident


採用するべきアップグレード手法

執筆時点 (2023/02/26) では、Istiodコントロールプレーン (以降、Istiodとします) のアップグレード手法には、『インプレース方式』と『カナリア方式』があります。

また合わせてアップグレードが必要なIstio IngressGatewayには、その手法に『インプレース方式』があります。

istio_upgrade_list

今回の安全なアップグレード手法として、Istiodでは『カナリアアップグレード』、Istio IngressGatewayでは『インプレースアップグレード』を採用します。


03. アップグレード手法を説明する前に

カナリアリリースとは

Istiodのカナリアアップグレードが理解しやすくなるように、カナリアリリースから説明したいと思います。

カナリアリリースは、実際のユーザーにテストしてもらいながらリリースする手法です。

もしカナリアリリースをご存知の方は、 04. アップグレード手法の概要 まで飛ばしてください🙇🏻‍


カナリアリリースの手順

カナリアリリースは、一部のユーザーを犠牲にすることになる一方で、アプリを実地的にテストできる点で優れています。

手順を交えながら説明します。

(1) 新環境のリリース

旧環境のアプリを残したまま、新環境をリリースします。

この段階では、全てのユーザー (100%) を旧環境にルーティングします。

canary-release_1

(2) 新環境への重み付けルーティング

ロードバランサーで重み付けを変更し、一部のユーザー (ここでは10%) を新環境にルーティングします。

canary-release_2

(3) 実地的テストの実施

ユーザーの手を借りて新環境を実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。

canary-release_3

(4) 重み付けの段階的変更

新環境に問題が起こらなければ、重み付けを段階的に変更し、最終的には全てのユーザー (100%) を新環境にルーティングします。

canary-release_4


カナリアリリース』の呼称の由来

カナリアリリースについては、その呼称の由来を知ると、より理解が深まります。

カナリアリリースは、20世紀頃の炭坑労働者の危機察知方法に由来します。

炭鉱内には有毒な一酸化炭素が発生する場所がありますが、これは無色無臭なため、気づくことに遅れる可能性があります。

そこで当時の炭鉱労働者は、一酸化炭素に敏感な『カナリア』を炭鉱内に持ち込み、カナリアの様子から一酸化炭素の存在を察知するようにしていたそうです。

つまり、先ほどの『犠牲になる一部のユーザー』が、ここでいうカナリアというわけです😨

canary_release_origin
画像引用元:George McCaa, U.S. Bureau of Mines


04. アップグレード手法の概要

カナリアリリースを理解したところで、Istioの安全なアップグレード手法の概要を説明します。

おおよそ以下の手順からなります。

なお各番号は、05. アップグレード手法の詳細 の (1) 〜 (8) に対応しています。


(1) アップグレード前の検証

旧Istiodが稼働しています。

ここで、アップグレードが可能かどうかを検証しておきます。

istio_canary-upgrade_1


(2) 新Istiodのインストール

新Istiod (discoveryコンテナ) をインストールします。

istio_canary-upgrade_2


(3) Webhookの宛先のServiceの変更

新Istiodのistio-proxyコンテナをインジェクションできるように、Webhookの宛先のServiceを変更します。

この手順は重要で、後の (3) Webhookの宛先のServiceの変更 で詳細を説明しています。


(4) Istio IngressGatewayをインプレースアップグレード

Istio IngressGatewayをインプレースアップグレードします。

istio_canary-upgrade_4


(5) 一部のNamespaceのistio-proxyコンテナをアップグレード

一部のNamespaceで、istio-proxyコンテナをカナリアアップグレードします。

istio_canary-upgrade_5


▶︎ 『カナリアアップグレード』の呼称について

ここで、カナリアリリースのような重み付けがなく、カナリアアップグレードの『カナリア』という呼称に違和感を持つ方がいるかもしれません。

これについては、全てのNamespaceのistio-proxyコンテナを一斉にアップグレードするのではなく、段階的にアップグレードしていく様子を『カナリア』と呼称している、と個人的に推測しています。

もし『カナリアアップグレード』の由来をご存じの方は、ぜひ教えていただけると🙇🏻‍


(6) ユーザの手を借りたテスト

ユーザーの手を借りて、実地的にテストします (例:該当のエラーメトリクスが基準値以下を満たすか) 。

istio_canary-upgrade_6


(7) istio-proxyコンテナの段階的アップグレード

新Istiodのistio-proxyコンテナに問題が起こらなければ、他のNamespaceでもistio-proxy コンテナを段階的にカナリアアップグレードしていきます。

一方でもし問題が起これば、Namespaceのistio-proxyコンテナとIstio IngressGatewayをダウングレードします。

istio_canary-upgrade_7


(8) 旧Istiodのアンインストール

最後に、旧Istiodをアンインストールします。

istio_canary-upgrade_8


05. アップグレード手法の詳細

istioctl コマンドを使用したアップグレード

ここからは、04. アップグレード手法の概要 を深ぼっていきます。

今回は、ドキュメントで一番優先して記載されている istioctl コマンドを使用した手順 を説明します。

なお各番号は、04. アップグレード手法の概要 の (1) 〜 (8) に対応しています。


▶︎ アップグレードに使用するツールについて

もちろん、istioctlコマンド以外のツール (例:helmコマンド、helmfileコマンド、ArgoCD) を使用してもアップグレードできます。

細かな手順が異なるだけで、アップグレード手法の概要は同じです🙆🏻‍


前提

Namespace

まず最初に、前提となる状況を設定しておきます。

istio_canary-upgrade_rollout-restart_1

各Namespaceのistio.io/revラベルにdefaultが設定されているとします。

$ kubectl get namespace -L istio.io/rev

NAME              STATUS   AGE   REV
foo               Active   34d   default
bar               Active   34d   default
baz               Active   34d   default
istio-ingress     Active   34d   default

...


▶︎ istio.io/revラベル値のエイリアスについて

istio.io/revラベル値は、どんなエイリアスでもよいです。

よくあるエイリアスとしてdefaultstableを使用します👍

さらに、マニフェストに書き起こすと以下のようになっています。

apiVersion: v1
kind: Namespace
metadata:
  name: foo
  labels:
    istio.io/rev: default

このistio.io/revラベルがあることにより、そのNamespaceのPodにistio-proxyコンテナを自動的にインジェクションします。


▶︎ istio-proxyコンテナのインジェクションの仕組みについてについて

istio-proxyコンテナのインジェクションの仕組みについては、今回言及しておりません。

以下の記事で解説していますため、もし気になる方はよろしくどうぞ🙇🏻‍

Istiod

istio_canary-upgrade_rollout-restart_1

すでに1-14-6のIstiodが動いており、1-15-4カナリアアップグレードします。

IstiodはDeployment配下のPodであり、このPodはIstiodの実体であるdiscoveryコンテナを持ちます。

$ kubectl get deployment -n istio-system -l app=istiod

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
istiod-1-14-6          1/1     1            1           47s # 1-14-6

Istio IngressGateway

Istio IngressGatewayはIstiodとは異なるNamespaceで動いており、インプレースアップグレードします。

istio_canary-upgrade_rollout-restart_1

Istio IngressGatewayはistio-proxyコンテナを持ちます。

$ kubectl get deployment -n istio-ingress

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
istio-ingressgateway   1/1     1            1           47s


▶︎ IstiodとIstio IngressGatewayを動かすNamespaceについて

セキュリティのベストプラクティスでは、IstiodとIstio IngressGatewayは異なるNamespaceで動かすことが推奨されています。

マイクロサービス

各Namespaceでマイクロサービスが動いています。

マイクロサービスのPodはistio-proxyコンテナを持ちます。

$ kubectl get deployment -n foo

NAME   READY   UP-TO-DATE   AVAILABLE   AGE
foo    2/2     1            1           47s
...
$ kubectl get deployment -n bar

NAME   READY   UP-TO-DATE   AVAILABLE   AGE
bar    2/2     1            1           47s
..
$ kubectl get deployment -n baz

NAME   READY   UP-TO-DATE   AVAILABLE   AGE
baz    2/2     1            1           47s
...


(1) アップグレード前の検証

ここで実施すること

アップグレード前に、現在のKubernetes Clusterがアップグレード要件を満たしているかを検証します。

istioctl x precheckコマンド

istioctl x precheckコマンドを実行し、アップグレード要件を検証します。

問題がなければ、istioctlコマンドはNo issue ...の文言を出力します。

$ istioctl x precheck

✅ No issues found when checking the cluster.Istiois safe to install or upgrade!
  To get started, check out https://istio.io/latest/docs/setup/getting-started/


▶︎ アップグレード要件が満たない場合について

もし、問題がある場合、istioctl x precheckコマンドはエラー文言を出力します。

例えば、Istioのistio-proxyコンテナのインジェクションではkube-apiserverと通信する必要があります。

そのため、kube-apiserverのバージョンが古すぎるせいでIstioが非対応であると、エラーになります😭

kubectl getコマンド

▼ IstiodのDeployment

kubectl getコマンドを実行し、現在のIstiodのバージョンを確認します👀

まずはIstiodのDeploymentを確認すると、1-14-6のDeploymentがあります。

$ kubectl get deployment -n istio-system -l app=istiod

NAME                   READY   UP-TO-DATE   AVAILABLE   AGE
istiod-1-14-6          1/1     1            1           47s # 1-14-6

istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です👇

istio_canary-upgrade_webhook_1-1

▼ Webhookの宛先のService

次に、 Serviceを確認すると、1-14-6のServiceがあります。

$ kubectl get service -n istio-system -l app=istiod

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                 AGE
istiod-1-14-6   ClusterIP   10.96.93.151     <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   109s # 1-14-6

このServiceは、kube-apiserverからIstiodへのWebhookを仲介することにより、istio-proxyコンテナのインジェクションを可能にします。

istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です👇

istio_canary-upgrade_webhook_1-2

▼ 宛先のServiceを決めるMutatingWebhookConfiguration

最後に、MutatingWebhookConfigurationを確認すると、istio-revision-tag-<エイリアス>istio-sidecar-injector-<リビジョン番号>のMutatingWebhookConfigurationがあります。

$ kubectl get mutatingwebhookconfigurations

NAME                            WEBHOOKS   AGE
istio-revision-tag-default      2          114s  # カナリアアップグレード用
istio-sidecar-injector-1-14-6   2          2m16s # インプレースアップグレード用のため今回は言及しない

istio-proxyコンテナのインジェクションの仕組みでいうと、以下の赤枠の要素です👇

istio_canary-upgrade_webhook_1-3

これらのうち、前者 (istio-revision-tag-<エイリアス>) をカナリアアップグレードのために使用します。

このMutatingWebhookConfigurationは、Webhookの宛先のServiceを決めるため、結果的にistio-proxyコンテナのバージョンを決めます。

ここで、MutatingWebhookConfigurationのistio.io/revラベルとistio.io/tagラベルの値も確認しておきます。

$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | yq '.metadata.labels'

...

istio.io/rev: 1-14-6
istio.io/tag: default

...

istio.io/revラベルはIstiodのバージョン、istio.io/tagラベルはこれのエイリアスを表しています。

また、.webhooks[].namespaceSelectorキー配下のistio.io/revキーの検知ルールを確認します。

$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | yq '.webhooks[]'

...

namespaceSelector:
  matchExpressions:
    - key: istio.io/rev
      operator: In
      values:
        - default

...

合わせて、.webhooks[].clientConfig.serviceキー配下のServiceを名前を確認します。

$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | yq '.webhooks[].clientConfig'

...

service:
  name: istiod-1-14-6

...


▶︎ MutatingWebhookConfigurationの役割について

ここで、重要な仕組みをおさらいします。

Namespaceでistio.io/revラベルにdefaultを設定してあるとします。

すると、上記のMutatingWebhookConfigurationがこれを検知します。

MutatingWebhookConfigurationにはdefaultに対応するIstioのリビジョンが定義されており、kube-apiserverが特定のIstioのバージョンのServiceにWebhookを送信可能になります🎉


(2) 新Istiodのインストール

ここで実施すること

それでは、新Istiodをインストールします。

istioctl versionコマンド

新しくインストールするIstiodのバージョンは、istioctlコマンドのバージョンで決まります。

そこで、istioctl versionコマンドを実行し、これのバージョンを確認します。

$ istioctl version

client version: 1.15.4        # アップグレード先のバージョン
control plane version: 1.14.6 # 現在のバージョン
data plane version: 1.14.6

istioctl installコマンド

カナリアアップグレードの場合、istioctl installコマンドを実行します。

ドキュメントではrevisionキーの値がcanaryですが、今回は1-15-4とします。

この値は、Istioが使用する様々なKubernetesリソースの接尾辞や、各リソースのistio.io/revラベルの値になります。

$ istioctl install --set revision=1-15-4

WARNING: Istio is being upgraded from 1.14.6 -> 1.15.4
WARNING: Before upgrading, you may wish to use 'istioctl analyze' to check for IST0002 and IST0135 deprecation warnings.

✅ Istio core installed
✅ Istiod installed
✅ Ingress gateways installed
✅ Installation complete

Thank you for installing Istio 1.15.  Please take a few minutes to tell us about your install/upgrade experience!
▶︎ カナリアアップグレードで指定できるバージョン差について

revisionキーを使用したカナリアアップグレードでは、2つの先のマイナーバージョンまでアップグレードできます。

例えば、現在のIstioが1.14.6であるなら、1.16系まで対応しています👍

kubectl getコマンド

▼ IstiodのDeployment

kubectl getコマンドを実行し、istioctl installコマンドで何をインストールしたのかを確認します👀

まずはIstiodのDeploymentを確認すると、1-15-4というDeploymentが新しく増えています。

$ kubectl get deployment -n istio-system -l app=istiod

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
istiod-1-14-6   1/1     1            1           47s # 1-14-6
istiod-1-15-4   1/1     1            1           47s # 1-15-4

接尾辞の1-15-4は、revisionキーの値で決まります。

この段階では、旧Istiodと新Istioが並行的に稼働しており、kube-apiserverはまだ旧Istiodと通信しています

今の状況は以下の通りです👇

istio_canary-upgrade_webhook_2-1

▼ Webhookの宛先のService

次に Webhookの宛先のServiceを確認すると、istiod-1-15-4というServiceが新しく増えています。

$ kubectl get service -n istio-system -l app=istiod

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                 AGE
istiod-1-14-6   ClusterIP   10.96.93.151     <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   109s # 1-14-6
istiod-1-15-4   ClusterIP   10.104.186.250   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   87s  # 1-15-4

この段階では、まだWebhookの宛先はistiod-1-14-6のServiceです。

今の状況は以下の通りです👇

istio_canary-upgrade_webhook_2-2

▼ Webhookの宛先のServiceを決めるMutatingWebhookConfiguration

最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-15-4というMutatingWebhookConfigurationが新しく増えています。

$ kubectl get mutatingwebhookconfigurations

NAME                            WEBHOOKS   AGE
istio-revision-tag-default      2          114s  # カナリアアップグレードで使用する
istio-sidecar-injector-1-14-6   2          2m16s
istio-sidecar-injector-1-15-4   2          2m16s

カナリアアップグレードでは、istio-revision-tag-<エイリアス>のMutatingWebhookConfigurationを使用します。

今の状況は以下の通りです👇

istio_canary-upgrade_webhook_2-3


▶︎ アンインストールについて

実は、他にもインストールしているものがあるのですが、話をわかりやすくするために、今回は言及していません🙇🏻‍


(3) Webhookの宛先のServiceの変更

ここで実施すること

この手順では、エイリアスistio.io/tagラベルの値はそのままにしておき、一方でistio.io/revラベルの値を変更します。

さらに、Webhookの宛先のServiceを変更します。

istioctl tag setコマンド

istioctl tag setコマンドを実行し、istio.io/revラベルの値と宛先のServiceを変更します。

$ istioctl tag set default --revision 1-15-4 --overwrite

実行後に、もう一度MutatingWebhookConfigurationを確認すると、istio.io/revラベルの値が変わっています。

$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | yq '.metadata.labels'

...

istio.io/rev: 1-15-4
istio.io/tag: default

...

また、Webhookの宛先のServiceも変わっています。

$ kubectl get mutatingwebhookconfiguration istio-revision-tag-default -o yaml \
    | yq '.webhooks[].clientConfig'

...

service:
  name: istiod-1-15-4

...

これらにより、Webhookの宛先が 1-15-4 のService となります。

そのため、 1-15-4 の istio-proxy コンテナをインジェクションできる ようになります。

今の状況は以下の通りです👇

istio_canary-upgrade_webhook_3


(4) Istio IngressGatewayをインプレースアップグレード

ここで実施すること

Webhookの宛先が1-15-4のServiceに変わったところで、Istio IngressGatewayをインプレースアップグレードします。

kubectl rollout restartコマンド

kubectl rollout restartコマンドを実行し、Istio IngressGatewayをインプレースアップグレードします。

$ kubectl rollout restart deployment istio-ingressgateway-n istio-ingress

再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。

$ kubectl get pod bar -n bar -o yaml | yq '.spec.containers[].image'

docker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ


▶︎ istioctl proxy-statusコマンドについて

kubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。

今の状況は以下の通りです👇

istio_canary-upgrade_rollout-restart_2


▶︎ Istio IngressGatewayの通信遮断について

Istio IngressGatewayのアップグレード時、マイクロサービスへのインバウンド通信が遮断されてしまうと思った方がいるかもしれません。

この点については、DeploymentがローリングアップデートでIstio IngressGatewayのPodを入れ替えるため、安心していただいて問題ありません🙆🏻‍


(5) 一部のNamespaceのistio-proxyコンテナをアップグレード

ここで実施すること

続けて、一部のNamespaceのistio-proxyコンテナをアップグレードします。

Podの再作成により、新Istiodのistio-proxyコンテナがインジェクションされるため。istio-proxyコンテナをアップグレードできます。

kubectl rollout restartコマンド

前提にあるように、Namespaceには foo bar baz があります。

kubectl rollout restartコマンドを実行し、baristio-proxyコンテナからアップグレードします。

$ kubectl rollout restart deployment bar -n bar

再作成したPodのイメージを確認してみると、istio-proxyコンテナを1-15-4にアップグレードできています。

$ kubectl get pod bar -n bar -o yaml | yq '.spec.containers[].image'

bar-app:1.0 # マイクロサービス
docker.io/istio/proxyv2:1.15.4 # istio-proxyコンテナ


▶︎ istioctl proxy-statusコマンドについて

kubectl getコマンドの代わりに、istioctl proxy-statusコマンドを使用して、アップグレードの完了を確認してもよいです。

今の状況は以下の通りです👇

istio_canary-upgrade_rollout-restart_3


(6) ユーザの手を借りたテスト

ここで実施すること

Istioを部分的にアップグレードしたところで、アップグレードが完了したNamespaceをテストします。

ユーザーの手を借りて実地的にテストします (例:該当のエラーメトリクスが基準値を満たすか) 。

今の状況は以下の通りです👇

istio_canary-upgrade_rollout-restart_4

もし問題が起こった場合

もし問題が起こった場合、1-14-6にダウングレードしていきます。

istioctl tag setコマンドを実行し、istio.io/revラベルの値を元に戻します。

$ istioctl tag set default --revision 1-14-6 --overwrite

その後、kubectl rollout restartコマンドの手順を実行し、istio-proxyコンテナをダウングレードしてきます。


(7) istio-proxyコンテナの段階的アップグレード

ここで実施すること

先ほどのNamespaceで問題が起こらなければ、残ったNamespace (foobaz、...) のistio-proxyコンテナも段階的にアップグレードしていきます。

kubectl rollout restartコマンド

同様にkubectl rollout restartコマンドを実行し、istio-proxyコンテナからアップグレードします。

$ kubectl rollout restart deployment foo -n foo

$ kubectl rollout restart deployment baz -n baz

...

最終的に、全てのNamespacemのistio-proxyコンテナが新しくなります。

今の状況は以下の通りです👇

istio_canary-upgrade_rollout-restart_5


(8) 旧Istiodのアンインストール

ここで実施すること

最後に、旧Istiodのアンインストールします。

istioctl uninstallコマンド

istioctl uninstallコマンドを実行し、旧Istiodをアンインストールします。

$ istioctl uninstall --revision 1-14-6

✅ Uninstall complete

今の状況は以下の通りです👇

istio_canary-upgrade_rollout-restart_6

kubectl getコマンド

▼ IstiodのDeployment

kubectl getコマンドを実行し、istioctl uninstallコマンドで何をアンインストールしたのかを確認します👀

まずはIstiodのDeploymentを確認すると、1-14-6というDeploymentが無くなっています。

$ kubectl get deployment -n istio-system -l app=istiod

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
istiod-1-15-4   1/1     1            1           47s # 1-15-4

▼ Webhookの宛先のService

次に Webhookの宛先のServiceを確認すると、istiod-1-14-6というServiceが無くなっています。

$ kubectl get service -n istio-system -l app=istiod

NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                                 AGE
istiod-1-15-4   ClusterIP   10.104.186.250   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP   87s  # 1-15-4

▼ 宛先のServiceを決めるMutatingWebhookConfiguration

最後にMutatingWebhookConfigurationを確認すると、istio-sidecar-injector-1-14-6というMutatingWebhookConfigurationが無くなっています。

$ kubectl get mutatingwebhookconfigurations

NAME                            WEBHOOKS   AGE
istio-revision-tag-default      2          114s  # 次のカナリアアップグレードでも使用する
istio-sidecar-injector-1-15-4   2          2m16s

これで、新Istiodに完全に入れ替わったため、アップグレードは完了です。

今の状況は以下の通りです👇

istio_canary-upgrade_webhook_4


▶︎ アンインストールについて

実は、他にもアンインストールしているものがあるのですが、話をわかりやすくするために、今回は言及していません🙇🏻‍


06. おわりに

Istioを安全にアップグレードするカナリア方式とその仕組みをもりもり布教しました。

Istioへの愛が溢れてしまいました。

これからIstioを採用予定の方は、Istioを安全にアップグレードするために十分に準備しておくことをお勧めします👍


記事関連のおすすめ書籍