멀티 클러스터 서비스 메시 설정

이 가이드에서는 새 GKE 클러스터를 기존 서비스 메시에 추가하는 방법을 보여줍니다.

시작하기 전에

클러스터를 추가하기 전에 멀티 클러스터 서비스 사용 설정을 포함한 GKE Gateway API로 배포 준비의 안내를 완료해야 합니다.

새로운 GKE 클러스터 만들기

  1. 다음 명령어를 사용하여 새 클러스터를 만듭니다.

    gcloud container clusters create gke-2 \
      --zone=us-west1-a \
      --enable-ip-alias \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --release-channel regular \
      --project=PROJECT_ID
    
  2. 다음 명령어를 실행하여 방금 만든 클러스터로 전환합니다.

    gcloud container clusters get-credentials gke-2 --zone us-west1-a
    
  3. 클러스터 컨텍스트 이름을 바꿉니다.

    kubectl config rename-context gke_PROJECT_ID_us-west1-a_gke-2 gke-2
    

Fleet에 클러스터 등록

  1. 클러스터가 생성되면 Fleet에 클러스터를 등록합니다.

    gcloud alpha container hub memberships register gke-2 \
      --gke-cluster us-west1-a/gke-2 \
      --enable-workload-identity \
      --project=PROJECT_ID
    
  2. 클러스터가 Fleet에 등록되어 있는지 확인합니다.

    gcloud alpha container hub memberships list --project=PROJECT_ID
    

    Fleet에는 방금 만든 클러스터와 이전에 만든 클러스터가 모두 포함됩니다.

    NAME          EXTERNAL_ID
    gke-1  657e835d-3b6b-4bc5-9283-99d2da8c2e1b
    gke-2  f3727836-9cb0-4ffa-b0c8-d51001742f19
    

새 GKE 클러스터에 Envoy 사이드카 인젝터 배포

Envoy 사이드카 인젝터 배포 안내를 따르고 인젝터를 gke-2 클러스터에 배포합니다.

새 GKE 클러스터로 서비스 메시 확장

Envoy 사이드카 서비스 메시 배포에서는 store 서비스가 실행되는 gke-1 클러스터에서 서비스 메시를 구성하는 방법을 보여줍니다. 이 섹션에서는 gke-2 클러스터에서 실행되는 payments 서비스가 포함되도록 서비스 메시를 확장하는 방법을 보여줍니다. Mesh 리소스가 이미 구성 클러스터에 있으므로 새 클러스터에 Mesh 리소스를 만들 필요가 없습니다.

payments 서비스 배포

  1. payments.yaml 파일에 다음 매니페스트를 저장합니다.

    kind: Namespace
    apiVersion: v1
    metadata:
      name: payments
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: payments
      namespace: payments
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: payments
          version: v1
      template:
        metadata:
          labels:
            app: payments
            version: v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: payments
      namespace: payments
    spec:
      selector:
        app: payments
      ports:
      - port: 8080
        targetPort: 8080
    
  2. gke-2 클러스터에 매니페스트를 적용합니다.

    kubectl apply --context gke-2 -f payments.yaml
    

payments 서비스 내보내기

모든 Gateway API 리소스는 구성 클러스터 gke-1에 중앙 집중식으로 저장됩니다. 서비스 메시의 네트워킹 동작을 구성할 때 gke-1 클러스터의 Gateway API 리소스가 이를 참조할 수 있도록 Fleet의 다른 클러스터에 있는 서비스는 내보내야 합니다.

ServiceExportServiceImport 작동 방식에 대한 자세한 내용은 멀티 클러스터 서비스를 참조하세요.

  1. gke-1 클러스터에 네임스페이스 payments를 만듭니다. 클러스터 gke-1payments 서비스는 동일한 네임스페이스에 있는 Fleet의 모든 클러스터로 내보냅니다.

    kubectl create namespace payments --context gke-1
    
  2. export-payments.yaml 파일에 다음 매니페스트를 저장합니다.

    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: payments
      namespace: payments
    
  3. gke-2 클러스터에서 ServiceExport 매니페스트를 적용합니다.

    kubectl apply --context gke-2 -f export-payments.yaml
    
  4. 몇 분 후 다음 명령어를 실행하여 함께 제공된 serviceImportsgke-1의 멀티 클러스터 서비스 컨트롤러에 의해 생성되었는지 확인합니다.

    kubectl get serviceimports --context gke-1 --namespace payments
    

    출력은 다음과 비슷하게 표시됩니다.

    NAME           TYPE           IP                  AGE
    payments       ClusterSetIP   ["10.112.31.15"]    6m54s
    

