Configurer un maillage de services side-car Envoy

Cette configuration est compatible avec les clients Preview, mais nous ne la recommandons pas aux nouveaux utilisateurs de Cloud Service Mesh. Pour en savoir plus, consultez la présentation de Cloud Service Mesh.

Ce guide explique comment configurer un maillage de services simple dans votre parc. Il comprend les étapes suivantes :

  • Déployer l'injecteur side-car Envoy dans le cluster. L'injecteur injecte le conteneur du proxy Envoy dans les pods d'application.
  • Déployer des ressources d'API de passerelle qui configurent le side-car Envoy dans le maillage de services, pour acheminer les requêtes vers un exemple de service dans l'espace de noms store.
  • Déployer un client simple pour vérifier le déploiement.

Le schéma suivant montre le maillage de services configuré.

Maillage de services side-car Envoy dans un parc
Maillage de services side-car Envoy dans un parc (cliquez pour agrandir)

Vous ne pouvez configurer qu'un seul Mesh dans un cluster, car le nom du maillage dans la configuration de l'injecteur side-car et le nom de la ressource Mesh doivent être identiques.

Déployer l'injecteur side-car Envoy

Pour déployer l'injecteur de side-car :

  1. Configurer les informations du projet

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

    Pour connaître la valeur MESH_NAME, attribuez-la comme suit, où MESH_NAME est la valeur du champ metadata.name dans la spécification de ressource Mesh:

    gketd-MESH_NAME
    

    Par exemple, si la valeur de metadata.name dans la ressource Mesh est butterfly-mesh, définissez la valeur de MESH_NAME comme suit:

    export MESH_NAME="gketd-butterfly-mesh"
    
  2. Appliquer les configurations pour le webhook de modification

    Les sections suivantes fournissent des instructions pour appliquer MutatingWebhookConfiguration au cluster. Lorsqu'un pod est créé, le contrôleur d'admission du cluster est appelé. Le contrôleur d'admission communique avec l'injecteur de sidecar géré pour ajouter le conteneur Envoy au pod.

    Appliquez les configurations de webhook de modification suivantes à votre 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
    

    Si vous devez personnaliser l'injecteur de side-car, procédez comme suit pour le personnaliser en fonction de votre cluster:

  3. Configurer TLS pour l'injecteur de side-car

  4. Activer l'injection side-car

  5. Options d'injection Envoy automatique

Déployer le service store

Dans cette section, vous allez déployer le service store dans le maillage.

  1. Dans le fichier store.yaml, enregistrez le fichier manifeste suivant :

    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. Appliquez le fichier manifeste à gke-1 :

    kubectl apply -f store.yaml
    

Créer un maillage de services

  1. Dans le fichier mesh.yaml, enregistrez le fichier manifeste mesh suivant. Le nom de la ressource mesh doit correspondre au nom du maillage spécifié dans le ConfigMap de l'injecteur. Dans cet exemple de configuration, le fichier ainsi que le ConfigMap reprennent le nom td-mesh :

    apiVersion: net.gke.io/v1alpha1
    kind: TDMesh
    metadata:
      name: td-mesh
      namespace: default
    spec:
      gatewayClassName: gke-td
      allowedRoutes:
        namespaces:
          from: All
    
  2. Appliquez le fichier manifeste mesh à gke-1, qui crée un maillage logique nommé td-mesh :

    kubectl apply -f mesh.yaml
    
  3. Dans le fichier store-route.yaml, enregistrez le fichier manifeste HTTPRoute suivant : Le fichier manifeste définit une ressource HTTPRoute qui achemine le trafic HTTP spécifiant le nom d'hôte example.com vers un service Kubernetes store dans l'espace de noms 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. Appliquez le fichier manifeste de routage à gke-1 :

    kubectl apply -f store-route.yaml
    

Validez le déploiement.

  1. Inspectez l'état Mesh et les événements pour vérifier que les ressources Mesh et HTTPRoute ont bien été déployées :

    kubectl describe tdmesh td-mesh
    

    Le résultat ressemble à ce qui suit :

    ...
    
    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. Pour vous assurer que l'injection side-car est activée dans l'espace de noms par défaut, exécutez la commande suivante :

    kubectl get namespace default --show-labels
    

    Si l'injection side-car est activée, les résultats suivants s'affichent :

    istio-injection=enabled
    

    Si l'injection side-car n'est pas activée, consultez la page Activer les injections side-car.

  3. Pour vérifier le déploiement, déployez un pod client qui sert de client au service store défini précédemment. Dans le fichier client.yaml, spécifiez les éléments suivants :

    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. Déployez la spécification :

    kubectl apply -f client.yaml
    

    L'injecteur side-car s'exécutant dans le cluster injecte automatiquement un conteneur Envoy dans le pod client.

  5. Pour vérifier que le conteneur Envoy est injecté, exécutez la commande suivante :

    kubectl describe pods -l run=client
    

    Le résultat ressemble à ce qui suit :

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

Une fois le pod client provisionné, envoyez une requête du pod client vers le service store.

  1. Obtenez le nom du pod client :

    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. Envoyez une requête pour stocker les services et générer les en-têtes de réponse :

    TEST_CMD="curl -v -H 'host: example.com' $VIP"
    
  3. Exécutez la commande de test dans le conteneur client :

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

    Le résultat ressemble à ce qui suit :

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

Étape suivante