シングルクラスタへのIstioコントロールプレーンの複数インストール

このガイドでは、シングルクラスタ内に複数のIstioコントロールプレーンをインストールし、ワークロードを特定のコントロールプレーンにスコープする方法について説明します。このデプロイモデルでは、複数のIstioコントロールプレーンとメッシュを持つ単一のKubernetesコントロールプレーンを使用します。メッシュ間の分離は、Kubernetes名前空間とRBACによって提供されます。

Multiple meshes in a single cluster
シングルクラスタ内の複数のメッシュ

discoverySelectorsを使用すると、Istioコントロールプレーンによって管理される特定のネームスペースに、クラスタ内のKubernetesリソースのスコープを限定できます。これには、メッシュの構成に使用されるIstioカスタムリソース(例:Gateway、VirtualService、DestinationRuleなど)も含まれます。さらに、discoverySelectorsを使用して、特定のIstioコントロールプレーンに対して、どのネームスペースにistio-ca-root-cert config mapを含めるべきかを構成できます。これらの機能を組み合わせることで、メッシュオペレータは特定のコントロールプレーンに対するネームスペースを指定でき、1つ以上のネームスペースの境界に基づいて、複数のメッシュのソフトマルチテナント化が可能になります。このガイドでは、Istioのリビジョン機能とともにdiscoverySelectorsを使用して、各々がクラスタのリソースの適切なサブセットで動作する2つのメッシュを単一クラスタにデプロイする方法を説明します。

始める前に

このガイドでは、以下のいずれかのサポートされているKubernetesバージョン:1.28、1.29、1.30、1.31を搭載したKubernetesクラスタが必要です。

このクラスタには、2つの異なるシステムネームスペースにインストールされた2つのコントロールプレーンがホストされます。メッシュアプリケーションのワークロードは、複数のアプリケーション固有のネームスペースで実行され、各ネームスペースは、リビジョンとディスカバリセレクタの構成に基づいて、一方またはもう一方のコントロールプレーンに関連付けられます。

クラスタ設定

複数コントロールプレーンのデプロイ

単一クラスタへの複数Istioコントロールプレーンのデプロイは、各コントロールプレーンに異なるシステムネームスペースを使用することで実現できます。IstioのリビジョンとdiscoverySelectorsを使用して、各コントロールプレーンによって管理されるリソースとワークロードのスコープを限定します。

  1. 最初のシステムネームスペースusergroup-1を作成し、そこにistiodをデプロイします。

    $ kubectl create ns usergroup-1 $ kubectl label ns usergroup-1 usergroup=usergroup-1 $ istioctl install -y -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: usergroup-1 spec: profile: minimal revision: usergroup-1 meshConfig: discoverySelectors: - matchLabels: usergroup: usergroup-1 values: global: istioNamespace: usergroup-1 EOF
  2. 2番目のシステムネームスペースusergroup-2を作成し、そこにistiodをデプロイします。

    $ kubectl create ns usergroup-2 $ kubectl label ns usergroup-2 usergroup=usergroup-2 $ istioctl install -y -f - <<EOF apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: usergroup-2 spec: profile: minimal revision: usergroup-2 meshConfig: discoverySelectors: - matchLabels: usergroup: usergroup-2 values: global: istioNamespace: usergroup-2 EOF
  3. usergroup-1ネームスペース内のワークロードが相互TLSトラフィックのみを受け入れるように、ポリシーをデプロイします。

    $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: "usergroup-1-peerauth" namespace: "usergroup-1" spec: mtls: mode: STRICT EOF
  4. usergroup-2ネームスペース内のワークロードが相互TLSトラフィックのみを受け入れるように、ポリシーをデプロイします。

    $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: "usergroup-2-peerauth" namespace: "usergroup-2" spec: mtls: mode: STRICT EOF

複数コントロールプレーンの作成の検証

  1. 各コントロールプレーンのシステムネームスペースのラベルを確認します。

    $ kubectl get ns usergroup-1 usergroup2 --show-labels
    NAME STATUS AGE LABELS usergroup-1 Active 13m kubernetes.io/metadata.name=usergroup-1,usergroup=usergroup-1 usergroup-2 Active 12m kubernetes.io/metadata.name=usergroup-2,usergroup=usergroup-2
  2. コントロールプレーンがデプロイされ、実行されていることを確認します。

    $ kubectl get pods -n usergroup-1
    NAMESPACE NAME READY STATUS RESTARTS AGE usergroup-1 istiod-usergroup-1-5ccc849b5f-wnqd6 1/1 Running 0 12m
    $ kubectl get pods -n usergroup-2
    NAMESPACE NAME READY STATUS RESTARTS AGE usergroup-2 istiod-usergroup-2-658d6458f7-slpd9 1/1 Running 0 12m

    ユーザーグループごとに1つのistiodデプロイメントが指定されたネームスペースに作成されていることに気付くでしょう。

  3. インストール済みのWebhookを一覧表示するには、次のコマンドを実行します。

    $ kubectl get validatingwebhookconfiguration
    NAME WEBHOOKS AGE istio-validator-usergroup-1-usergroup-1 1 18m istio-validator-usergroup-2-usergroup-2 1 18m istiod-default-validator 1 18m
    $ kubectl get mutatingwebhookconfiguration
    NAME WEBHOOKS AGE istio-revision-tag-default-usergroup-1 4 18m istio-sidecar-injector-usergroup-1-usergroup-1 2 19m istio-sidecar-injector-usergroup-2-usergroup-2 2 18m

    出力には、istiod-default-validatoristio-revision-tag-default-usergroup-1が含まれています。これらは、リビジョンに関連付けられていないリソースからのリクエストを処理するために使用されるデフォルトのWebhook構成です。すべてのコントロールプレーンが適切なネームスペースのラベル付けを通じてリソースに関連付けられている完全にスコープされた環境では、これらのデフォルトのWebhook構成は必要ありません。これらは呼び出されるべきではありません。