payments 서비스에 대한 HTTPRoute 리소스 구성

  1. payments-route.yaml 파일에 다음 HTTPRoute 매니페스트를 저장합니다.

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    metadata:
      name: payments-route
      namespace: payments
    spec:
      parentRefs:
      - name: td-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - "example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /payments
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          namespace: payments
          name: payments
          port: 8080
    
  2. 경로 매니페스트를 gke-1에 적용합니다.

    kubectl apply --context gke-1 -f payments-route.yaml
    

배포 검증

Mesh 상태와 이벤트를 검사하여 MeshHTTPRoute가 성공적으로 배포되었는지 확인합니다.

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

    kubectl describe tdmesh td-mesh -–context gke-1
    

    출력은 다음과 비슷하게 표시됩니다.

    ...
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:49:56Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:27:17Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age                From                Message
      ----    ------  ----               ----                -------
      Normal  ADD     23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  UPDATE  23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    71s                mc-mesh-controller  SYNC on default/td-mesh was a success
    
  2. 배포를 확인하려면 클라이언트 포드를 클러스터 중 하나에 배포합니다. client.yaml 파일에 다음을 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: client
      name: client
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: client
      template:
        metadata:
          labels:
            run: client
        spec:
          containers:
          - name: client
            image: curlimages/curl
            command:
            - sh
            - -c
            - while true; do sleep 1; done
    
  3. 매니페스트 적용

    kubectl apply -f client.yaml --context $CLUSTER
    

    클러스터에서 실행되는 사이드카 인젝터가 자동으로 Envoy 컨테이너를 클라이언트 포드에 삽입합니다.

  4. Envoy 컨테이너가 삽입되었는지 확인하려면 다음 명령어를 실행합니다.

    kubectl describe pods -l run=client --context $CLUSTER
    

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

    ...
    Init Containers:
      # Istio-init sets up traffic interception for the Pod.
      istio-init:
    ...
      # td-bootstrap-writer generates the Envoy bootstrap file for the Envoy container
      td-bootstrap-writer:
    ...
    Containers:
    # client is the client container that runs application code.
      client:
    ...
    # Envoy is the container that runs the injected Envoy proxy.
      envoy:
    ...
    
  5. mesh 및 클라이언트 포드가 프로비저닝되면 클라이언트 포드에서 store 서비스로 요청을 전송합니다.

    # Get the name of the client Pod.
    CLIENT_POD=$(kubectl get pod --context $CLUSTER -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # The VIP where the following request will be sent. Because requests from the
    # Busybox container are redirected to the Envoy proxy, the IP address can
    # be any other address, such as 10.0.0.2 or 192.168.0.1.
    VIP='10.0.0.1'
    
    # Command to send a request to store.
    TEST_CMD="curl -v -H 'Host: example.com' $VIP/store"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client --context $CLUSTER -- /bin/sh -c "$TEST_CMD"
    

    gke-1store 포드 중 하나가 요청을 처리하는 것으로 출력에 표시됩니다.

    {
      "cluster_name": "gke-1",
      "zone": "us-central1-a",
      "host_header": "example.com",
    ...
    }
    
  6. payments 서비스에 요청을 보냅니다.

    # Command to send a request to payments.
    TEST_CMD="curl -v -H 'host: example.com' $VIP/payments"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
    

    gke-2의 payments 포드중 하나가 요청을 처리하는 것으로 출력에 표시됩니다.

    {
      "cluster_name": "gke-2",
      "zone": "us-west1-a",
      "host_header": "example.com",
    ...
    }
    

다음 단계