8장. 외부 컨트롤 플레인 토폴로지
외부 컨트롤 플레인 토폴로지를 사용하여 별도의 클러스터의 데이터 플레인에서 컨트롤 플레인을 분리합니다.
8.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>컨트롤 플레인의 수신 게이트웨이를 설정합니다.
다음 명령을 실행하여
istio-system이라는 프로젝트를 생성합니다.$ oc get project istio-system --context "${CTX_CONTROL_PLANE_CLUSTER}" || oc new-project istio-system --context "${CTX_CONTROL_PLANE_CLUSTER}"다음 명령을 실행하여 컨트롤 플레인 클러스터에서
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다음 명령을 실행하여 컨트롤 플레인의 수신 게이트웨이를 생성합니다.
$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" apply -f https://raw.githubusercontent.com/istio-ecosystem/sail-operator/main/docs/deployment-models/resources/controlplane-gateway.yaml다음 명령을 실행하여 수신 게이트웨이에 할당된 IP 주소를 가져옵니다.
$ oc --context "${CTX_CONTROL_PLANE_CLUSTER}" get svc istio-ingressgateway -n istio-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}'다음 명령을 실행하여 수신 게이트웨이의 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다음 명령을 실행하여 데이터 플레인 클러스터의 사이드카 프록시가 컨트롤 플레인에 액세스할 수 있도록
게이트웨이및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
검증
데이터 플레인 클러스터에 샘플 애플리케이션을 배포합니다.
다음 명령을 실행하여 데이터 플레인 클러스터에서 샘플 애플리케이션의 네임스페이스를 생성합니다.
$ oc --context "${CTX_DATA_PLANE_CLUSTER}" get project sample || oc --context="${CTX_DATA_PLANE_CLUSTER}" new-project sample다음 명령을 실행하여 샘플 애플리케이션의 네임스페이스에 라벨을 지정하여 사이드카 삽입을 지원합니다.
$ 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
다음 명령을 실행하여
절전애플리케이션을 배포합니다.$ oc --context="${CTX_DATA_PLANE_CLUSTER}" apply \ -f https://raw.githubusercontent.com/istio/istio/${ISTIO_VERSION}/samples/sleep/sleep.yaml -n sample다음 명령을 실행하여
샘플네임스페이스의 Pod에 사이드카가 삽입되었는지 확인합니다.$ oc --context="${CTX_DATA_PLANE_CLUSTER}" get pods -n sample터미널은 다음 명령을 실행하여
샘플네임스페이스의 각 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/hello터미널에서
helloworld애플리케이션의 응답을 반환해야 합니다.출력 예
Hello version: v1, instance: helloworld-v1-6d65866976-jb6qc
수신 게이트웨이를 설치하여 샘플 애플리케이션을 외부 클라이언트에 노출합니다.
다음 명령을 실행하여 수신 게이트웨이를 만듭니다.
$ 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다음 명령을 실행하여 수신 게이트웨이가 실행 중인지 확인합니다.
$ 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다음 명령을 실행하여 수신 게이트웨이를 통해
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