Multi-Cluster-Service Mesh einrichten

Diese Konfiguration wird für Vorabversionen unterstützt, für neue Cloud Service Mesh-Nutzer wird sie jedoch nicht empfohlen. Weitere Informationen finden Sie in der Übersicht zum Cloud Service Mesh.

In dieser Anleitung wird gezeigt, wie Sie einem vorhandenen Service Mesh einen neuen GKE-Cluster hinzufügen.

Hinweise

Bevor Sie einen Cluster hinzufügen, müssen Sie die Schritte unter Bereitstellung mit der GKE Gateway API vorbereiten ausführen, einschließlich Multi-Cluster-Dienste aktivieren.

Neuen GKE-Cluster erstellen

  1. Erstellen Sie mit dem folgenden Befehl einen neuen Cluster:

    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. Wechseln Sie mit dem folgenden Befehl zu dem soeben erstellten Cluster:

    gcloud container clusters get-credentials gke-2 --zone us-west1-a
    
  3. Benennen Sie den Clusterkontext um:

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

Cluster bei einer Flotte registrieren

  1. Registrieren Sie den Cluster nach der Erstellung des Clusters bei Ihrer Flotte:

    gcloud alpha container hub memberships register gke-2 \
      --gke-cluster us-west1-a/gke-2 \
      --enable-workload-identity \
      --project=PROJECT_ID
    
  2. Prüfen Sie, ob die Cluster bei der Flotte registriert sind:

    gcloud alpha container hub memberships list --project=PROJECT_ID
    

    Die Flotte enthält sowohl den soeben erstellten als auch den zuvor erstellten Cluster:

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

Envoy-Sidecar-Injektor im neuen GKE-Cluster bereitstellen

Folgen Sie der Anleitung zum Bereitstellen des Envoy-Sidecar-Injektors und stellen Sie den Injektor im Cluster gke-2 bereit.

Service Mesh auf den neuen GKE-Cluster erweitern

Unter Envoy-Sidecar-Service-Mesh bereitstellen erfahren Sie, wie Sie ein Service Mesh im Cluster gke-1 konfigurieren, in dem der store-Dienst ausgeführt wird. In diesem Abschnitt wird gezeigt, wie Sie das Service Mesh um einen payments-Dienst erweitern, der im Cluster gke-2 ausgeführt wird. Eine Mesh-Ressource ist bereits im Konfigurationscluster vorhanden. Daher müssen Sie im neuen Cluster keine Mesh-Ressource erstellen.

payments-Dienst bereitstellen

  1. Speichern Sie in der Datei payments.yaml das folgende 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. Wenden Sie das Manifest auf den Cluster gke-2 an:

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

payments-Dienst exportieren

Alle Gateway API-Ressourcen werden zentral im Konfigurationscluster gke-1 gespeichert. Dienste in anderen Clustern in der Flotte müssen exportiert werden, damit Gateway API-Ressourcen im gke-1-Cluster auf sie verweisen können, wenn Sie das Netzwerkverhalten des Service Mesh konfigurieren.

Eine ausführliche Erläuterung der Funktionsweise von ServiceExport und ServiceImport finden Sie unter Multi-Cluster-Dienste.

  1. Erstellen Sie den Namespace payments im Cluster gke-1. Der payments-Dienst im Cluster gke-1 wird in alle Cluster in der Flotte exportiert, die sich im selben Namespace befinden.

    kubectl create namespace payments --context gke-1
    
  2. Speichern Sie in der Datei export-payments.yaml das folgende Manifest:

    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: payments
      namespace: payments
    
  3. Wenden Sie das ServiceExport-Manifest im Cluster gke-2 an:

    kubectl apply --context gke-2 -f export-payments.yaml
    
  4. Führen Sie nach einigen Minuten den folgenden Befehl aus, um zu prüfen, ob die zugehörigen serviceImports vom Multi-Cluster-Dienst-Controller in gke-1 erstellt wurden:

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

    Die Ausgabe sollte in etwa so aussehen:

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

HTTPRoute-Ressource für den payments-Dienst konfigurieren

  1. Speichern Sie in der Datei payments-route.yaml das folgende HTTPRoute-Manifest:

    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. Wenden Sie das Routenmanifest auf gke-1 an:

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

Deployment validieren

Prüfen Sie den Status und die Ereignisse von Mesh, um festzustellen, ob Mesh und HTTPRoute erfolgreich bereitgestellt wurden.

  1. Führen Sie dazu diesen Befehl aus:

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

    Die Ausgabe sollte in etwa so aussehen:

    ...
    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. Stellen Sie zur Überprüfung der Bereitstellung einen Client-Pod in einem der Cluster bereit. Speichern Sie in der Datei client.yaml Folgendes:

    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. Wenden Sie das Manifest an:

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

    Der im Cluster ausgeführte Sidecar-Injektor fügt automatisch einen Envoy-Container in den Client-Pod ein.

  4. Führen Sie den folgenden Befehl aus, um zu prüfen, ob der Envoy-Container eingefügt wurde:

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

    Die Ausgabe sieht in etwa so aus:

    ...
    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. Nachdem das mesh und der Client-Pod bereitgestellt wurden, senden Sie eine Anfrage vom Client-Pod an den store-Dienst:

    # 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"
    

    Die Ausgabe sollte zeigen, dass einer der store-Pods in gke-1 die Anfrage verarbeitet:

    {
      "cluster_name": "gke-1",
      "zone": "us-central1-a",
      "host_header": "example.com",
    ...
    }
    
  6. Senden Sie eine Anfrage an den payments-Dienst:

    # 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"
    

    Die Ausgabe sollte zeigen, dass einer der payments-Pods in gke-2 die Anfrage verarbeitet:

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

Nächste Schritte