シングルクラスタへの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
    
この情報は役に立ちましたか?
改善のための提案はありますか?

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