Configurer l'équilibrage de charge HTTP(S) externe pour Anthos Service Mesh géré

Présentation

Cloud Load Balancing fournit de nombreuses fonctionnalités périphériques gérées dans le cloud, y compris l'équilibrage de charge Anycast mondial, les certificats gérés par Google, la gestion de l'authentification et des accès, ainsi que le pare-feu cloud ou IDS. Anthos Service Mesh peut intégrer parfaitement ces fonctionnalités de périphérie dans le modèle d'entrée de maillage suivant. La passerelle cloud du maillage de services offre un moyen unifié de configurer la passerelle d'entrée Anthos Service Mesh avec Cloud Load Balancing simultanément via l'API Kubernetes Gateway.

Schéma illustrant l'équilibreur de charge Cloud avec Anthos Service Mesh

Par rapport à notre précédent guide de l'utilisateur, From Edge to Mesh: Exposing service maillage applications by GKE Ingress (De la périphérie au maillage : exposer les applications de maillage de services via GKE Ingress), ce modèle peut désormais être déployé via une seule ressource Kubernetes Gateway, ce qui simplifie le processus de déploiement simultané dans le cloud et l'équilibrage de charge hébergé par le cluster.

Limites de l'aperçu

Pour la version preview de cette fonctionnalité, les limites suivantes s'appliquent:

  • Les passerelles multicluster ne sont pas compatibles.
  • Les clusters Autopilot ne sont pas compatibles.
  • Seul l'équilibreur de charge d'application classique est compatible. L'équilibreur de charge avancé et l'équilibreur de charge HTTP(S) interne ne sont pas compatibles.
  • Le trafic entre l'équilibreur de charge HTTP(S) externe et la passerelle d'entrée Anthos Service Mesh est chiffré à l'aide de TLS. Toutefois, l'équilibreur de charge HTTP(S) externe ne vérifie pas le certificat fourni par la passerelle d'entrée Anthos Service Mesh. Cette limite s'applique à tous les utilisateurs de l'équilibreur de charge HTTP(S) Google Cloud.
  • Si les GatewayClasses Anthos Service Mesh sont supprimés d'un cluster, ils ne seront pas réinstallés automatiquement. Toutefois, cela n'a aucune incidence sur la facilité d'utilisation de la fonctionnalité.
  • La logique de mise en correspondance des routes ne respecte pas les spécifications de l'API Gateway et les met en correspondance dans l'ordre de la route HTTP. Cela changera dans les futures versions afin de respecter les spécifications de l'API Gateway.

Conditions requises

  • Anthos Service Mesh géré installé sur un cluster Google Kubernetes Engine (GKE) exécutant la version 1.24 ou une version ultérieure. Les autres clusters GKE Enterprise ne sont pas compatibles.
  • API Kubernetes Gateway v1beta1 uniquement.

Prérequis

  • Activez les API suivantes dans votre projet:

    • compute.googleapis.com
    • container.googleapis.com
    • certificatemanager.googleapis.com
    • serviceusage.googleapis.com
    gcloud services enable \
       compute.googleapis.com \
       container.googleapis.com \
       certificatemanager.googleapis.com \
       serviceusage.googleapis.com
    

Déployer la passerelle cloud du maillage de services pour un réseau maillé à cluster unique

Cette section explique comment déployer une ressource de passerelle Kubernetes qui déploie un équilibreur de charge HTTP(S) externe global (classique) et une passerelle d'entrée Anthos Service Mesh.

Activer l'API Gateway avec Anthos Service Mesh géré

  1. Activez l'API Gateway dans votre cluster. Le cluster GKE doit être de version 1.24 ou ultérieure.

  2. Installez Anthos Service Mesh géré avec rapid ou regular comme version disponible.

Déployer la ressource Gateway

Lors du déploiement d'une passerelle cloud de maillage de services, les ressources Kubernetes Gateway permettent de déployer à la fois Cloud Load Balancing et la passerelle d'entrée Anthos Service Mesh en une seule étape. Notez que les ressources de la passerelle Kubernetes sont différentes des ressources de la passerelle Istio.

