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

멀티 클러스터 Cloud Service Mesh를 사용하면 Google Cloud 이외의 환경에서 워크로드를 연결할 수 있습니다. 이 아키텍처는 배포 전반에서 교차 클러스터 엔드포인트 검색, 통합 트래픽 라우팅, 일관된 보안 정책을 제공합니다. 자세한 내용은 Cloud Service Mesh 개요를 참조하세요.

지원되는 플랫폼에는 VMware용 Google Distributed Cloud(소프트웨어 전용), 베어메탈용 Google Distributed Cloud(소프트웨어 전용), Azure용 GKE(지원 중단됨), AWS용 GKE(지원 중단됨), 연결된 클러스터(Amazon EKS 클러스터 및 Microsoft AKS 클러스터 포함)(지원 중단됨)가 포함됩니다. 다음 안내에서는 두 개의 클러스터를 연결하는 방법을 보여주지만 이 프로세스를 확장하여 여러 개의 클러스터를 메시에 통합할 수 있습니다.

시작하기 전에

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

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

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

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

  1. 프로젝트 번호의 환경 변수를 만듭니다. 다음 명령어에서 FLEET_PROJECT_ID를 Fleet 호스트 프로젝트의 프로젝트 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_1 및 CLUSTER_NAME_2를 클러스터 이름으로 바꿉니다.

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

GKE 클러스터

Mesh CA 또는 CA 서비스

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

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1311-19 | \
        ./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-1311-19 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Istio CA

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

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1311-19 | \
        ./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-1311-19 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Azure, AWS, 연결

Mesh CA

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

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1311-19 | \
        ./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-1311-19 | \
        ./istioctl --kubeconfig=PATH_TO_KUBECONFIG_2 \
        install -y --set spec.values.global.pilotCertProvider=istiod -f -
    

Istio CA

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

    asm/istio/expansion/gen-eastwest-gateway.sh \
        --mesh ${MESH_ID}  \
        --cluster ${CLUSTER_1}  \
        --network default \
        --revision asm-1311-19 | \
        ./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-1311-19 | \
        ./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

멀티 클러스터 연결 확인

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

사이드카 삽입 사용 설정

  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 v1을 CLUSTER_1에, v2를 CLUSTER_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 v1 및 v2가 실행 중인지 확인합니다. 출력이 다음과 비슷한지 확인합니다.

    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 서비스를 배포합니다. 이 pod는 데모용으로 인위적인 네트워크 트래픽을 생성합니다.

    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의 부하 분산이 성공적으로 완료되었습니다.

삭제

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

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