Configurer un maillage de services multicluster

Ce guide explique comment ajouter un cluster GKE à un maillage de services existant.

Avant de commencer

Avant d'ajouter un cluster, veillez à suivre les instructions de la page Préparer le déploiement avec l'API GKE Gateway, y compris celles de la section Activer les services multiclusters.

Créer un cluster GKE

  1. Créez un cluster à l'aide de la commande suivante :

    gcloud container clusters create gke-2 \
      --zone=us-west1-a \
      --enable-ip-alias \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --release-channel regular \
      --project=PROJECT_ID
    
  2. Basculez vers le cluster que vous venez de créer en exécutant la commande ci-après :

    gcloud container clusters get-credentials gke-2 --zone us-west1-a
    
  3. Renommez le contexte du cluster :

    kubectl config rename-context gke_PROJECT_ID_us-west1-a_gke-2 gke-2
    

Enregistrer le cluster dans un parc

  1. Une fois le cluster créé, enregistrez-le dans votre parc :

    gcloud alpha container hub memberships register gke-2 \
      --gke-cluster us-west1-a/gke-2 \
      --enable-workload-identity \
      --project=PROJECT_ID
    
  2. Vérifiez que les clusters sont enregistrés auprès du parc :

    gcloud alpha container hub memberships list --project=PROJECT_ID
    

    Le parc inclut à la fois le cluster que vous venez de créer et le cluster que vous avez créé précédemment :

    NAME          EXTERNAL_ID
    gke-1  657e835d-3b6b-4bc5-9283-99d2da8c2e1b
    gke-2  f3727836-9cb0-4ffa-b0c8-d51001742f19
    

Déployer l'injecteur side-car Envoy sur le nouveau cluster GKE

Suivez les instructions pour déployer l'injecteur side-car Envoy sur le cluster gke-2.

Étendre votre maillage de services au nouveau cluster GKE

L'article Déployer un maillage de services side-car Envoy décrit comment configurer un maillage de services dans le cluster gke-1, où le service store s'exécute. Cette section explique comment étendre le maillage de services pour inclure un service payments s'exécutant dans le cluster gke-2. Une ressource Mesh existe déjà dans le cluster de configuration. Vous n'avez donc pas besoin de créer une ressource Mesh dans le nouveau cluster.

Déployer le service payments

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

    kind: Namespace
    apiVersion: v1
    metadata:
      name: payments
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: payments
      namespace: payments
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: payments
          version: v1
      template:
        metadata:
          labels:
            app: payments
            version: v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: payments
      namespace: payments
    spec:
      selector:
        app: payments
      ports:
      - port: 8080
        targetPort: 8080
    
  2. Appliquez le fichier manifeste au cluster gke-2 :

    kubectl apply --context gke-2 -f payments.yaml
    

Exporter le service payments

Toutes les ressources de l'API Gateway sont stockées de manière centralisée dans le cluster de configuration gke-1. Les services d'autres clusters du parc doivent être exportés de sorte que les ressources de l'API Gateway du cluster gke-1 puissent les référencer lorsque vous configurez le comportement de mise en réseau du maillage de services.

Pour obtenir une explication détaillée sur le fonctionnement de ServiceExport et ServiceImport, consultez la section Services multiclusters.

  1. Créez l'espace de noms payments dans le cluster gke-1. Le service payments du cluster gke-1 est exporté vers tous les clusters du parc qui se trouvent dans le même espace de noms.

    kubectl create namespace payments --context gke-1
    
  2. Dans le fichier export-payments.yaml, enregistrez le fichier manifeste suivant :

    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
      name: payments
      namespace: payments
    
  3. Appliquez le fichier manifeste ServiceExport dans le cluster gke-2 :

    kubectl apply --context gke-2 -f export-payments.yaml
    
  4. Après quelques minutes, exécutez la commande suivante pour vérifier que serviceImports a été créé par le contrôleur de services multicluster associé dans gke-1 :

    kubectl get serviceimports --context gke-1 --namespace payments
    

    Le résultat doit ressembler à ce qui suit :

    NAME           TYPE           IP                  AGE
    payments       ClusterSetIP   ["10.112.31.15"]    6m54s
    

Configurer une ressource HTTPRoute pour le service payments

  1. Dans le fichier payments-route.yaml, enregistrez le fichier manifeste HTTPRoute suivant :

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    metadata:
      name: payments-route
      namespace: payments
    spec:
      parentRefs:
      - name: td-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - "example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /payments
        backendRefs:
        - group: net.gke.io
          kind: ServiceImport
          namespace: payments
          name: payments
          port: 8080
    
  2. Appliquez le fichier manifeste de routage à gke-1 :

    kubectl apply --context gke-1 -f payments-route.yaml
    

Validez le déploiement.

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

  1. Exécutez la commande suivante :

    kubectl describe tdmesh td-mesh -–context gke-1
    

    Le résultat doit se présenter comme suit :

    ...
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:49:56Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:27:17Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age                From                Message
      ----    ------  ----               ----                -------
      Normal  ADD     23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  UPDATE  23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    23m                mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    71s                mc-mesh-controller  SYNC on default/td-mesh was a success
    
  2. Pour vérifier le déploiement, déployez un pod client sur l'un des clusters. Dans le fichier client.yaml, enregistrez 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
    
  3. Appliquer le fichier manifeste :

    kubectl apply -f client.yaml --context $CLUSTER
    

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

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

    kubectl describe pods -l run=client --context $CLUSTER
    

    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:
    ...
    
  5. Une fois le mesh et le pod client provisionnés, envoyez une requête du pod client au service store :

    # Get the name of the client Pod.
    CLIENT_POD=$(kubectl get pod --context $CLUSTER -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # The VIP where the following request will be sent. Because requests from the
    # Busybox container are redirected to the Envoy proxy, the IP address can
    # be any other address, such as 10.0.0.2 or 192.168.0.1.
    VIP='10.0.0.1'
    
    # Command to send a request to store.
    TEST_CMD="curl -v -H 'Host: example.com' $VIP/store"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client --context $CLUSTER -- /bin/sh -c "$TEST_CMD"
    

    Le résultat doit indiquer que l'un des pods store de gke-1 diffuse la requête :

    {
      "cluster_name": "gke-1",
      "zone": "us-central1-a",
      "host_header": "example.com",
    ...
    }
    
  6. Envoyez une requête au service payments :

    # Command to send a request to payments.
    TEST_CMD="curl -v -H 'host: example.com' $VIP/payments"
    
    # Execute the test command in the client container.
    kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
    

    Le résultat doit indiquer que l'un des pods payments de gke-2 diffuse la requête :

    {
      "cluster_name": "gke-2",
      "zone": "us-west1-a",
      "host_header": "example.com",
    ...
    }
    

Étapes suivantes