Pour en savoir plus sur les différences, consultez la section Passerelles Kubernetes et passerelles Istio. Chaque passerelle Kubernetes possède une classe de passerelle (GatewayClass) qui indique son type et ses fonctionnalités inhérentes. La passerelle cloud de maillage de services possède une classe de passerelle (GatewayClass) capable de déployer à la fois Cloud Load Balancing et la passerelle d'entrée Anthos Service Mesh.

  1. Enregistrez le fichier manifeste GatewayClass suivant dans un fichier nommé l7-gateway-class.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: GatewayClass
    metadata:
      name: asm-l7-gxlb
    spec:
      controllerName: mesh.cloud.google.com/gateway
    
  2. Déployez la GatewayClass dans votre cluster:

    kubectl apply -f l7-gateway-class.yaml
    
  3. Vérifiez que la classe GatewayClass est présente après l'installation:

    kubectl get gatewayclasses.gateway.networking.k8s.io
    

    Le résultat est semblable à :

    NAME          CONTROLLER
    asm-l7-gxlb   mesh.cloud.google.com/gateway
    gke-l7-rilb   networking.gke.io/gateway
    gke-l7-gxlb   networking.gke.io/gateway
    

    Le déploiement de toutes les ressources peut prendre quelques minutes. Si vous ne voyez pas le résultat attendu, vérifiez que vous avez correctement rempli les conditions préalables.

    La GatewayClass suivante s'affiche également:

    gke-l7-gxlb   networking.gke.io/gateway
    

    Cela permet de déployer l'équilibreur de charge HTTP(S) externe global de Google Cloud.

  4. Créez un espace de noms dédié pour votre passerelle cloud de maillage de services:

    kubectl create namespace istio-ingress
    
  5. Enregistrez le fichier de manifeste de passerelle suivant dans un fichier nommé gateway.yaml :

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
    
  6. Déployez la passerelle dans votre cluster dans l'espace de noms Istio-ingress:

    kubectl apply -f gateway.yaml
    
  7. Vérifiez que les objets de l'API Kubernetes Gateway ont été créés:

    kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
    

    Le résultat est semblable à :

    NAME                                CLASS         ADDRESS         READY   AGE
    asm-gw-gke-servicemesh-cloud-gw     gke-l7-gxlb   34.111.114.64   True    9m40s
    asm-gw-istio-servicemesh-cloud-gw   istio                                 9m44s
    servicemesh-cloud-gw                asm-l7-gxlb                           9m44s
    

Voici ce qui se passera lorsque cet objet API Kubernetes Gateway sera déployé:

  • Un équilibreur de charge HTTP(S) externe est déployé et configuré. Quelques minutes peuvent s'écouler avant qu'il ne s'affiche. Lorsqu'il se produit, la passerelle indique l'adresse IP et est annotée avec les noms des ressources de l'équilibreur de charge Compute Engine créées.
  • Un déploiement de passerelle d'entrée Anthos Service Mesh est créé dans l'espace de noms "Istio-ingress". Cette opération crée les instances de proxy Envoy qui recevront le trafic provenant de l'équilibreur de charge Cloud.
  • L'équilibreur de charge Cloud chiffre et achemine tout le trafic vers la passerelle d'entrée Anthos Service Mesh.

Vous disposez désormais de toute l'infrastructure nécessaire pour accepter le trafic Internet dans votre maillage. Notez qu'il s'agit du déploiement de Gateway le plus simple possible. Dans les sections suivantes, vous allez ajouter des règles et des fonctionnalités qui permettront d'assurer la mise en production.

Déploiement d'applications et de routages

