Envoy-Sidecar-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 ein einfaches Service Mesh in Ihrer Flotte konfigurieren. Die Anleitung umfasst folgende Schritte:

  • Envoy-Sidecar-Injektor im Cluster bereitstellen. Der Injektor fügt den Envoy-Proxy-Container in Anwendungs-Pods ein.
  • Gateway API-Ressourcen bereitstellen, die die Envoy-Sidecar-Datei im Service Mesh konfigurieren, um Anfragen an einen Beispieldienst im Namespace store weiterzuleiten.
  • Einfachen Client bereitstellen, um die Bereitstellung zu überprüfen.

Das folgende Diagramm zeigt das konfigurierte Service Mesh.

Envoy-Sidecar-Service-Mesh in einer Flotte
Envoy-Sidecar-Service-Mesh in einer Flotte (zum Vergrößern klicken)

Sie können nur ein Mesh in einem Cluster konfigurieren, da der Mesh-Netzwerk-Name in der Sidecar-Injektor-Konfiguration und der Name der Mesh-Ressource identisch sein müssen.

Envoy-Sidecar-Injektor bereitstellen

Zum Bereitstellen des Sidecar-Injektors müssen Sie zwei Werte angeben.

  • TRAFFICDIRECTOR_GCP_PROJECT_NUMBER. Ersetzen Sie PROJECT_NUMBER durch die Projektnummer des Projekts für Ihren Konfigurationscluster. Die Projektnummer ist die numerische Kennung Ihres Projekts.

  • TRAFFICDIRECTOR_MESH_NAME. Weisen Sie den Wert so zu, wobei MESH_NAME der Wert des Felds metadata.name in der Mesh-Ressourcenspezifikation ist:

    gketd-MESH_NAME
    

    Wenn der Wert von metadata.name in der Mesh-Ressource beispielsweise butterfly-mesh lautet, legen Sie den Wert von TRAFFICDIRECTOR_MESH_NAME so fest:

    TRAFFICDIRECTOR_MESH_NAME: "gketd-butterfly-mesh"
    
  • TRAFFICDIRECTOR_NETWORK_NAME. Achten Sie darauf, dass der Wert von TRAFFICDIRECTOR_NETWORK_NAME auf leer gesetzt ist:

    TRAFFICDIRECTOR_NETWORK_NAME=""
    
  1. Laden Sie das Sidecar-Injektor-Paket herunter:

    wget https://storage.googleapis.com/traffic-director/td-sidecar-injector-xdsv3.tgz
    tar -xzvf td-sidecar-injector-xdsv3.tgz
    cd td-sidecar-injector-xdsv3
    
  2. Füllen Sie in der Datei specs/01-configmap.yaml die Felder TRAFFICDIRECTOR_GCP_PROJECT_NUMBER und TRAFFICDIRECTOR_MESH_NAME aus und setzen Sie TRAFFICDIRECTOR_NETWORK_NAME auf leer.

       apiVersion: v1
       kind: ConfigMap
       metadata:
         name: injector-mesh
         namespace: istio-control
       data:
         mesh: |-
           defaultConfig:
             discoveryAddress: trafficdirector.googleapis.com:443
    
             # Envoy proxy port to listen on for the admin interface.
             # This port is bound to 127.0.0.1.
             proxyAdminPort: 15000
    
             proxyMetadata:
               # Google Cloud Project number that your Fleet belongs to.
               # This is the numeric identifier of your project
               TRAFFICDIRECTOR_GCP_PROJECT_NUMBER: "PROJECT_NUMBER"
    
               # TRAFFICDIRECTOR_NETWORK_NAME must be empty when
               # TRAFFICDIRECTOR_MESH_NAME is set.
               TRAFFICDIRECTOR_NETWORK_NAME=""
    
               # The value of `metadata.name` in the `Mesh` resource. When a
               # sidecar requests configurations from Cloud Service Mesh,
               # Cloud Service Mesh will only return configurations for the
               # specified mesh.
               TRAFFICDIRECTOR_MESH_NAME: "gketd-td-mesh"
    

Nachdem Sie die vorherige Anleitung abgeschlossen haben, führen Sie die folgenden Schritte aus, um den Sidecar-Injektor in Ihrem Cluster bereitzustellen:

  1. TLS für den Sidecar-Injektor konfigurieren
  2. Sidecar-Injektor im GKE-Cluster installieren
  3. [Optional] Erforderlichen Port in einem privaten Cluster öffnen
  4. Sidecar-Injektion aktivieren

store-Dienst bereitstellen

