Primary-Remote 설치

Primary-Remote 설치

primary 클러스터(cluster1)에 Istio 컨트롤 플레인을 설치하고 remote 클러스터(cluster2)가 그 컨트롤 플레인을 사용하도록 설정하는 방법을 알려드려요.

출처: Istio 문서

본문

이 가이드를 따라 cluster1(primary 클러스터)에 Istio 컨트롤 플레인을 설치하고, cluster2(remote 클러스터)가 cluster1의 컨트롤 플레인을 사용하도록 설정해요. 두 클러스터 모두 network1 네트워크에 있어서, 두 클러스터의 pod 간에 직접 연결이 가능해요.

진행하기 전에 시작하기 전에의 단계를 반드시 완료하세요.

이 구성에서는 cluster1이 두 클러스터의 API Server를 모두 관찰해서 endpoint를 얻어요. 이렇게 해서 컨트롤 플레인이 두 클러스터의 워크로드에 대해 서비스 디스커버리를 제공할 수 있어요.

서비스 워크로드는 클러스터 경계를 넘어 직접(pod-to-pod) 통신해요.

cluster2의 서비스들은 east-west 트래픽용 전용 게이트웨이를 통해 cluster1의 컨트롤 플레인에 도달해요.

cluster1을 primary로 설정

cluster1용 istioctl 설정을 만들어요:

istioctl과 IstioOperator API로 cluster1에 Istio를 primary로 설치해요.

$ cat <<EOF > cluster1.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      meshID: mesh1
      multiCluster:
        clusterName: cluster1
      network: network1
      externalIstiod: true
EOF

설정을 cluster1에 적용해요:

$ istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml

values.global.externalIstiod가 true로 설정된 것에 주목하세요. 이렇게 하면 cluster1에 설치된 컨트롤 플레인이 다른 remote 클러스터를 위한 외부 컨트롤 플레인으로도 동작할 수 있어요. 이 기능이 활성화되면 istiod는 리더십 락(leadership lock)을 획득하려 시도하고, 결과적으로 여기에 적절히 annotation된 remote 클러스터(이 경우 cluster2)를 관리하게 돼요.

다음 Helm 명령으로 cluster1에 Istio를 primary로 설치해요:

cluster1에 base 차트를 설치해요:

$ helm install istio-base istio/base -n istio-system --kube-context "${CTX_CLUSTER1}"

그리고 다음 멀티클러스터 설정으로 cluster1에 istiod 차트를 설치해요:

$ helm install istiod istio/istiod -n istio-system --kube-context "${CTX_CLUSTER1}" --set global.meshID=mesh1 --set global.externalIstiod=true --set global.multiCluster.clusterName=cluster1 --set global.network=network1

values.global.externalIstiod가 true로 설정된 것에 주목하세요. 이렇게 하면 cluster1에 설치된 컨트롤 플레인이 다른 remote 클러스터를 위한 외부 컨트롤 플레인으로도 동작할 수 있어요. 이 기능이 활성화되면 istiod는 리더십 락을 획득하려 시도하고, 결과적으로 여기에 적절히 annotation된 remote 클러스터(이 경우 cluster2)를 관리하게 돼요.

cluster1에 east-west 게이트웨이 설치

east-west 트래픽 전용 게이트웨이를 cluster1에 설치해요. 기본적으로 이 게이트웨이는 인터넷에 공개돼요. 프로덕션 시스템은 외부 공격을 막기 위해 추가 접근 제한(예: 방화벽 규칙)이 필요할 수 있어요. 어떤 옵션이 있는지 클라우드 벤더에 확인하세요.

$ @samples/multicluster/gen-eastwest-gateway.sh@ \
    --network network1 | \
    istioctl --context="${CTX_CLUSTER1}" install -y -f -

다음 Helm 명령으로 cluster1에 east-west 게이트웨이를 설치해요:

$ helm install istio-eastwestgateway istio/gateway -n istio-system --kube-context "${CTX_CLUSTER1}" --set name=istio-eastwestgateway --set networkGateway=network1

east-west 게이트웨이에 외부 IP 주소가 할당될 때까지 기다려요:

$ kubectl --context="${CTX_CLUSTER1}" get svc istio-eastwestgateway -n istio-system
NAME                    TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)   AGE
istio-eastwestgateway   LoadBalancer   10.80.6.124   34.75.71.237   ...       51s

cluster1에서 컨트롤 플레인 노출

cluster2에 설치하기 전에 먼저 cluster1의 컨트롤 플레인을 노출해서 cluster2의 서비스가 서비스 디스커버리에 접근할 수 있게 해야 해요:

$ kubectl apply --context="${CTX_CLUSTER1}" -n istio-system -f \
    @samples/multicluster/expose-istiod.yaml@

cluster2의 컨트롤 플레인 클러스터 설정

istio-system 네임스페이스에 annotation을 달아서 cluster2를 관리해야 하는 외부 컨트롤 플레인 클러스터를 지정해야 해요:

$ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
$ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1

