Google Cloud 외부에서 멀티 클러스터 메시 설정

이 가이드에서는 다음 플랫폼에 대해 멀티 클러스터 메시를 설정하는 방법을 설명합니다.

  • VMware용 Google Distributed Cloud(소프트웨어 전용)
  • 베어메탈용 Google Distributed Cloud(소프트웨어 전용)
  • Azure용 GKE
  • GKE on AWS
  • 연결된 클러스터(Amazon EKS 클러스터 및 Microsoft AKS 클러스터 포함)

이 가이드에서는 2개의 클러스터를 설정하는 방법을 보여주지만 이 프로세스를 확장하여 원하는 수의 클러스터를 메시에 통합할 수 있습니다.

시작하기 전에

이 가이드에서는 asmcli install을 사용하여 Cloud Service Mesh를 설치했다고 가정합니다. asmcli install을 실행할 때 asmcli--output_dir에 지정된 디렉터리에 다운로드하는 구성 패키지 및 asmcli가 필요합니다. 설정해야 하는 경우 종속 도구 설치 및 클러스터 검증의 단계를 따라 다음을 수행합니다.

메시에 설정하려는 모든 클러스터에 대해 kubeconfig 파일 액세스 권한이 필요합니다.

환경 변수 및 자리표시자 설정

east-west 게이트웨이를 설치할 때는 다음 환경 변수가 필요합니다.

  1. 프로젝트 번호의 환경 변수를 만듭니다. 다음 명령어에서 FLEET_PROJECT_IDFleet 호스트 프로젝트의 프로젝트 ID로 바꿉니다.

    export PROJECT_NUMBER=$(gcloud projects describe FLEET_PROJECT_ID \
    --format="value(projectNumber)")
    
  2. 메시 식별자의 환경 변수를 만듭니다.

    export MESH_ID="proj-${PROJECT_NUMBER}"
    
  3. asmcli에 필요한 형식으로 클러스터 이름에 대한 환경 변수를 만듭니다.

    export CLUSTER_1="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_1"
    export CLUSTER_2="cn-FLEET_PROJECT_ID-global-CLUSTER_NAME_2"
    
  4. 이 명령어 출력에서 NAME 열 아래의 값을 사용하여 클러스터의 컨텍스트 이름을 가져옵니다.

    kubectl config get-contexts
  5. 클러스터 컨텍스트 이름에 환경 변수를 설정합니다. 이는 이 가이드에서 나중에 여러 단계에서 사용하게 될 것입니다.

    export CTX_1=CLUSTER1_CONTEXT_NAME
    export CTX_2=CLUSTER2_CONTEXT_NAME
    

east-west 게이트웨이 설치

다음 명령어를 실행합니다.

  • CLUSTER_NAME_1CLUSTER_NAME_2를 클러스터 이름으로 바꿉니다.

  • PATH_TO_KUBECONFIG_1PATH_TO_KUBECONFIG_2를 해당 클러스터의 kubeconfig 파일로 바꿉니다.

Anthos 클러스터

Mesh CA 또는 CA 서비스

  1. $CLUSTER_2East-West 트래픽 전용 cluster1에 게이트웨이를 설치합니다. 기본적으로 이 게이트웨이는 인터넷에 공개됩니다. 프로덕션 시스템에서는 외부 공격을 차단하기 위해 방화벽 규칙과 같은 추가 액세스 제한이 필요할 수 있습니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=kubernetes -f -
    
  2. $CLUSTER_2$CLUSTER_1의 East-West 트래픽 전용 게이트웨이를 설치합니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=kubernetes -f -
    

Istio CA

  1. $CLUSTER_2East-West 트래픽 전용 cluster1에 게이트웨이를 설치합니다. 기본적으로 이 게이트웨이는 인터넷에 공개됩니다. 프로덕션 시스템에서는 외부 공격을 차단하기 위해 방화벽 규칙과 같은 추가 액세스 제한이 필요할 수 있습니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2$CLUSTER_1의 East-West 트래픽 전용 게이트웨이를 설치합니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Azure, AWS, 연결

Mesh CA

  1. $CLUSTER_2East-West 트래픽 전용 cluster1에 게이트웨이를 설치합니다. 기본적으로 이 게이트웨이는 인터넷에 공개됩니다. 프로덕션 시스템에서는 외부 공격을 차단하기 위해 방화벽 규칙과 같은 추가 액세스 제한이 필요할 수 있습니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2$CLUSTER_1의 East-West 트래픽 전용 게이트웨이를 설치합니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Istio CA

  1. $CLUSTER_2East-West 트래픽 전용 cluster1에 게이트웨이를 설치합니다. 기본적으로 이 게이트웨이는 인터넷에 공개됩니다. 프로덕션 시스템에서는 외부 공격을 차단하기 위해 방화벽 규칙과 같은 추가 액세스 제한이 필요할 수 있습니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_1 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    
  2. $CLUSTER_2$CLUSTER_1의 East-West 트래픽 전용 게이트웨이를 설치합니다.

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_2}  \
        --network default \
        --revision asm-1225-1 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

노출 중인 서비스