Pour démontrer pleinement les fonctionnalités, vous allez par exemple déployer une application sur Anthos Service Mesh et recevoir du trafic Internet via votre passerelle.

  1. Ajoutez un libellé à l'espace de noms default pour activer l'injection side-car.

    kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
    
  2. Enregistrez le fichier de manifeste de passerelle suivant dans un fichier nommé whereami.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v1
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v1
      template:
        metadata:
          labels:
            app: whereami-v1
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v1"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v1
    spec:
      selector:
        app: whereami-v1
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-v2
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: whereami-v2
      template:
        metadata:
          labels:
            app: whereami-v2
        spec:
          containers:
          - name: whereami
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20
            ports:
              - containerPort: 8080
            env:
            - name: METADATA
              value: "whereami-v2"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: whereami-v2
    spec:
      selector:
        app: whereami-v2
      ports:
      - port: 8080
        targetPort: 8080
    

    Ce fichier manifeste crée Service/whereami-v1, Service/whereami-v2, Deployment/whereami-v1 et Deployment/whereami-v2 pour WHERE, une application simple qui génère du fichier JSON pour indiquer son identité et son emplacement. Vous allez déployer deux versions différentes de celui-ci.

  3. Créez les services et les déploiements:

    kubectl apply -f whereami.yaml
    

    Une fois que celui-ci est opérationnel, quatre pods WHEREami s'exécutent dans votre cluster.

  4. Vérifiez que les quatre pods sont en cours d'exécution:

    kubectl get pods
    

    Le résultat est semblable à :

    whereami-v1-7c76d89d55-qg6vs       2/2     Running   0          28s
    whereami-v1-7c76d89d55-vx9nm       2/2     Running   0          28s
    whereami-v2-67f6b9c987-p9kqm       2/2     Running   0          27s
    whereami-v2-67f6b9c987-qhj76       2/2     Running   0          27s
    
  5. Enregistrez le fichier manifeste HTTPRoute suivant dans un fichier nommé http-route.yaml :

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: where-route
    spec:
     parentRefs:
     - kind: Gateway
       name: servicemesh-cloud-gw
       namespace: istio-ingress
     hostnames:
     - "where.example.com"
     rules:
     - matches:
       - headers:
         - name: version
           value: v2
       backendRefs:
       - name: whereami-v2
         port: 8080
     - backendRefs:
       - name: whereami-v1
         port: 8080
    
  6. Déployez http-route.yaml sur votre cluster:

    kubectl apply -f http-route.yaml
    

    Cette ressource HTTPRoute fait référence à servicemesh-cloud-gw, ce qui signifie qu'elle configure la passerelle cloud du maillage de services afin de configurer la passerelle d'entrée Anthos Service Mesh sous-jacente avec ces règles de routage. La ressource HTTPRoute exécute la même fonction que l'API Istio VirtualService, mais utilise l'API Kubernetes Gateway pour ce faire. Étant donné que l'API Gateway est une spécification OSS avec de nombreuses implémentations sous-jacentes, elle est la mieux adaptée pour définir le routage sur une combinaison de différents équilibreurs de charge (tels que des proxys Anthos Service Mesh et des équilibreurs de charge Cloud).

  7. Récupérez l'adresse IP de la passerelle afin de pouvoir envoyer du trafic vers votre application:

    VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
    

    Le résultat est une adresse IP.

    echo $VIP
    
    34.111.61.135
    
  8. Envoyer le trafic vers l'adresse IP de la passerelle pour vérifier que cette configuration fonctionne correctement Envoyez une requête avec l'en-tête version: v2 et une autre sans pour déterminer que le routage est effectué correctement entre les deux versions de l'application.

    curl ${VIP} -H "host: where.example.com"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v1",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v1-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    
    curl ${VIP} -H "host: where.example.com" -H "version: v2"
    
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "whereami-v2",
      "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal",
      "pod_name": "whereami-v2-67d9c5d48b-zhr4l",
      "pod_name_emoji": "⚒",
      "project_id": "church-243723",
      "timestamp": "2021-02-08T18:55:01",
      "zone": "us-central1-a"
    }
    

Déploiement de la passerelle de production

La section précédente a montré un exemple très simple de passerelle cloud de maillage de services. Les étapes suivantes s'appuient sur l'exemple simple pour présenter une configuration prête pour la production, qui montre les avantages de la délégation de certaines fonctionnalités de routage d'entrée à l'équilibreur de charge cloud.

