Déployer des services LoadBalancer multiréseaux

Ce document explique comment exposer des pods multiréseaux à des clients internes ou externes en créant des ressources d'équilibreur de charge réseau passthrough externe et d'équilibreur de charge réseau passthrough interne dans GKE. Google Cloud Elle décrit la configuration, les capacités et les limites requises des services LoadBalancer multiréseaux.

Si vous connectez des charges de travail à plusieurs réseaux VPC, utilisez un service Kubernetes de type LoadBalancer pour acheminer le trafic vers des pods sur un réseau secondaire spécifique. Lorsque vous créez le service, GKE crée un équilibreur de charge réseau direct pour gérer ce trafic.

Pour en savoir plus sur le multiréseau dans GKE, consultez À propos de la compatibilité multiréseau des pods.

Fonctionnement des services LoadBalancer multiréseaux

Pour exposer une charge de travail multiréseau, créez un Service de type: LoadBalancer. Le service doit inclure un sélecteur spécial qui cible les pods en fonction du réseau de leur interface secondaire. Ajoutez une annotation pour spécifier si vous souhaitez créer un équilibreur de charge interne ou externe.

Le libellé networking.gke.io/network dans le sélecteur filtre les points de terminaison par réseau. Ce libellé garantit que l'équilibreur de charge n'envoie le trafic qu'aux interfaces de pod connectées au réseau spécifié.

Limites

Les équilibreurs de charge multiréseaux présentent les limites suivantes :

  • Les services qui utilisent externalTrafficPolicy: Cluster ne sont pas acceptés.
  • Les services qui ciblent les pods hostNetwork ne sont pas acceptés.
  • La mise en réseau IPv6 et à double pile n'est pas prise en charge.
  • Vous ne pouvez pas modifier le réseau d'un service existant.
  • Seuls les réseaux de couche 3 sont acceptés.
  • Les équilibreurs de charge basés sur des pools cibles ou des backends de groupes d'instances ne sont pas acceptés.
  • Les services ClusterIP et NodePort ne sont pas compatibles avec les réseaux secondaires (non définis par défaut).

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  1. Suivez la procédure décrite dans Configurer la compatibilité multiréseau pour les pods afin de préparer vos réseaux VPC et de créer un cluster GKE avec un réseau supplémentaire.
  2. Assurez-vous que le sous-ensemble pour les équilibreurs de charge internes de couche 4 est activé dans votre cluster. Pour activer cette fonctionnalité, utilisez l'option --enable-l4-ilb-subsetting lorsque vous créez ou mettez à jour le cluster.
  3. Assurez-vous que votre cluster exécute GKE version 1.37 ou ultérieure.

Déployer des pods multiréseaux

Pour associer des pods à un réseau supplémentaire, créez un déploiement avec l'annotation networking.gke.io/interfaces. Cette annotation spécifie les réseaux et les interfaces pour les pods.

  1. Enregistrez le manifeste suivant sous le nom web-app-deployment.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-app
      labels:
        app: web-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web-app
      template:
        metadata:
          labels:
            app: web-app
          annotations:
            networking.gke.io/default-interface: 'eth1'
            networking.gke.io/interfaces: '[
              {"interfaceName":"eth0","network":"default"},
              {"interfaceName": "eth1","network": "dmz"}
            ]'
    spec:
      containers:
      - name: whereami
        image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
        ports:
        - containerPort: 8080
    

    Ce fichier manifeste crée un déploiement nommé web-app avec trois pods. Les pods comportent deux interfaces : eth0 connecté au réseau default et eth1 connecté au réseau dmz. L'annotation networking.gke.io/default-interface définit eth1 comme interface par défaut pour les pods.

  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f web-app-deployment.yaml
    

Si vous utilisez une interface non définie par défaut pour votre service, vous devez configurer le routage dans le pod. Pour configurer le routage, ajoutez un initContainer à la spécification de votre pod qui possède la fonctionnalité NET_ADMIN.

L'exemple suivant montre un initContainer qui ajoute un itinéraire par défaut pour l'interface eth1 :

initContainers:
      - name: init-routes-busybox
        image: busybox
        command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]

Dans la commande initContainer, remplacez 172.16.1.0/24 par la plage d'adresses IP secondaire de votre réseau de pods.

Déployer un service LoadBalancer interne

Pour exposer le déploiement web-app sur le réseau dmz, créez un service LoadBalancer interne.

  1. Enregistrez le manifeste suivant sous le nom internal-lb-service.yaml :

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-internal-lb
      namespace: default
      annotations:
        networking.gke.io/load-balancer-type: "Internal"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    Ce fichier manifeste crée un service avec les propriétés suivantes :

    • networking.gke.io/load-balancer-type: "Internal" : spécifie un équilibreur de charge réseau passthrough interne.
    • selector : sélectionne les pods portant le libellé app: web-app et connectés au réseau dmz.
  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f internal-lb-service.yaml
    

Déployer un service LoadBalancer externe

