Envoy-Sidecar-Service-Mesh einrichten

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 Traffic Director,
               # Traffic Director 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