topology.istio.io/controlPlaneClusters 네임스페이스 annotation을 cluster1로 설정하면, cluster1의 같은 네임스페이스(이 경우 istio-system)에서 실행 중인 istiod에게 remote 클러스터로 연결될 때 cluster2를 관리하라고 지시해요.

cluster2를 remote로 설정

cluster1의 east-west 게이트웨이 주소를 저장해요.

$ export DISCOVERY_ADDRESS=$(kubectl \
    --context="${CTX_CLUSTER1}" \
    -n istio-system get svc istio-eastwestgateway \
    -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

이제 cluster2용 remote 설정을 만들어요.

$ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: remote
  values:
    istiodRemote:
      injectionPath: /inject/cluster/cluster2/net/network1
    global:
      remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF

설정을 cluster2에 적용해요:

$ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml

다음 Helm 명령으로 cluster2에 Istio를 remote로 설치해요:

cluster2에 base 차트를 설치해요:

$ helm install istio-base istio/base -n istio-system --set profile=remote --kube-context "${CTX_CLUSTER2}"

그리고 다음 멀티클러스터 설정으로 cluster2에 istiod 차트를 설치해요:

$ helm install istiod istio/istiod -n istio-system --set profile=remote --set global.multiCluster.clusterName=cluster2 --set istiodRemote.injectionPath=/inject/cluster/cluster2/net/network1 --set global.configCluster=true --set global.remotePilotAddress="${DISCOVERY_ADDRESS}" --kube-context "${CTX_CLUSTER2}"

cluster2를 cluster1의 remote 클러스터로 연결

remote 클러스터를 컨트롤 플레인에 연결하려면, cluster1의 컨트롤 플레인에 cluster2의 API Server에 대한 접근 권한을 줘요. 그러면 다음이 수행돼요:

  • cluster2에서 실행 중인 워크로드의 연결 요청을 컨트롤 플레인이 인증할 수 있게 돼요. API Server 접근 권한이 없으면 컨트롤 플레인은 요청을 거부해요.
  • cluster2에서 실행 중인 서비스 endpoint의 디스커버리가 가능해져요.

topology.istio.io/controlPlaneClusters 네임스페이스 annotation에 포함되었기 때문에, cluster1의 컨트롤 플레인은 또한:

  • cluster2의 웹훅에서 인증서를 패치해요.
  • cluster2의 네임스페이스에 configmap을 쓰는 네임스페이스 컨트롤러를 시작해요.

cluster2에 API Server 접근을 제공하려면 remote secret을 생성해서 cluster1에 적용해요:

$ istioctl create-remote-secret \
    --context="${CTX_CLUSTER2}" \
    --name=cluster2 | \
    kubectl apply -f - --context="${CTX_CLUSTER1}"

축하합니다! primary와 remote 클러스터에 걸친 Istio 메시를 성공적으로 설치했어요!

다음 단계

이제 설치를 검증할 수 있어요.

정리

cluster1과 cluster2 양쪽 모두에서 Istio를 설치했을 때 사용한 것과 같은 방식(istioctl 또는 Helm)으로 Istio를 제거해요.

cluster1에서 Istio를 제거해요:

$ istioctl uninstall --context="${CTX_CLUSTER1}" -y --purge
$ kubectl delete ns istio-system --context="${CTX_CLUSTER1}"

cluster2에서 Istio를 제거해요:

$ istioctl uninstall --context="${CTX_CLUSTER2}" -y --purge
$ kubectl delete ns istio-system --context="${CTX_CLUSTER2}"

cluster1에서 Istio Helm 설치를 삭제해요:

$ helm delete istiod -n istio-system --kube-context "${CTX_CLUSTER1}"
$ helm delete istio-eastwestgateway -n istio-system --kube-context "${CTX_CLUSTER1}"
$ helm delete istio-base -n istio-system --kube-context "${CTX_CLUSTER1}"

cluster1에서 istio-system 네임스페이스를 삭제해요:

$ kubectl delete ns istio-system --context="${CTX_CLUSTER1}"

cluster2에서 Istio Helm 설치를 삭제해요:

$ helm delete istiod -n istio-system --kube-context "${CTX_CLUSTER2}"
$ helm delete istio-base -n istio-system --kube-context "${CTX_CLUSTER2}"

cluster2에서 istio-system 네임스페이스를 삭제해요:

$ kubectl delete ns istio-system --context="${CTX_CLUSTER2}"

(선택) Istio가 설치한 CRD를 삭제해요:

CRD를 삭제하면 클러스터에 만든 모든 Istio 리소스가 영구적으로 제거돼요. 클러스터에 설치된 Istio CRD를 삭제하려면:

$ kubectl get crd -oname --context "${CTX_CLUSTER1}" | grep --color=never 'istio.io' | xargs kubectl delete --context "${CTX_CLUSTER1}"
$ kubectl get crd -oname --context "${CTX_CLUSTER2}" | grep --color=never 'istio.io' | xargs kubectl delete --context "${CTX_CLUSTER2}"

더 알아보기 (Learn more)