Configurare un mesh di servizi sidecar Envoy

Questa configurazione è supportata per i clienti Preview, ma non è consigliata per i nuovi utenti di Cloud Service Mesh. Per saperne di più, consulta la panoramica di Cloud Service Mesh.

Questa guida illustra come configurare un semplice mesh di servizi nel tuo fleet. La guida include i seguenti passaggi:

  • Esegui il deployment dell'iniettore di sidecar Envoy nel cluster. L'iniettore inietta il container del proxy Envoy nei pod dell'applicazione.
  • Esegui il deployment di risorse API Gateway che configurano il sidecar Envoy nel mesh di servizi per instradare le richieste a un servizio di esempio nello spazio dei nomi store.
  • Esegui il deployment di un client semplice per verificare il deployment.

Il seguente diagramma mostra il mesh di servizi configurato.

Un mesh di servizi sidecar Envoy in un parco risorse
Un mesh di servizi sidecar Envoy in un parco risorse (fai clic per ingrandire)

Puoi configurare un solo Mesh in un cluster, perché il nome del mesh nella configurazione dell'iniettore sidecar e il nome della risorsa Mesh devono essere identici.

Esegui il deployment dell'iniettore sidecar Envoy

Per eseguire il deployment dell'iniettore sidecar:

  1. Configura le informazioni del progetto

    # The project that contains your GKE cluster.
    export CLUSTER_PROJECT_ID=YOUR_CLUSTER_PROJECT_NUMBER_HERE
    # The name of your GKE cluster.
    export CLUSTER=YOUR_CLUSTER_NAME
    # The channel of your GKE cluster. Eg: rapid, regular, stable.
    export CHANNEL=YOUR_CLUSTER_CHANNEL
    # The location of your GKE cluster, Eg: us-central1 for regional GKE cluster,
    # us-central1-a for zonal GKE cluster
    export LOCATION=ZONE
    
    # The mesh name of the traffic director load balancing API.
    export MESH_NAME=YOUR_MESH_NAME
    # The project that holds the mesh resources.
    export MESH_PROJECT_NUMBER=YOUR_PROJECT_NUMBER_HERE
    
    export TARGET=projects/${MESH_PROJECT_NUMBER}/locations/global/meshes/${MESH_NAME}
    
    gcloud config set project ${CLUSTER_PROJECT_ID}
    

    Per trovare MESH_NAME, assegna il valore come segue, dove MESH_NAME è il valore del campo metadata.name nella specifica della risorsa Mesh:

    gketd-MESH_NAME
    

    Ad esempio, se il valore di metadata.name nella risorsa Mesh è butterfly-mesh, imposta il valore di MESH_NAME come segue:

    export MESH_NAME="gketd-butterfly-mesh"
    
  2. Applica le configurazioni per il webhook con mutazioni

    Le sezioni seguenti forniscono istruzioni per applicare MutatingWebhookConfiguration al cluster. Quando viene creato un pod, viene invocato il controller di ammissione nel cluster. Il controller di ammissione comunica con l'iniettore sidecar gestito per aggiungere il contenitore Envoy al pod.

    Applica le seguenti configurazioni di webhook con mutazioni al tuo cluster.

    cat <<EOF | kubectl apply -f -
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      labels:
        app: sidecar-injector
      name: td-mutating-webhook
    webhooks:
    - admissionReviewVersions:
      - v1beta1
      - v1
      clientConfig:
        url: https://meshconfig.googleapis.com/v1internal/projects/${CLUSTER_PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER}/channels/${CHANNEL}/targets/${TARGET}:tdInject
      failurePolicy: Fail
      matchPolicy: Exact
      name: namespace.sidecar-injector.csm.io
      namespaceSelector:
        matchExpressions:
        - key: td-injection
          operator: Exists
      reinvocationPolicy: Never
      rules:
      - apiGroups:
        - ""
        apiVersions:
        - v1
        operations:
        - CREATE
        resources:
        - pods
        scope: '*'
      sideEffects: None
      timeoutSeconds: 30
    EOF
    

    Se devi personalizzare l'iniettore sidecar, segui questi passaggi per personalizzare l'iniettore sidecar per il tuo cluster:

  3. Configurazione di TLS per l'iniettore sidecar.

  4. Attiva l'iniezione sidecar.

  5. Opzioni per le iniezioni automatiche di Envoy

Esegui il deployment del servizio store

In questa sezione esegui il deployment del servizio store nel mesh.

  1. Nel file store.yaml, salva il seguente 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: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    
  2. Applica il manifest a gke-1:

    kubectl apply -f store.yaml
    

Creare un mesh di servizi

  1. Nel file mesh.yaml, salva il seguente manifest mesh. Il nome della risorsa mesh deve corrispondere al nome del mesh specificato nel ConfigMap dell'iniettore. In questa configurazione di esempio, il nome td-mesh viene utilizzato in entrambi i punti:

    apiVersion: net.gke.io/v1alpha1
    kind: TDMesh
    metadata:
      name: td-mesh
      namespace: default
    spec:
      gatewayClassName: gke-td
      allowedRoutes:
        namespaces:
          from: All
    
  2. Applica il manifest mesh a gke-1, che crea una mesh logica con il nome td-mesh:

    kubectl apply -f mesh.yaml
    
  3. Nel file store-route.yaml, salva il seguente manifest HTTPRoute. Il manifest definisce una risorsa HTTPRoute che instrada il traffico HTTP specificando il nome host example.com a un servizio Kubernetes store nello spazio dei nomi store:

    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. Applica il manifest del percorso a gke-1:

    kubectl apply -f store-route.yaml
    

Convalida il deployment

  1. Controlla lo stato e gli eventi di Mesh per verificare che le risorse Mesh e HTTPRoute siano state implementate correttamente:

    kubectl describe tdmesh td-mesh
    

    L'output è simile al seguente:

    ...
    
    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. Per assicurarti che l'iniezione di sidecar sia abilitata nel namespace predefinito, esegui il seguente comando:

    kubectl get namespace default --show-labels
    

    Se l'iniezione sidecar è attivata, nell'output viene visualizzato quanto segue:

    istio-injection=enabled
    

    Se l'iniezione sidecar non è abilitata, consulta Abilitare le iniezioni sidecar.

  3. Per verificare il deployment, esegui il deployment di un pod client che funge da client per il servizio store definito in precedenza. 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
    
  4. Esegui il deployment della specifica:

    kubectl apply -f client.yaml
    

    L'iniettore sidecar in esecuzione nel cluster inietta automaticamente un contenitore Envoy nel pod client.

  5. Per verificare che il contenitore Envoy sia stato inserito, esegui il seguente comando:

    kubectl describe pods -l run=client
    

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

Dopo aver eseguito il provisioning del pod client, invia una richiesta dal pod client al servizio store.

  1. Recupera il nome del pod del cliente:

    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. Invia una richiesta al servizio di archiviazione e visualizza le intestazioni di risposta:

    TEST_CMD="curl -v -H 'host: example.com' $VIP"
    
  3. Esegui il comando di test nel contenitore client:

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

    L'output è simile al seguente:

    < 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",
      ...
    }
    

Passaggi successivi