カナリアアップグレード

Istioのアップグレードは、まず新しいコントロールプレーンのカナリアデプロイメントを実行することで行うことができます。これにより、すべてのトラフィックを新しいバージョンに移行する前に、少数のワークロードでアップグレードの影響を監視できます。これはインプレースアップグレードを行うよりもはるかに安全であり、推奨されるアップグレード方法です。

Istioをインストールする際、revisionインストール設定を使用して、複数の独立したコントロールプレーンを同時にデプロイできます。新しいIstioバージョンのコントロールプレーンを、異なるrevision設定を使用して古いコントロールプレーンの隣にインストールすることで、アップグレードのカナリアバージョンを開始できます。各リビジョンは、独自のDeploymentServiceなどを持つ、完全なIstioコントロールプレーンの実装です。

アップグレード前

Istioをアップグレードする前に、istioctl x precheckコマンドを実行して、アップグレードが環境と互換性があることを確認することをお勧めします。

$ istioctl x precheck
✔ No issues found when checking the cluster. Istio is safe to install or upgrade! To get started, check out https://istio.dokyumento.jp/latest/docs/setup/getting-started/

コントロールプレーン

canaryという新しいリビジョンをインストールするには、revisionフィールドを次のように設定します。

$ istioctl install --set revision=canary

コマンドを実行すると、2つのコントロールプレーンのデプロイメントとサービスが並行して実行されます。

$ kubectl get pods -n istio-system -l app=istiod
NAME READY STATUS RESTARTS AGE istiod-1-23-1-bdf5948d5-htddg 1/1 Running 0 47s istiod-canary-84c8d4dcfb-skcfv 1/1 Running 0 25s
$ kubectl get svc -n istio-system -l app=istiod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istiod-1-23-1 ClusterIP 10.96.93.151 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 109s istiod-canary ClusterIP 10.104.186.250 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 87s

また、新しいリビジョンを含む2つのサイドカーインジェクター構成があることも確認できます。

$ kubectl get mutatingwebhookconfigurations
NAME WEBHOOKS AGE istio-sidecar-injector-1-23-1 2 2m16s istio-sidecar-injector-canary 2 114s

データプレーン

Istioゲートウェイのリビジョン固有のインスタンスを実行する方法を理解するには、ゲートウェイカナリアアップグレードを参照してください。この例では、default Istioプロファイルを使用しているため、Istioゲートウェイはリビジョン固有のインスタンスを実行しませんが、代わりに新しいコントロールプレーンリビジョンを使用するようにインプレースアップグレードされます。istio-ingressゲートウェイがcanaryリビジョンを使用していることを確認するには、次のコマンドを実行します。

$ istioctl proxy-status | grep "$(kubectl -n istio-system get pod -l app=istio-ingressgateway -o jsonpath='{.items..metadata.name}')" | awk -F '[[:space:]][[:space:]]+' '{print $8}'
istiod-canary-6956db645c-vwhsk

ただし、新しいリビジョンをインストールするだけでは、既存のサイドカープロキシには影響しません。これらをアップグレードするには、新しいistiod-canaryコントロールプレーンを指すように構成する必要があります。これは、名前空間ラベルistio.io/revに基づいてサイドカーインジェクション中に制御されます。

istio-injectionが有効になっている名前空間test-nsを作成します。test-ns名前空間に、サンプルのcurlポッドをデプロイします。

  1. 名前空間test-nsを作成します。

    $ kubectl create ns test-ns
  2. istio-injectionラベルを使用して名前空間にラベルを付けます。

    $ kubectl label namespace test-ns istio-injection=enabled
  3. test-ns名前空間にサンプルのcurlポッドを起動します。

    $ kubectl apply -n test-ns -f samples/curl/curl.yaml

名前空間test-nsをアップグレードするには、istio-injectionラベルを削除し、canaryリビジョンを指すようにistio.io/revラベルを追加します。istio-injectionラベルは、下位互換性のためにistio.io/revラベルよりも優先されるため、削除する必要があります。

$ kubectl label namespace test-ns istio-injection- istio.io/rev=canary

