Configurer un maillage de services side-car Envoy

Cette configuration est disponible pour les clients Preview, mais nous ne la recommandons pas pour les 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

Vous devez fournir deux valeurs pour déployer l'injecteur side-car.

  • TRAFFICDIRECTOR_GCP_PROJECT_NUMBER. Remplacez PROJECT_NUMBER par le numéro du projet correspondant à votre cluster de configuration. Le numéro de projet est l'identifiant numérique de votre projet.

  • TRAFFICDIRECTOR_MESH_NAME. Attribuez la valeur 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 TRAFFICDIRECTOR_MESH_NAME comme suit :

    TRAFFICDIRECTOR_MESH_NAME: "gketd-butterfly-mesh"
    
  • TRAFFICDIRECTOR_NETWORK_NAME Assurez-vous que la valeur de TRAFFICDIRECTOR_NETWORK_NAME est définie sur vide :

    TRAFFICDIRECTOR_NETWORK_NAME=""
    
  1. Téléchargez le package d'injecteur de side-car :

    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. Dans le fichier specs/01-configmap.yaml, renseignez les champs TRAFFICDIRECTOR_GCP_PROJECT_NUMBER et TRAFFICDIRECTOR_MESH_NAME, puis définissez TRAFFICDIRECTOR_NETWORK_NAME sur une valeur vide.

       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"
    

Après avoir suivi les instructions précédentes, procédez comme suit pour déployer l'injecteur side-car sur votre cluster :

  1. Configurer TLS pour l'injecteur de side-car
  2. Installer l'injecteur de side-car sur votre cluster GKE
  3. [Facultatif] Ouvrir le port requis sur un cluster privé
  4. Activer l'injection side-car

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

Étapes suivantes