Pour exposer le déploiement web-app à des clients externes, créez un service LoadBalancer externe.

  1. Enregistrez le manifeste suivant sous le nom external-lb-service.yaml :

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-external-lb
      namespace: default
      annotations:
        cloud.google.com/l4-rbs: "enabled"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    Ce fichier manifeste crée un service avec les propriétés suivantes :

    • cloud.google.com/l4-rbs: "enabled" : spécifie un équilibreur de charge réseau passthrough externe basé sur un service de backend.
    • selector : sélectionne les pods portant le libellé app: web-app et connectés au réseau dmz.
  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f external-lb-service.yaml
    

Vérifier les services

Après avoir déployé les services, vérifiez que les équilibreurs de charge sont créés et configurés correctement.

  1. Vérifiez l'état des services :

    kubectl get services
    

    Le résultat ressemble à ce qui suit :

    NAME                  TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
    web-app-external-lb   LoadBalancer   10.8.47.77    35.239.57.231   80:31550/TCP   5m
    web-app-internal-lb   LoadBalancer   10.8.43.251   172.16.0.43     80:32628/TCP   6m
    kubernetes            ClusterIP      10.8.32.1     <none>          443/TCP        43h
    

    L'adresse EXTERNAL-IP de l'équilibreur de charge interne appartient au réseau dmz.

  2. Listez les règles de transfert de votre projet :

    gcloud compute forwarding-rules list
    

    Le résultat ressemble à ce qui suit :

    NAME                                                   REGION        IP_ADDRESS     IP_PROTOCOL  TARGET
    af901673cc0f24907a6aa8c3ce4afc21                       us-central1   35.239.57.231  TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot
    k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1   172.16.0.43    TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    
  3. Décrivez la règle de transfert de l'équilibreur de charge interne pour vérifier qu'elle est associée au bon réseau :

    gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION
    

    Remplacez REGION par la région de votre cluster.

    Le résultat renvoyé ressemble à ceci : Vérifiez que les champs network et subnetwork correspondent aux détails du réseau dmz.

    IPAddress: 172.16.0.43
    IPProtocol: TCP
    ...
    loadBalancingScheme: INTERNAL
    name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc
    ...
    subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
    

Tester les équilibreurs de charge

  1. Pour tester l'équilibreur de charge externe, envoyez une requête à son adresse IP externe :

    curl EXTERNAL_LB_IP:80
    

    Remplacez EXTERNAL_LB_IP par l'adresse IP externe du service web-app-external-lb.

  2. Pour tester l'équilibreur de charge interne, envoyez une requête depuis un hôte du même VPC que l'équilibreur de charge :

    curl INTERNAL_LB_IP:80
    

    Remplacez INTERNAL_LB_IP par l'adresse IP du service web-app-internal-lb.

Dépannage

Cette section explique comment résoudre les problèmes liés aux équilibreurs de charge multiréseaux.

Échec de la création de l'équilibreur de charge

Si la création de l'équilibreur de charge échoue, recherchez les messages d'erreur dans les événements de service :

kubectl describe service SERVICE_NAME

Remplacez SERVICE_NAME par le nom de votre service.

Un message d'erreur tel que network some-other-network does not exist indique que le réseau spécifié dans le sélecteur de service n'est pas défini dans le cluster. Vérifiez que le réseau existe :

kubectl get networks

Si le réseau existe, vérifiez que l'objet Network fait correctement référence à une ressource GKENetworkParamSet valide. Pour rechercher les erreurs de configuration, inspectez l'état de la ressource Network :

kubectl get networks NETWORK_NAME -o yaml

Remplacez NETWORK_NAME par le nom du réseau.

Dans une configuration valide, les conditions ParamsReady et Ready sont True. Si ParamsReady n'est pas True, assurez-vous que le parametersRef dans la spécification Network correspond correctement au nom, au type et au groupe d'une ressource GKENetworkParamSet existante.

Si la ressource Network est correcte, mais qu'elle n'est toujours pas prête, vérifiez l'état de la ressource GKENetworkParamSet référencée pour détecter les erreurs, comme une absence de sous-réseau :

kubectl get gkenetworkparamsets GNP_NAME -o yaml

Remplacez GNP_NAME par le nom de votre GKENetworkParamSet.

L'équilibreur de charge n'a aucun backend

Si l'équilibreur de charge est provisionné, mais qu'il ne comporte aucun backend opérationnel, procédez comme suit :

  1. Vérifiez qu'il existe un pool de nœuds avec des interfaces réseau dans le réseau utilisé par le service.
  2. Vérifiez que les pods sélectionnés par le service sont en cours d'exécution.
  3. Vérifiez les points de terminaison du service :

    kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAME
    

    Le contrôleur multinet-endpointslice-controller.gke.io crée les points de terminaison multiréseaux. Les adresses IP des pods listées dans EndpointSlice appartiennent au réseau utilisé par le service. Si EndpointSlice ne comporte aucun point de terminaison, vérifiez que les libellés du sélecteur de service correspondent aux pods en cours d'exécution et que le sélecteur de réseau correspond au réseau des pods.

Étapes suivantes