Configura un mesh di servizi multi-cluster

Questa guida illustra come aggiungere un nuovo cluster GKE a un mesh di servizi esistente.

Prima di iniziare

Prima di aggiungere un cluster, assicurati di completare le istruzioni descritte in Preparare il deployment con l'API GKE Gateway, tra cui Abilitare servizi multi-cluster.

Crea un nuovo cluster GKE

  1. Crea un nuovo cluster utilizzando il comando seguente:

    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. Passa al cluster appena creato inviando il seguente comando:

    gcloud container clusters get-credentials gke-2 --zone us-west1-a
    
  3. Rinomina il contesto del cluster:

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

Registra il cluster in un parco risorse

  1. Dopo aver creato il cluster, registralo nel tuo parco risorse:

    gcloud alpha container hub memberships register gke-2 \
      --gke-cluster us-west1-a/gke-2 \
      --enable-workload-identity \
      --project=PROJECT_ID
    
  2. Verifica che i cluster siano registrati nel parco risorse:

    gcloud alpha container hub memberships list --project=PROJECT_ID
    

    Il parco risorse include sia il cluster appena creato sia quello creato in precedenza:

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

Esegui il deployment dell'iniettore sidecar Envoy nel nuovo cluster GKE

Segui le istruzioni per eseguire il deployment dell'iniettore sidecar Envoy ed eseguire il deployment dell'iniettore nel cluster gke-2.

Espandi il tuo mesh di servizi nel nuovo cluster GKE

Esegui il deployment di un mesh di servizi collaterali Envoy mostra come configurare un mesh di servizi nel cluster gke-1, in cui viene eseguito il servizio store. Questa sezione mostra come espandere il mesh di servizi per includere un servizio payments in esecuzione nel cluster gke-2. Una risorsa Mesh esiste già nel cluster di configurazione, quindi non è necessario creare una risorsa Mesh nel nuovo cluster.

Esegui il deployment del servizio payments

  1. Nel file payments.yaml, salva il seguente manifest:

    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. Applica il manifest al cluster gke-2:

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

Esporta il servizio payments

Tutte le risorse dell'API Gateway sono archiviate centralmente nel cluster di configurazione gke-1. I servizi in altri cluster nel parco risorse devono essere esportati in modo che le risorse dell'API Gateway nel cluster gke-1 possano fare riferimento quando configuri il comportamento di networking del mesh di servizi.

Per una spiegazione dettagliata di come funzionano ServiceExport e ServiceImport, leggi Servizi multi-cluster.

  1. Crea lo spazio dei nomi payments nel cluster gke-1. Il servizio payments nel cluster gke-1 viene esportato in tutti i cluster del parco risorse che si trovano nello stesso spazio dei nomi.

    kubectl create namespace payments --context gke-1
    
  2. Nel file export-payments.yaml, salva il seguente manifest:

    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: payments
      namespace: payments
    
  3. Applica il manifest ServiceExport nel cluster gke-2:

    kubectl apply --context gke-2 -f export-payments.yaml
    
  4. Dopo alcuni minuti, esegui questo comando per verificare che i valori serviceImports associati siano stati creati dal controller di servizi multi-cluster in gke-1:

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

    L'output dovrebbe essere simile al seguente:

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

Configura una risorsa HTTPRoute per il servizio payments

  1. Nel file payments-route.yaml, salva il seguente manifest di 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. Applica il manifest della route a gke-1:

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

Convalida il deployment

Controlla lo stato e gli eventi di Mesh per verificare che il deployment di Mesh e HTTPRoute sia stato eseguito correttamente.

  1. Esegui questo comando:

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

    L'output dovrebbe essere simile al seguente:

    ...
    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. Per verificare il deployment, esegui il deployment di un pod client in uno dei cluster. Nel file client.yaml, salva quanto segue:

    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. Applica il manifest:

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

    L'iniettore sidecar in esecuzione nel cluster inserisce automaticamente un container Envoy nel pod client.

  4. Per verificare che il container Envoy sia stato inserito, esegui questo comando:

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

    L'output è simile al seguente:

    ...
    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. Dopo aver eseguito il provisioning di mesh e del pod client, invia una richiesta dal pod del client al servizio 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"
    

    L'output dovrebbe mostrare che uno dei pod store in gke-1 gestisce la richiesta:

    {
      "cluster_name": "gke-1",
      "zone": "us-central1-a",
      "host_header": "example.com",
    ...
    }
    
  6. Invia una richiesta al servizio 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"
    

    L'output dovrebbe mostrare che uno dei pod payments in gke-2 gestisce la richiesta:

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

Passaggi successivi