第8章 外部コントロールプレーントポロジー
外部コントロールプレーントポロジーは、コントロールプレーンを別のクラスター上のデータプレーンから分離するために使用します。
8.1. 外部コントロールプレーントポロジーについて リンクのコピーリンクがクリップボードにコピーされました!
外部コントロールプレーントポロジーを使用すると、セキュリティーが向上し、Service Mesh をサービスとしてホストできます。このインストール設定では、1 つのクラスターが Istio コントロールプレーンをホストおよび管理します。アプリケーションは他のクラスターでホストされます。
8.1.1. コントロールプレーンとデータプレーンを別々のクラスターにインストールする リンクのコピーリンクがクリップボードにコピーされました!
コントロールプレーンクラスターと、個別のデータプレーンクラスターに Istio をインストールします。このインストール方法により、セキュリティーが強化されます。
この手順は、複数のデータプレーンクラスターにまたがるメッシュに適用できます。この手順は、同じコントロールプレーンクラスター上に複数のコントロールプレーンを持つ複数のメッシュにも適用できます。
前提条件
- コントロールプレーンクラスターとデータプレーンクラスターに OpenShift Service Mesh Operator をインストールした。
-
この手順を実行するために使用するノートパソコンに
istioctlをインストールした。
手順
次のコマンドを実行して、すべてのクラスターにインストールする Istio のバージョンを定義する
ISTIO_VERSION環境変数を作成します。$ export ISTIO_VERSION=1.24.3次のコマンドを実行して、クラスターの名前を定義する
REMOTE_CLUSTER_NAME環境変数を作成します。$ export REMOTE_CLUSTER_NAME=cluster1次のコマンドを実行して、コントロールプレーンクラスター用の
ocコマンドコンテキストを含む環境変数を設定します。$ export CTX_CONTROL_PLANE_CLUSTER=<context_name_of_the_control_plane_cluster>次のコマンドを実行して、データプレーンクラスター用の
ocコマンドコンテキストを含む環境変数を設定します。$ export CTX_DATA_PLANE_CLUSTER=<context_name_of_the_data_plane_cluster>コントロールプレーンの Ingress ゲートウェイを設定します。
次のコマンドを実行して、
istio-systemというプロジェクトを作成します。$ oc get project istio-system --context "${CTX_CONTROL_PLANE_CLUSTER}" || oc new-project istio-system --context "${CTX_CONTROL_PLANE_CLUSTER}"次のコマンドを実行して、Ingress ゲートウェイを管理するための
Istioリソースをコントロールプレーンクラスターに作成します。$ cat <<EOF | oc --context "${CTX_CONTROL_PLANE_CLUSTER}" apply -f - apiVersion: sailoperator.io/v1 kind: Istio metadata: name: default spec: version: v${ISTIO_VERSION} namespace: istio-system value: global: network: network1 EOF次のコマンドを実行して、コントロールプレーンの Ingress ゲートウェイを作成します。
$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" apply -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/deployment-models/resources/controlplane-gateway.yaml次のコマンドを実行して、Ingress ゲートウェイに割り当てられた IP アドレスを取得します。
$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}'次のコマンドを実行して、Ingress ゲートウェイの IP アドレスを環境変数に保存します。
$ export EXTERNAL_ISTIOD_ADDR=$(oc -n istio-system --context="${CTX_CONTROL_PLANE_CLUSTER}" get svc istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
データプレーンクラスターに Istio をインストールします。
次のコマンドを実行して、データプレーンクラスターに
external-istiodというプロジェクトを作成します。$ oc get project external-istiod --context "${CTX_DATA_PLANE_CLUSTER}" || oc new-project external-istiod --context "${CTX_DATA_PLANE_CLUSTER}"次のコマンドを実行して、データプレーンクラスターに
Istioリソースを作成します。$ cat <<EOF | oc --context "${CTX_DATA_PLANE_CLUSTER}" apply -f - apiVersion: sailoperator.io/v1 kind: Istio metadata: name: external-istiod spec: version: v${ISTIO_VERSION} namespace: external-istiod profile: remote values: defaultRevision: external-istiod global: remotePilotAddress: ${EXTERNAL_ISTIOD_ADDR} configCluster: true1 pilot: configMap: true istiodRemote: injectionPath: /inject/cluster/cluster2/net/network1 EOF- 1
- この設定は、データプレーンクラスターをメッシュ設定のソースとして指定するものです。
次のコマンドを実行して、データプレーンクラスターに
istio-cniというプロジェクトを作成します。$ oc get project istio-cni --context "${CTX_DATA_PLANE_CLUSTER}" || oc new-project istio-cni --context "${CTX_DATA_PLANE_CLUSTER}"次のコマンドを実行して、データプレーンクラスターに
IstioCNIリソースを作成します。$ cat <<EOF | oc --context "${CTX_DATA_PLANE_CLUSTER}" apply -f - apiVersion: sailoperator.io/v1 kind: IstioCNI metadata: name: default spec: version: v${ISTIO_VERSION} namespace: istio-cni EOF
コントロールプレーンクラスターに外部 Istio コントロールプレーンを設定します。
次のコマンドを実行して、コントロールプレーンクラスターに
external-istiodというプロジェクトを作成します。$ oc get project external-istiod --context "${CTX_CONTROL_PLANE_CLUSTER}" || oc new-project external-istiod --context "${CTX_CONTROL_PLANE_CLUSTER}"次のコマンドを実行して、コントロールプレーンクラスターに
ServiceAccountリソースを作成します。$ oc --context="${CTX_CONTROL_PLANE_CLUSTER}" create serviceaccount istiod-service-account -n external-istiod次のコマンドを実行して、データプレーンクラスターの API サーバーアドレスを環境変数に保存します。
$ DATA_PLANE_API_SERVER=https://<hostname_or_IP_address_of_the_API_server_for_the_data_plane_cluster>:6443次のコマンドを実行して、データプレーンクラスターの API サーバーへのアクセスを提供するリモートシークレットを、コントロールプレーンクラスターにインストールします。
$ istioctl create-remote-secret \ --context="${CTX_DATA_PLANE_CLUSTER}" \ --type=config \ --namespace=external-istiod \ --service-account=istiod-external-istiod \ --create-service-account=false \ --server="${DATA_PLANE_API_SERVER}" | \ oc --context="${CTX_CONTROL_PLANE_CLUSTER}" apply -f -次のコマンドを実行して、コントロールプレーンクラスターに
Istioリソースを作成します。$ cat <<EOF | oc --context "${CTX_CONTROL_PLANE_CLUSTER}" apply -f - apiVersion: sailoperator.io/v1 kind: Istio metadata: name: external-istiod spec: version: v${ISTIO_VERSION} namespace: external-istiod profile: empty values: meshConfig: rootNamespace: external-istiod defaultConfig: discoveryAddress: $EXTERNAL_ISTIOD_ADDR:15012 pilot: enabled: true volumes: - name: config-volume configMap: name: istio-external-istiod - name: inject-volume configMap: name: istio-sidecar-injector-external-istiod volumeMounts: - name: config-volume mountPath: /etc/istio/config - name: inject-volume mountPath: /var/lib/istio/inject env: INJECTION_WEBHOOK_CONFIG_NAME: "istio-sidecar-injector-external-istiod-external-istiod" VALIDATION_WEBHOOK_CONFIG_NAME: "istio-validator-external-istiod-external-istiod" EXTERNAL_ISTIOD: "true" LOCAL_CLUSTER_SECRET_WATCHER: "true" CLUSTER_ID: cluster2 SHARED_MESH_CONFIG: istio global: caAddress: $EXTERNAL_ISTIOD_ADDR:15012 configValidation: false meshID: mesh1 multiCluster: clusterName: cluster2 network: network1 EOF次のコマンドを実行して、データプレーンクラスター上のサイドカープロキシーがコントロールプレーンにアクセスできるように、
GatewayおよびVirtualServiceリソースを作成します。$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" apply -f - <<EOF apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: external-istiod-gw namespace: external-istiod spec: selector: istio: ingressgateway servers: - port: number: 15012 protocol: tls name: tls-XDS tls: mode: PASSTHROUGH hosts: - "*" - port: number: 15017 protocol: tls name: tls-WEBHOOK tls: mode: PASSTHROUGH hosts: - "*" --- apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: external-istiod-vs namespace: external-istiod spec: hosts: - "*" gateways: - external-istiod-gw tls: - match: - port: 15012 sniHosts: - "*" route: - destination: host: istiod-external-istiod.external-istiod.svc.cluster.local port: number: 15012 - match: - port: 15017 sniHosts: - "*" route: - destination: host: istiod-external-istiod.external-istiod.svc.cluster.local port: number: 443 EOF次のコマンドを実行して、コントロールプレーンクラスター上の
external-istiodIstioリソースが "Ready" ステータス条件を返すまで待ちます。$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" wait --for condition=Ready istio/external-istiod --timeout=3m次のコマンドを実行して、データプレーンクラスター上の
Istioリソースが "Ready" ステータス条件を返すまで待ちます。$ oc --context "${CTX_DATA_PLANE_CLUSTER}" wait --for condition=Ready istio/external-istiod --timeout=3m次のコマンドを実行して、データプレーンクラスター上の
IstioCNIリソースが "Ready" ステータス条件を返すまで待ちます。$ oc --context "${CTX_DATA_PLANE_CLUSTER}" wait --for condition=Ready istiocni/default --timeout=3m
検証
データプレーンクラスターにサンプルアプリケーションをデプロイします。
次のコマンドを実行して、データプレーンクラスターにサンプルアプリケーションの namespace を作成します。
$ oc --context "${CTX_DATA_PLANE_CLUSTER}" get project sample || oc --context="${CTX_DATA_PLANE_CLUSTER}" new-project sample次のコマンドを実行して、サイドカーインジェクションをサポートするために、サンプルアプリケーションの namespace にラベルを付けます。
$ oc --context="${CTX_DATA_PLANE_CLUSTER}" label namespace sample istio.io/rev=external-istiodhelloworldアプリケーションをデプロイします。以下のコマンドを実行して
helloworldサービスを作成します。$ oc --context="${CTX_DATA_PLANE_CLUSTER}" apply \ -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample以下のコマンドを実行して
helloworld-v1デプロイメントを作成します。$ oc --context="${CTX_DATA_PLANE_CLUSTER}" apply \ -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample
次のコマンドを実行して、
sleepアプリケーションをデプロイします。$ oc --context="${CTX_DATA_PLANE_CLUSTER}" apply \ -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/sleep/sleep.yaml -n sample次のコマンドを実行して、
samplenamespace の Pod にサイドカーが注入されていることを確認します。$ oc --context="${CTX_DATA_PLANE_CLUSTER}" get pods -n sampleターミナルで次のコマンドを実行すると、
samplenamespace の各 Pod に対して2/2が返されるはずです。出力例
NAME READY STATUS RESTARTS AGE helloworld-v1-6d65866976-jb6qc 2/2 Running 0 1m sleep-5fcd8fd6c8-mg8n2 2/2 Running 0 1m
内部トラフィックがクラスター上のアプリケーションに到達できることを確認します。
次のコマンドを実行して、
sleepアプリケーションを介してhelloworldアプリケーションにリクエストを送信できることを確認します。$ oc exec --context="${CTX_DATA_PLANE_CLUSTER}" -n sample -c sleep deploy/sleep -- curl -sS helloworld.sample:5000/hellohelloworldアプリケーションからのレスポンスがターミナルに返されるはずです。出力例
Hello version: v1, instance: helloworld-v1-6d65866976-jb6qc
Ingress ゲートウェイをインストールして、サンプルアプリケーションを外部クライアントに公開します。
次のコマンドを実行して、Ingress ゲートウェイを作成します。
$ oc --context="${CTX_DATA_PLANE_CLUSTER}" apply -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/refs/heads/main/chart/samples/ingress-gateway.yaml -n sample次のコマンドを実行して、Ingress ゲートウェイが実行中であることを確認します。
$ oc get pod -l app=istio-ingressgateway -n sample --context="${CTX_DATA_PLANE_CLUSTER}"ゲートウェイが実行中であることを確認できる出力がターミナルに返されるはずです。
出力例
NAME READY STATUS RESTARTS AGE istio-ingressgateway-7bcd5c6bbd-kmtl4 1/1 Running 0 8m4s次のコマンドを実行して、Ingress ゲートウェイを介して
helloworldアプリケーションを公開します。$ oc apply -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/helloworld/helloworld-gateway.yaml -n sample --context="${CTX_DATA_PLANE_CLUSTER}"次のコマンドを実行して、ゲートウェイ URL の環境変数を設定します。
$ export INGRESS_HOST=$(oc -n sample --context="${CTX_DATA_PLANE_CLUSTER}" get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}'); \ export INGRESS_PORT=$(oc -n sample --context="${CTX_DATA_PLANE_CLUSTER}" get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}'); \ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
外部トラフィックがメッシュ上のアプリケーションに到達できることを確認します。
次のコマンドを実行して、ゲートウェイを介して
helloworldアプリケーションにアクセスできることを確認します。$ curl -s "http://${GATEWAY_URL}/hello"helloworldアプリケーションからレスポンスが返されるはずです。出力例
Hello version: v1, instance: helloworld-v1-6d65866976-jb6qc