名前空間を更新した後、ポッドを再起動して再インジェクションをトリガーする必要があります。名前空間test-ns内のすべてのポッドを再起動する1つの方法は、次を使用することです。

$ kubectl rollout restart deployment -n test-ns

ポッドが再インジェクションされると、istiod-canaryコントロールプレーンを指すように構成されます。istioctl proxy-statusを使用してこれを確認できます。

$ istioctl proxy-status | grep "\.test-ns "

出力には、カナリアリビジョンを使用している名前空間下のすべてのポッドが表示されます。

安定版リビジョンラベル

新しいリビジョンに移動するときに名前空間を手動で再ラベル付けすると、手間がかかり、エラーが発生しやすくなります。リビジョンのタグはこの問題を解決します。リビジョンのタグは、リビジョンを指す安定した識別子であり、名前空間の再ラベル付けを回避するために使用できます。メッシュオペレーターは、名前空間の再ラベル付けを行う代わりに、タグを新しいリビジョンを指すように変更するだけで済みます。そのタグでラベル付けされたすべての名前空間は、同時に更新されます。

使用法

1-23-11-24-0の2つのリビジョンがインストールされたクラスターを考えます。クラスターオペレーターは、古い安定した1-23-1バージョンを指すリビジョンタグprod-stableと、新しい1-24-0リビジョンを指すリビジョンタグprod-canaryを作成します。この状態は、次のコマンドで到達できます。
  1. コントロールプレーンの2つのリビジョンをインストールします。

    $ istioctl install --revision=1-23-1 --set profile=minimal --skip-confirmation $ istioctl install --revision=1-24-0 --set profile=minimal --skip-confirmation
  2. stableおよびcanaryリビジョンタグを作成し、それぞれののリビジョンに関連付けます。

    $ istioctl tag set prod-stable --revision 1-23-1 $ istioctl tag set prod-canary --revision 1-24-0
  3. アプリケーション名前空間にラベルを付けて、それぞれののリビジョンタグにマップします。

    $ kubectl create ns app-ns-1 $ kubectl label ns app-ns-1 istio.io/rev=prod-stable $ kubectl create ns app-ns-2 $ kubectl label ns app-ns-2 istio.io/rev=prod-stable $ kubectl create ns app-ns-3 $ kubectl label ns app-ns-3 istio.io/rev=prod-canary
  4. 各名前空間でサンプルのcurlポッドを起動します。

    $ kubectl apply -n app-ns-1 -f samples/curl/curl.yaml $ kubectl apply -n app-ns-2 -f samples/curl/curl.yaml $ kubectl apply -n app-ns-3 -f samples/curl/curl.yaml
  5. istioctl proxy-statusコマンドを使用して、アプリケーションとコントロールプレーンのマッピングを確認します。

    $ istioctl ps
    NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION curl-78ff5975c6-62pzf.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-24-0-7f6fc6cfd6-s8zfg 1.24.0 curl-78ff5975c6-8kxpl.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-1-bdf5948d5-n72r2 1.23.1 curl-78ff5975c6-8q7m6.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-23-1-bdf5948d5-n72r2 1-23.1

リビジョン、タグ、名前空間間の結果のマッピングを以下に示します。

Two namespaces pointed to prod-stable and one pointed to prod-canary
prod-stableを指す2つの名前空間と、prod-canaryを指す1つの名前空間

クラスターオペレーターは、istioctl tag listコマンドを使用して、タグ付けされた名前空間に加えてこのマッピングを表示できます。

$ istioctl tag list
TAG REVISION NAMESPACES default 1-23-1 ... prod-canary 1-24-0 ... prod-stable 1-23-1 ...

クラスターオペレーターがprod-canaryでタグ付けされたコントロールプレーンの安定性に満足したら、istio.io/rev=prod-stableでラベル付けされた名前空間は、prod-stableリビジョンタグを新しい1-24-0リビジョンを指すように変更することで、1つのアクションで更新できます。

$ istioctl tag set prod-stable --revision 1-24-0 --overwrite

これで、リビジョン、タグ、名前空間間の更新されたマッピングは以下のようになります。

