リモートクラスタに対する istioctl の設定
外部制御プレーンを持つメッシュで istioctl コマンドをサポートするためのプロキシサーバの使用。
外部制御プレーンまたはマルチクラスタ Istio デプロイメントのリモートクラスタで istioctl
CLI を使用する場合、一部のコマンドはデフォルトでは動作しません。たとえば、istioctl proxy-status
は、管理しているプロキシのステータスと設定を取得するために istiod
サービスへのアクセスが必要です。リモートクラスタで実行しようとすると、次のようなエラーメッセージが表示されます。
$ istioctl proxy-status
Error: unable to find any Istiod instances
エラーメッセージは、istiod
サービスにアクセスできないと言っているだけでなく、具体的に istiod
インスタンスが見つからないことを示しています。これは、istioctl proxy-status
の実装が、単一の istiod
インスタンスだけでなく、すべての istiod
インスタンスの同期ステータスを取得する必要があるためです。複数の istiod
インスタンス(レプリカ)が実行されている場合、各インスタンスはメッシュで実行されているサービスプロキシのサブセットのみに接続されます。istioctl
コマンドは、1つのインスタンスによって管理されるサブセットだけでなく、メッシュ全体のステータスを返す必要があります。
istiod
サービスがクラスタ上でローカルに実行されている通常の Istio インストール(つまり、プライマリクラスタ)では、コマンドは、実行中のすべての istiod
ポッドを見つけて、それぞれを順番に呼び出し、結果を集約してからユーザーに返すことで実装されます。
一方、リモートクラスタを使用する場合、istiod
インスタンスはメッシュクラスタの外部で実行されており、メッシュユーザーからアクセスできないため、これは不可能です。インスタンスは、Kubernetes クラスタ上のポッドを使用してデプロイされていない可能性さえあります。
幸いなことに、istioctl
はこの問題に対処するための設定オプションを提供しています。istiod
インスタンスにアクセスできる外部プロキシサービスのアドレスを使用して istioctl
を設定できます。着信リクエストをインスタンスの1つに委譲する通常のロードバランサーサービスとは異なり、このプロキシサービスは代わりにすべての istiod
インスタンスに委譲し、応答を集約してから、結合された結果を返す必要があります。
外部プロキシサービスが実際にもう一方の Kubernetes クラスタ上で実行されている場合、プロキシ実装コードは、istioctl
がプライマリクラスタの場合に実行する実装コードと非常によく似ています。つまり、実行中のすべての istiod
ポッドを見つけて、それぞれを順番に呼び出し、結果を集約します。
このような istioctl
プロキシサーバーの実装を含む Istio エコシステムプロジェクトはこちらにあります。試してみるには、一方をもう一方のクラスタにインストールされた制御プレーンを使用してリモートクラスタとして設定された2つのクラスタが必要です。
リモートクラスタトポロジを使用した Istio のインストール
リモートクラスタで istioctl
が機能することを示すために、まず外部制御プレーンインストール手順を使用して、別の外部クラスタで実行されている外部制御プレーンを持つ単一のリモートクラスタメッシュを設定します。
インストールが完了すると、リモート(メッシュ)クラスタと外部(制御プレーン)クラスタのコンテキスト名をそれぞれ含む、CTX_REMOTE_CLUSTER
と CTX_EXTERNAL_CLUSTER
の2つの環境変数が設定されます。
メッシュ、つまりリモートクラスタ上で helloworld
と sleep
のサンプルも実行されているはずです。
$ kubectl get pod -n sample --context="${CTX_REMOTE_CLUSTER}"
NAME READY STATUS RESTARTS AGE
helloworld-v1-776f57d5f6-tmpkd 2/2 Running 0 10s
sleep-557747455f-v627d 2/2 Running 0 9s
リモートクラスタで istioctl proxy-status
を実行しようとすると、先に説明したエラーメッセージが表示されることに注意してください。
$ istioctl proxy-status --context="${CTX_REMOTE_CLUSTER}"
Error: unable to find any Istiod instances
サンプルプロキシサービスを使用するように istioctl を設定する
istioctl
を設定するには、まず実行中の istiod
ポッドの横にプロキシサービスをデプロイする必要があります。インストールでは、制御プレーンを external-istiod
名前空間でデプロイしているので、次のコマンドを使用して外部クラスタでプロキシサービスを開始します。
$ kubectl apply -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}" \
-f https://raw.githubusercontent.com/istio-ecosystem/istioctl-proxy-sample/main/istioctl-proxy.yaml
service/istioctl-proxy created
serviceaccount/istioctl-proxy created
secret/jwt-cert-key-secret created
deployment.apps/istioctl-proxy created
role.rbac.authorization.k8s.io/istioctl-proxy-role created
rolebinding.rbac.authorization.k8s.io/istioctl-proxy-role created
次のコマンドを実行して、istioctl-proxy
サービスが istiod
の横に実行されていることを確認できます。
$ kubectl get po -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}"
NAME READY STATUS RESTARTS AGE
istioctl-proxy-664bcc596f-9q8px 1/1 Running 0 15s
istiod-666fb6694d-jklkt 1/1 Running 0 5m31s
プロキシサービスは、ポート9090でサービスを提供している gRPC サーバーです。
$ kubectl get svc istioctl-proxy -n external-istiod --context="${CTX_EXTERNAL_CLUSTER}"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istioctl-proxy ClusterIP 172.21.127.192 <none> 9090/TCP 11m
ただし、使用するには、外部クラスタの外側に公開する必要があります。デプロイメント環境に応じて、これを行う方法はたくさんあります。私たちのセットアップでは、外部クラスタでイングレスゲートウェイが実行されているため、ポート9090も公開するように更新し、関連付けられた仮想サービスを更新してポート9090のリクエストをプロキシサービスに転送し、次にistioctl
をゲートウェイアドレスを使用するように設定できます。これが「適切な」アプローチです。
ただし、これは両方のクラスタにアクセスできる簡単なデモなので、プロキシサービスをlocalhost
にポートフォワード
するだけです。
$ kubectl port-forward -n external-istiod service/istioctl-proxy 9090:9090 --context="${CTX_EXTERNAL_CLUSTER}"
これで、ISTIOCTL_XDS_ADDRESS
環境変数を設定して、localhost:9090
を使用するように istioctl
を設定します。
$ export ISTIOCTL_XDS_ADDRESS=localhost:9090
$ export ISTIOCTL_ISTIONAMESPACE=external-istiod
$ export ISTIOCTL_PREFER_EXPERIMENTAL=true
制御プレーンはデフォルトの istio-system
ではなく external-istiod
名前空間で実行されているため、ISTIOCTL_ISTIONAMESPACE
環境変数も設定する必要があります。
ISTIOCTL_PREFER_EXPERIMENTAL
の設定はオプションです。これは、安定版と実験版の両方の実装を持つコマンドに対して、istioctl command
呼び出しを実験的な同等物である istioctl x command
にリダイレクトするように istioctl
に指示します。この場合、プロキシ委任機能を実装するバージョンである istioctl x proxy-status
を使用する必要があります。
istioctl proxy-status コマンドを実行する
istioctl
の設定が完了したので、proxy-status
コマンドを再度実行して試すことができます。
$ istioctl proxy-status --context="${CTX_REMOTE_CLUSTER}"
NAME CDS LDS EDS RDS ISTIOD VERSION
helloworld-v1-776f57d5f6-tmpkd.sample SYNCED SYNCED SYNCED SYNCED <external> 1.12.1
istio-ingressgateway-75bfd5668f-lggn4.external-istiod SYNCED SYNCED SYNCED SYNCED <external> 1.12.1
sleep-557747455f-v627d.sample SYNCED SYNCED SYNCED SYNCED <external> 1.12.1
ご覧のとおり、今回はメッシュで実行されているすべてのサービスの同期ステータスが正しく表示されます。ISTIOD
列は、ポッドがローカルで実行されている場合に表示されるインスタンス名(例:istiod-666fb6694d-jklkt
)ではなく、一般的な値 <external>
を返します。この場合、この詳細は、メッシュユーザーが利用可能でも必要でもありません。メッシュオペレーターが確認できるのは外部クラスタ上のみです。
まとめ
この記事では、サンプルプロキシサーバーを使用して、istioctl
を外部制御プレーンインストールで動作するように設定しました。一部の istioctl
CLI コマンドは、外部制御プレーンによって管理されているリモートクラスタではすぐに動作しないことがわかりました。istioctl proxy-status
などの一部のコマンドは、メッシュを管理している istiod
サービスインスタンスへのアクセスを必要としますが、制御プレーンがメッシュクラスタの外部で実行されている場合、これらは利用できません。この問題に対処するために、istioctl
は、代わりに istiod
インスタンスにアクセスする外部制御プレーンの横に実行されているプロキシサーバーに委譲するように設定されました。