Dans l'exemple suivant, vous allez utiliser le servicemesh-cloud-gw de la section précédente et ajouter les fonctionnalités suivantes pour créer une passerelle plus sécurisée et plus facile à gérer:

  • Déployez la passerelle avec une adresse IP statique qui sera conservée même si l'infrastructure sous-jacente change.
  • Convertissez la passerelle pour recevoir le trafic HTTPS avec un certificat autosigné.
  1. Créez une adresse IP externe statique. Une adresse IP statique est utile car l'infrastructure sous-jacente peut changer à l'avenir, mais l'adresse IP peut être conservée.

    gcloud compute addresses create whereami-ip \
        --global \
        --project PROJECT_ID
    
  2. Créez un certificat autosigné pour le domaine where-example-com:

    openssl genrsa -out key.pem 2048
    cat <<EOF >ca.conf
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    [dn_requirements]
    0.organizationName        = example
    commonName                = where.example.com
    [sans_list]
    DNS.1                     = where.example.com
    EOF
    
    openssl req -new -key key.pem \
        -out csr.pem \
        -config ca.conf
    
    openssl x509 -req \
        -signkey key.pem \
        -in csr.pem \
        -out cert.pem \
        -extfile ca.conf \
        -extensions extension_requirements \
        -days 365
    
    gcloud compute ssl-certificates create where-example-com \
        --certificate=cert.pem \
        --private-key=key.pem \
        --global \
        --project PROJECT_ID
    

    Il existe de nombreuses façons de générer des certificats TLS. Ils peuvent être générés manuellement sur la ligne de commande, à l'aide de certificats gérés par Google ou en interne par le système d'infrastructure à clé publique (PKI) de votre entreprise. Dans cet exemple, vous générez manuellement un certificat autosigné. Bien que les certificats autosignés ne soient généralement pas utilisés pour les services publics, ils illustrent plus facilement ces concepts.

    Pour en savoir plus sur la création d'un certificat autosigné via un secret Kubernetes, consultez la page Sécuriser une passerelle.

  3. Mettez à jour gateway.yaml avec le fichier manifeste suivant:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: servicemesh-cloud-gw
      namespace: istio-ingress
    spec:
      gatewayClassName: asm-l7-gxlb
      listeners:
      - name: http
        protocol: HTTP
        port: 80
        allowedRoutes:
          namespaces:
            from: All
      - name: https
        protocol: HTTPS
        port: 443
        allowedRoutes:
          namespaces:
            from: All
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: where-example-com
      addresses:
      - type: NamedAddress
        value: whereami-ip
    
  4. Redéployez la passerelle dans votre cluster:

    kubectl apply -f gateway.yaml
    
  5. Obtenez l'adresse IP de l'adresse IP statique:

    VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
    
  6. Utilisez curl pour accéder au domaine de la ressource Gateway. Comme le DNS n'est pas configuré pour ce domaine, utilisez l'option --resolve pour indiquer à curl de résoudre le nom de domaine sur l'adresse IP de la passerelle:

    curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
    

    Une fois l'opération terminée, le résultat ressemble à ce qui suit:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=where.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: where.example.com (matched)
    *  issuer: O=example; CN=where.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gke1",
      "host_header": "where.example.com",
      "metadata": "where-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "where-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

Le résultat détaillé inclut un handshake TLS réussi, suivi d'une réponse de l'application comme dans le résultat suivant. Cela prouve que TLS est correctement arrêté au niveau de la passerelle et que l'application répond au client de manière sécurisée.

Vous venez de déployer l'architecture suivante:

Architecture ASM

Le servicemesh-cloud-gw et sa GatewayClass asm-l7-gxlb ont extrait certains composants d'infrastructure interne pour simplifier l'expérience utilisateur. Cloud Load Balancing met fin au trafic TLS à l'aide d'un certificat interne et vérifie également l'état de la couche proxy de la passerelle d'entrée Anthos Service Mesh. Le whereami-route déployé dans le déploiement d'applications et de routage configure les proxys de passerelle d'entrée Anthos Service Mesh pour acheminer le trafic vers le service hébergé sur le maillage approprié.

Étapes suivantes