Namespace labels unchanged but now all namespaces pointed to {{< istio_full_version_revision >}}
名前空間ラベルは変更されていませんが、すべての名前空間が{{< istio_full_version_revision >}}を指すようになりました。

prod-stableとマークされた名前空間でインジェクションされたワークロードを再起動すると、これらのワークロードは1-24-0コントロールプレーンを使用するようになります。ワークロードを新しいリビジョンに移行するために名前空間の再ラベル付けは必要なかったことに注意してください。

$ kubectl rollout restart deployment -n app-ns-1 $ kubectl rollout restart deployment -n app-ns-2

istioctl proxy-statusコマンドを使用して、アプリケーションとコントロールプレーンのマッピングを確認します。

$ istioctl ps
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION curl-5984f48bc7-kmj6x.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-24-0-7f6fc6cfd6-jsktb 1.24.0 curl-78ff5975c6-jldk4.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-24-0-7f6fc6cfd6-jsktb 1.24.0 curl-7cdd8dccb9-5bq5n.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-1-24-0-7f6fc6cfd6-jsktb 1.24.0

デフォルトタグ

タグdefaultによって指されるリビジョンは、デフォルトリビジョンと見なされ、追加の意味的な意味を持ちます。デフォルトリビジョンは、次の機能を実行します。

  • istio-injection=enabledの名前空間セレクター、sidecar.istio.io/inject=trueオブジェクトセレクター、およびistio.io/rev=defaultセレクターのサイドカーをインジェクションします。
  • Istioリソースを検証します。
  • デフォルト以外のリビジョンからリーダロックを奪い、シングルトンメッシュの役割(リソースステータスの更新など)を実行します。

リビジョン1-24-0をデフォルトにするには、次を実行します。

$ istioctl tag set default --revision 1-24-0
既存のリビジョンされていないIstioインストールと一緒にdefaultタグを使用する場合、古いMutatingWebhookConfiguration(通常はistio-sidecar-injectorと呼ばれます)を削除して、古いコントロールプレーンと新しいコントロールプレーンの両方がインジェクションを試行しないようにすることをお勧めします。

古いコントロールプレーンのアンインストール

コントロールプレーンとデータプレーンの両方をアップグレードしたら、古いコントロールプレーンをアンインストールできます。たとえば、次のコマンドはリビジョン1-23-1のコントロールプレーンをアンインストールします。

$ istioctl uninstall --revision 1-23-1 -y

古いコントロールプレーンにリビジョンラベルがない場合は、元のインストールオプションを使用してアンインストールします。例:

$ istioctl uninstall -f manifests/profiles/default.yaml -y

古いコントロールプレーンが削除され、新しいコントロールプレーンのみがクラスターに存在することを確認します。

$ kubectl get pods -n istio-system -l app=istiod
NAME READY STATUS RESTARTS AGE istiod-canary-55887f699c-t8bh8 1/1 Running 0 27m

上記の指示では、指定されたコントロールプレーンリビジョンのリソースのみが削除され、他のコントロールプレーンと共有されるクラスターレベルのリソースは削除されないことに注意してください。Istioを完全にアンインストールするには、アンインストールガイドを参照してください。

カナリアコントロールプレーンのアンインストール

カナリアアップグレードを完了する代わりに、古いコントロールプレーンにロールバックする場合は、次のコマンドを使用してカナリアリビジョンをアンインストールできます。

$ istioctl uninstall --revision=canary -y

ただし、この場合は、以前にインプレースアップグレードされたゲートウェイを、アンインストールコマンドでは自動的に元に戻らないため、最初に手動で再インストールする必要があります。

クリーンアップ

  1. 作成したリビジョンのタグをクリーンアップします。

    $ istioctl tag remove prod-stable $ istioctl tag remove prod-canary
  2. リビジョンラベルの例を使用して、カナリアアップグレードに使用した名前空間をクリーンアップします。

    $ kubectl delete ns istio-system test-ns
  3. リビジョンタグの例を使用して、カナリアアップグレードに使用した名前空間をクリーンアップします。

    $ kubectl delete ns istio-system app-ns-1 app-ns-2 app-ns-3
この情報は役に立ちましたか?
改善のためのご提案はありますか?

フィードバックありがとうございます!