カナリアアップグレード
Istioのアップグレードは、まず新しいコントロールプレーンのカナリアデプロイメントを実行することで行うことができます。これにより、すべてのトラフィックを新しいバージョンに移行する前に、少数のワークロードでアップグレードの影響を監視できます。これはインプレースアップグレードを行うよりもはるかに安全であり、推奨されるアップグレード方法です。
Istioをインストールする際、revision
インストール設定を使用して、複数の独立したコントロールプレーンを同時にデプロイできます。新しいIstioバージョンのコントロールプレーンを、異なるrevision
設定を使用して古いコントロールプレーンの隣にインストールすることで、アップグレードのカナリアバージョンを開始できます。各リビジョンは、独自のDeployment
、Service
などを持つ、完全な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ポッドをデプロイします。
名前空間
test-ns
を作成します。$ kubectl create ns test-ns
istio-injection
ラベルを使用して名前空間にラベルを付けます。$ kubectl label namespace test-ns istio-injection=enabled
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-1
と1-24-0
の2つのリビジョンがインストールされたクラスターを考えます。クラスターオペレーターは、古い安定した1-23-1
バージョンを指すリビジョンタグprod-stable
と、新しい1-24-0
リビジョンを指すリビジョンタグprod-canary
を作成します。この状態は、次のコマンドで到達できます。コントロールプレーンの2つのリビジョンをインストールします。
$ istioctl install --revision=1-23-1 --set profile=minimal --skip-confirmation $ istioctl install --revision=1-24-0 --set profile=minimal --skip-confirmation
stable
およびcanary
リビジョンタグを作成し、それぞれののリビジョンに関連付けます。$ istioctl tag set prod-stable --revision 1-23-1 $ istioctl tag set prod-canary --revision 1-24-0
アプリケーション名前空間にラベルを付けて、それぞれののリビジョンタグにマップします。
$ 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
各名前空間でサンプルの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
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
リビジョン、タグ、名前空間間の結果のマッピングを以下に示します。
クラスターオペレーターは、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
これで、リビジョン、タグ、名前空間間の更新されたマッピングは以下のようになります。
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
ただし、この場合は、以前にインプレースアップグレードされたゲートウェイを、アンインストールコマンドでは自動的に元に戻らないため、最初に手動で再インストールする必要があります。
クリーンアップ
作成したリビジョンのタグをクリーンアップします。
$ istioctl tag remove prod-stable $ istioctl tag remove prod-canary
リビジョンラベルの例を使用して、カナリアアップグレードに使用した名前空間をクリーンアップします。
$ kubectl delete ns istio-system test-ns
リビジョンタグの例を使用して、カナリアアップグレードに使用した名前空間をクリーンアップします。
$ kubectl delete ns istio-system app-ns-1 app-ns-2 app-ns-3