In diesem Abschnitt stellen Sie den store-Dienst im Mesh-Netzwerk bereit.

  1. Speichern Sie in der Datei store.yaml das folgende Manifest:

    kind: Namespace
    apiVersion: v1
    metadata:
      name: store
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store
      namespace: store
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: store
          version: v1
      template:
        metadata:
          labels:
            app: store
            version: v1
        spec:
          containers:
          - name: whereami
            image: gcr.io/google-samples/whereami:v1.2.20
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    
  2. Wenden Sie das Manifest auf gke-1 an:

    kubectl apply -f store.yaml
    

Service Mesh erstellen

  1. Speichern Sie in der Datei mesh.yaml das folgende mesh-Manifest. Der Name der mesh-Ressource muss mit dem in der Injektor-Konfigurationszuordnung angegebenen Mesh-Netzwerknamen übereinstimmen. In dieser Beispielkonfiguration wird der Name td-mesh an beiden Stellen verwendet:

    apiVersion: net.gke.io/v1alpha1
    kind: TDMesh
    metadata:
      name: td-mesh
      namespace: default
    spec:
      gatewayClassName: gke-td
      allowedRoutes:
        namespaces:
          from: All
    
  2. Wenden Sie das mesh-Manifest auf gke-1 an. Dadurch wird ein logisches Mesh-Netzwerk mit dem Namen td-mesh erstellt:

    kubectl apply -f mesh.yaml
    
  3. Speichern Sie in der Datei store-route.yaml das folgende HTTPRoute-Manifest. Das Manifest definiert eine HTTPRoute-Ressource, die HTTP-Traffic, der den Hostnamen example.com angibt, an einen Kubernetes-Dienst store im Namespace store weiterleitet:

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    metadata:
      name: store-route
      namespace: store
    spec:
      parentRefs:
      - name: td-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - "example.com"
      rules:
      - backendRefs:
        - name: store
          namespace: store
          port: 8080
    
  4. Wenden Sie das Routenmanifest auf gke-1 an:

    kubectl apply -f store-route.yaml
    

Deployment validieren

  1. Prüfen Sie den Mesh-Status und die Ereignisse, um festzustellen, ob die Mesh- und HTTPRoute-Ressourcen erfolgreich bereitgestellt wurden:

    kubectl describe tdmesh td-mesh
    

    Die Ausgabe sieht in etwa so aus:

    ...
    
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:08:39Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:08:28Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age   From                Message
      ----    ------  ----  ----                -------
      Normal  ADD     36s   mc-mesh-controller  Processing mesh default/td-mesh
      Normal  UPDATE  35s   mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    24s   mc-mesh-controller  SYNC on default/td-mesh was a success
    
  2. Prüfen Sie mit dem folgenden Befehl, ob die Sidecar-Injektion im Standard-Namespace aktiviert ist:

    kubectl get namespace default --show-labels
    

    Wenn die Sidecar-Injektion aktiviert ist, wird in der Ausgabe Folgendes angezeigt:

    istio-injection=enabled
    

    Wenn die Sidecar-Injektion nicht aktiviert ist, finden Sie weitere Informationen unter Sidecar-Injektionen aktivieren.

  3. Stellen Sie zum Prüfen der Bereitstellung einen Client-Pod bereit, der als Client für den zuvor definierten store-Dienst fungiert. 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
    
  4. Stellen Sie die Spezifikation bereit:

    kubectl apply -f client.yaml
    

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

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

    kubectl describe pods -l run=client
    

    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:
    ...
    

Nachdem der Client-Pod bereitgestellt wurde, senden Sie eine Anfrage vom Client-Pod an den store-Dienst.

  1. Rufen Sie den Namen des Client-Pods ab:

    CLIENT_POD=$(kubectl get pod -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # The VIP where the following request will be sent. Because all requests
    # from the client container are redirected to the Envoy proxy sidecar, you
    # can use any IP address, including 10.0.0.2, 192.168.0.1, and others.
    VIP='10.0.0.1'
    
  2. Senden Sie eine Anfrage an den Store-Dienst und geben Sie die Antwortheader aus:

    TEST_CMD="curl -v -H 'host: example.com' $VIP"
    
  3. Führen Sie den Testbefehl im Clientcontainer aus:

    kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
    

    Die Ausgabe sieht in etwa so aus:

    < Trying 10.0.0.1:80...
    < Connected to 10.0.0.1 (10.0.0.1) port 80 (#0)
    < GET / HTTP/1.1
    < Host: example.com
    < User-Agent: curl/7.82.0-DEV
    < Accept: */*
    <
    < Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: application/json
    < content-length: 318
    < access-control-allow-origin: *
    < server: envoy
    < date: Tue, 12 Apr 2022 22:30:13 GMT
    <
    {
      "cluster_name": "gke-1",
      "zone": "us-west1-a",
      "host_header": "example.com",
      ...
    }
    

Nächste Schritte