클러스터가 별도의 네트워크에 있으므로 두 클러스터의 east-west 게이트웨이에 모든 서비스(*.local)를 노출해야 합니다. 이 게이트웨이는 인터넷에서는 공개 상태지만, 마치 동일한 네트워크에 있는 것처럼 신뢰할 수 있는 mTLS 인증서와 워크로드 ID를 사용하는 서비스만 이러한 서비스에 액세스할 수 있습니다.

  1. CLUSTER_NAME_1의 east-west 게이트웨이를 통해 서비스를 노출합니다.

    kubectl --kubeconfig=PATH_TO_KUBECONFIG_1 apply -n istio-system -f \
        asm/istio/expansion/expose-services.yaml
    
  2. CLUSTER_NAME_2의 east-west 게이트웨이를 통해 서비스를 노출합니다.

    kubectl --kubeconfig=PATH_TO_KUBECONFIG_2 apply -n istio-system -f \
        asm/istio/expansion/expose-services.yaml
    

엔드포인트 검색 사용 설정

asmcli create-mesh 명령어를 실행하여 엔드포인트 검색을 사용 설정합니다. 이 예시에서는 클러스터 2개만 표시하지만 명령어를 실행하면 GKE 허브 서비스 한도에 따른 추가 클러스터에 엔드포인트 검색을 사용 설정할 수 있습니다.

  ./asmcli create-mesh \
      FLEET_PROJECT_ID \
      PATH_TO_KUBECONFIG_1 \
      PATH_TO_KUBECONFIG_2

멀티 클러스터 연결 확인

이 섹션에서는 샘플 HelloWorldSleep 서비스를 멀티 클러스터 환경에 배포하여 클러스터 간 부하 분산 작동 방식을 확인하는 방법을 설명합니다.

사이드카 삽입 사용 설정

  1. 각 클러스터에 샘플 네임스페이스를 만듭니다.

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl create --context=${CTX} namespace sample
    done
    
  2. 생성된 네임스페이스에서 사이드카 삽입을 사용 설정합니다.

    권장: 다음 명령어를 실행하여 네임스페이스에 기본 삽입 라벨을 적용합니다.

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl label --context=${CTX} namespace sample \
            istio.io/rev- istio-injection=enabled --overwrite
    done
    

    기본 삽입을 사용하는 것이 좋지만 버전 기반 삽입이 지원됩니다. 다음 안내를 따르세요.

    1. 다음 명령어를 사용하여 istiod에서 버전 라벨을 찾습니다.

      kubectl get deploy -n istio-system -l app=istiod -o \
          jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. 네임스페이스에 버전 라벨을 적용합니다. 다음 명령어에서 REVISION_LABEL은 이전 단계에서 확인한 istiod 버전 라벨의 값입니다.

      for CTX in ${CTX_1} ${CTX_2}
      do
          kubectl label --context=${CTX} namespace sample \
              istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      done
      

HelloWorld 서비스 설치

  • 두 클러스터에서 HelloWorld 서비스를 만듭니다.

    kubectl create --context=${CTX_1} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    
    kubectl create --context=${CTX_2} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    

HelloWorld v1 및 v2를 각 클러스터에 배포

  1. 나중에 클러스터 간 부하 분산을 확인하는 데 도움이 되도록 HelloWorld v1CLUSTER_1에, v2CLUSTER_2에 배포합니다.

    kubectl create --context=${CTX_1} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v1 -n sample
    kubectl create --context=${CTX_2} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v2 -n sample
  2. 다음 명령어를 사용하여 HelloWorld v1v2가 실행 중인지 확인합니다. 출력이 다음과 비슷한지 확인합니다.

    kubectl get pod --context=${CTX_1} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v1-86f77cd7bd-cpxhv  2/2       Running   0          40s
    kubectl get pod --context=${CTX_2} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v2-758dd55874-6x4t8  2/2       Running   0          40s

Sleep 서비스 배포

  1. 두 클러스터에 Sleep 서비스를 배포합니다. 이 포드는 데모용으로 인위적인 네트워크 트래픽을 생성합니다.

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl apply --context=${CTX} \
            -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample
    done
    
  2. 각 클러스터에서 Sleep 서비스가 시작될 때까지 기다립니다. 출력이 다음과 비슷한지 확인합니다.

    kubectl get pod --context=${CTX_1} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-n6bzf           2/2     Running   0          5s
    kubectl get pod --context=${CTX_2} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-dzl9j           2/2     Running   0          5s

클러스터 간 부하 분산 확인

HelloWorld 서비스를 여러 번 호출하고 출력을 확인하여 v1과 v2에서 번갈아 응답을 보내는지 확인합니다.

  1. HelloWorld 서비스를 호출합니다.

    kubectl exec --context="${CTX_1}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_1}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    출력은 다음과 비슷합니다.

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...
  2. HelloWorld 서비스를 다시 호출합니다.

    kubectl exec --context="${CTX_2}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_2}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    출력은 다음과 비슷합니다.

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...

수고하셨습니다. 멀티 클러스터 Cloud Service Mesh의 부하 분산이 성공적으로 완료되었습니다.

삭제

부하 분산이 확인되면 클러스터에서 HelloWorldSleep 모드를 삭제하세요.

kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}