ユーザーグループごとのアプリケーションワークロードのデプロイ

  1. 3つのアプリケーションネームスペースを作成します。

    $ kubectl create ns app-ns-1 $ kubectl create ns app-ns-2 $ kubectl create ns app-ns-3
  2. 各ネームスペースにラベルを付け、それぞれのコントロールプレーンに関連付けます。

    $ kubectl label ns app-ns-1 usergroup=usergroup-1 istio.io/rev=usergroup-1 $ kubectl label ns app-ns-2 usergroup=usergroup-2 istio.io/rev=usergroup-2 $ kubectl label ns app-ns-3 usergroup=usergroup-2 istio.io/rev=usergroup-2
  3. ネームスペースごとに1つのcurlhttpbinアプリケーションをデプロイします。

    $ kubectl -n app-ns-1 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-1 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-2 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-2 apply -f samples/httpbin/httpbin.yaml $ kubectl -n app-ns-3 apply -f samples/curl/curl.yaml $ kubectl -n app-ns-3 apply -f samples/httpbin/httpbin.yaml
  4. サイドアカーが注入された状態でhttpbincurlポッドが実行されるまで、数秒間待ちます。

    $ kubectl get pods -n app-ns-1
    NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-zc2v4 2/2 Running 0 115m curl-78ff5975c6-fml7c 2/2 Running 0 115m
    $ kubectl get pods -n app-ns-2
    NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-sd9ln 2/2 Running 0 115m curl-78ff5975c6-sz728 2/2 Running 0 115m
    $ kubectl get pods -n app-ns-3
    NAME READY STATUS RESTARTS AGE httpbin-9dbd644c7-8ll27 2/2 Running 0 115m curl-78ff5975c6-sg4tq 2/2 Running 0 115m

アプリケーションとコントロールプレーンのマッピングの検証

アプリケーションがデプロイされたので、istioctl psコマンドを使用して、アプリケーションワークロードがそれぞれのコントロールプレーンによって管理されていることを確認できます(つまり、app-ns-1usergroup-1によって、app-ns-2app-ns-3usergroup-2によって管理されています)。

$ istioctl ps -i usergroup-1
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION httpbin-9dbd644c7-hccpf.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-1-5ccc849b5f-wnqd6 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117 curl-78ff5975c6-9zb77.app-ns-1 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-1-5ccc849b5f-wnqd6 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117
$ istioctl ps -i usergroup-2
NAME CLUSTER CDS LDS EDS RDS ECDS ISTIOD VERSION httpbin-9dbd644c7-vvcqj.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117 httpbin-9dbd644c7-xzgfm.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117 curl-78ff5975c6-fthmt.app-ns-2 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117 curl-78ff5975c6-nxtth.app-ns-3 Kubernetes SYNCED SYNCED SYNCED SYNCED NOT SENT istiod-usergroup-2-658d6458f7-slpd9 1.17-alpha.f5212a6f7df61fd8156f3585154bed2f003c4117

アプリケーションの接続がそれぞれのユーザーグループ内でのみ行われることの検証

  1. usergroup-1app-ns-1内のcurlポッドから、usergroup-2app-ns-2内のhttpbinサービスへのリクエストを送信します。通信は失敗するはずです。

    $ kubectl -n app-ns-1 exec "$(kubectl -n app-ns-1 get pod -l app=curl -o jsonpath={.items..metadata.name})" -c curl -- curl -sIL http://httpbin.app-ns-2.svc.cluster.local:8000
    HTTP/1.1 503 Service Unavailable content-length: 95 content-type: text/plain date: Sat, 24 Dec 2022 06:54:54 GMT server: envoy
  2. usergroup-2app-ns-2内のcurlポッドから、usergroup-2app-ns-3内のhttpbinサービスへのリクエストを送信します。通信は成功するはずです。

    $ kubectl -n app-ns-2 exec "$(kubectl -n app-ns-2 get pod -l app=curl -o jsonpath={.items..metadata.name})" -c curl -- curl -sIL http://httpbin.app-ns-3.svc.cluster.local:8000
    HTTP/1.1 200 OK server: envoy date: Thu, 22 Dec 2022 15:01:36 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 3

クリーンアップ

  1. 最初のユーザーグループをクリーンアップします。

    $ istioctl uninstall --revision usergroup-1 --set values.global.istioNamespace=usergroup-1 $ kubectl delete ns app-ns-1 usergroup-1
  2. 2番目のユーザーグループをクリーンアップします。

    $ istioctl uninstall --revision usergroup-2 --set values.global.istioNamespace=usergroup-2 $ kubectl delete ns app-ns-2 app-ns-3 usergroup-2
この情報は役に立ちましたか?
改善のための提案はありますか?

ご意見ありがとうございます!