リモートクラスタに対する istioctl の設定

外部制御プレーンを持つメッシュで istioctl コマンドをサポートするためのプロキシサーバの使用。

2022年3月25日 | Frank Budinsky - IBM

外部制御プレーンまたはマルチクラスタ 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 ポッドを見つけて、それぞれを順番に呼び出し、結果を集約してからユーザーに返すことで実装されます。

CLI with local access to istiod pods
istiod ポッドへのローカルアクセスのある CLI

一方、リモートクラスタを使用する場合、istiod インスタンスはメッシュクラスタの外部で実行されており、メッシュユーザーからアクセスできないため、これは不可能です。インスタンスは、Kubernetes クラスタ上のポッドを使用してデプロイされていない可能性さえあります。

幸いなことに、istioctl はこの問題に対処するための設定オプションを提供しています。istiod インスタンスにアクセスできる外部プロキシサービスのアドレスを使用して istioctl を設定できます。着信リクエストをインスタンスの1つに委譲する通常のロードバランサーサービスとは異なり、このプロキシサービスは代わりにすべての istiod インスタンスに委譲し、応答を集約してから、結合された結果を返す必要があります。

外部プロキシサービスが実際にもう一方の Kubernetes クラスタ上で実行されている場合、プロキシ実装コードは、istioctl がプライマリクラスタの場合に実行する実装コードと非常によく似ています。つまり、実行中のすべての istiod ポッドを見つけて、それぞれを順番に呼び出し、結果を集約します。

CLI without local access to istiod pods
istiod ポッドへのローカルアクセスがない CLI

このような istioctl プロキシサーバーの実装を含む Istio エコシステムプロジェクトはこちらにあります。試してみるには、一方をもう一方のクラスタにインストールされた制御プレーンを使用してリモートクラスタとして設定された2つのクラスタが必要です。

リモートクラスタトポロジを使用した Istio のインストール

リモートクラスタで istioctl が機能することを示すために、まず外部制御プレーンインストール手順を使用して、別の外部クラスタで実行されている外部制御プレーンを持つ単一のリモートクラスタメッシュを設定します。

インストールが完了すると、リモート(メッシュ)クラスタと外部(制御プレーン)クラスタのコンテキスト名をそれぞれ含む、CTX_REMOTE_CLUSTERCTX_EXTERNAL_CLUSTER の2つの環境変数が設定されます。

メッシュ、つまりリモートクラスタ上で helloworldsleep のサンプルも実行されているはずです。

$ 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 インスタンスにアクセスする外部制御プレーンの横に実行されているプロキシサーバーに委譲するように設定されました。

この記事を共有する