Utiliser GKE Dataplane V2


Cette page explique comment activer GKE Dataplane V2 pour Google Kubernetes Engine (GKE).

Les nouveaux clusters Autopilot disposent de GKE Dataplane V2 activé dans les versions 1.22.7-gke.1500 et ultérieures, et les versions 1.23.4-gke.1500 et ultérieures. Si vous rencontrez des problèmes avec GKE Dataplane V2, passez à la section Dépannage.

Créer un cluster GKE avec GKE Dataplane V2

Vous pouvez activer GKE Dataplane V2 lorsque vous créez des clusters avec GKE version 1.20.6-gke.700 ou une version ultérieure en utilisant gcloud CLI ou l'API Kubernetes Engine. Vous pouvez également activer GKE Dataplane V2 dans la version Bêta lorsque vous créez des clusters avec GKE version 1.17.9 ou une version ultérieure.

Console

Pour créer un cluster avec GKE Dataplane V2, procédez comme suit :

  1. Accédez à la page Google Kubernetes Engine dans la console Google Cloud.

    Accéder à Google Kubernetes Engine

  2. Cliquez sur Créer.

  3. Cliquez sur Configurer pour configurer un cluster standard.

  4. Dans la section "Réseau", cochez la case Activer Dataplane V2. L'option "Activer la règle de réseau Kubernetes" est désactivée lorsque vous sélectionnez "Activer Dataplane V2", car l'application de la règle de réseau est intégrée à GKE Dataplane V2.

  5. Cliquez sur Create (Créer).

gcloud

Pour créer un cluster avec GKE Dataplane V2, utilisez la commande suivante :

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --enable-ip-alias \
    --release-channel CHANNEL_NAME \
    --location COMPUTE_LOCATION

Remplacez les éléments suivants :

  • CLUSTER_NAME : nom de votre nouveau cluster
  • CHANNEL_NAME : canal de publication incluant la version 1.20.6-gke.700 ou ultérieure de GKE. Si vous préférez ne pas utiliser de canal de publication, vous pouvez également utiliser l'option --cluster-version au lieu de --release-channel, en spécifiant la version 1.20.6-gke.700 ou ultérieure.
  • COMPUTE_LOCATION : emplacement Compute Engine du nouveau cluster.

API

Pour créer un cluster avec GKE Dataplane V2, spécifiez le champ datapathProvider dans l'objet networkConfig dans la requête create du cluster.

L'extrait de code JSON suivant montre la configuration nécessaire pour activer GKE Dataplane V2 :

"cluster":{
   "initialClusterVersion":"VERSION",
   "ipAllocationPolicy":{
      "useIpAliases":true
   },
   "networkConfig":{
      "datapathProvider":"ADVANCED_DATAPATH"
   },
   "releaseChannel":{
      "channel":"CHANNEL_NAME"
   }
}

Remplacez les éléments suivants :

  • VERSION : version de votre cluster, qui doit être la version 1.20.6-gke.700 ou ultérieure de GKE.
  • CHANNEL_NAME : canal de publication incluant la version 1.20.6-gke.700 ou ultérieure de GKE.

Résoudre les problèmes liés à GKE Dataplane V2

Cette section explique comment examiner et résoudre les problèmes liés à GKE Dataplane V2.

  1. Vérifiez que GKE Dataplane V2 est activé :

    kubectl -n kube-system get pods -l k8s-app=cilium -o wide
    

    Si GKE Dataplane V2 est en cours d'exécution, la sortie inclut les pods portant le préfixe anetd-. anetd est le contrôleur réseau pour GKE Dataplane V2.

  2. Si le problème concerne les services ou l'application de la règle de réseau, consultez les journaux du pod anetd. Utilisez les sélecteurs de journal suivants dans Cloud Logging :

    resource.type="k8s_container"
    labels."k8s-pod/k8s-app"="cilium"
    resource.labels.cluster_name="CLUSTER_NAME"
    
  3. Si la création de pod échoue, consultez les journaux du kubelet pour obtenir des indices. Utilisez les sélecteurs de journal suivants dans Cloud Logging :

    resource.type="k8s_node"
    log_name=~".*/logs/kubelet"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    Remplacez CLUSTER_NAME par le nom du cluster ou supprimez-le complètement pour afficher les journaux de tous les clusters.

Problèmes connus

Les plages de ports des règles de réseau ne prennent pas effet

Si vous spécifiez un champ endPort dans une règle de réseau sur un cluster sur lequel GKE Dataplane V2 est activé, il ne sera pas appliqué.

À partir de la version 1.22 de GKE, l'API Network Policy de Kubernetes vous permet de spécifier une plage de ports sur lesquels la règle de réseau est appliquée. Cette API est compatible avec les clusters utilisant une règle de réseau Calico, mais pas avec les clusters avec GKE Dataplane V2.

Vous pouvez vérifier le comportement des objets NetworkPolicy en les lisant après avoir écrit sur le serveur d'API. Si l'objet contient toujours le champ endPort, la fonctionnalité est appliquée. Si le champ endPort n'est pas renseigné, la fonctionnalité n'est pas appliquée. Dans tous les cas, l'objet stocké dans le serveur d'API est la source de vérité pour la règle de réseau.

Pour plus d'informations, consultez KEP-2079 : Règles de réseau compatibles avec les plages de ports.

Les pods affichent le message d'erreur failed to allocate for range 0: no IP addresses available in range set

Versions de GKE concernées : 1.22 à 1.25

Les clusters GKE exécutant des pools de nœuds qui utilisent containerd et pour lesquels GKE Dataplane V2 est activé peuvent rencontrer des problèmes de fuite d'adresses IP et épuiser toutes les adresses IP des pods d'un nœud. Un pod planifié sur un nœud affecté affiche un message d'erreur semblable à celui-ci :

failed to allocate for range 0: no IP addresses available in range set: 10.48.131.1-10.48.131.62

Pour plus d'informations sur le problème, reportez-vous au conteneur problème nº 5768.

Versions corrigées

Pour résoudre ce problème, mettez à niveau votre cluster vers l'une des versions GKE suivantes :

  • 1.22.17-gke.3100 (et versions ultérieures).
  • 1.23.16-gke.200 (et versions ultérieures).
  • 1.24.9-gke.3200 (et versions ultérieures).
  • 1.25.6-gke.200 (et versions ultérieures)

Solutions pour les clusters GKE standards

Vous pouvez atténuer ce problème en supprimant les adresses IP de pod divulguées pour le nœud.

Pour supprimer les adresses IP des pods divulguées, obtenez des identifiants d'authentification pour le cluster et exécutez les étapes suivantes pour nettoyer un seul nœud, si vous connaissez son nom.

  1. Enregistrez le script shell suivant dans un fichier nommé cleanup.sh :

    for hash in $(sudo find /var/lib/cni/networks/gke-pod-network -iregex '/var/lib/cni/networks/gke-pod-network/[0-9].*' -exec head -n1 {} \;); do hash="${hash%%[[:space:]]}"; if [ -z $(sudo ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then sudo grep -ilr $hash /var/lib/cni/networks/gke-pod-network; fi; done | sudo xargs -r rm
    
  2. Exécutez le script sur un nœud de cluster :

    gcloud compute ssh --zone "ZONE" --project "PROJECT" NODE_NAME --command "$(cat cleanup.sh)"
    

    Remplacez NODE_NAME par le nom du nœud.

Vous pouvez également exécuter une version DaemonSet de ce script pour l'exécuter en parallèle sur tous les nœuds à la fois :

  1. Enregistrez le fichier manifeste suivant dans un fichier nommé cleanup-ips.yaml :

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: cleanup-ipam-dir
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          name: cleanup-ipam
      template:
        metadata:
          labels:
            name: cleanup-ipam
        spec:
          hostNetwork: true
          securityContext:
            runAsUser: 0
            runAsGroup: 0
          containers:
          - name: cleanup-ipam
            image: gcr.io/gke-networking-test-images/ubuntu-test:2022
            command:
              - /bin/bash
              - -c
              - |
                while true; do
                for hash in $(find /hostipam -iregex '/hostipam/[0-9].*' -mmin +10 -exec head -n1 {} \; ); do
                hash="${hash%%[[:space:]]}"
                if [ -z $(ctr -n k8s.io c ls | grep $hash | awk '{print $1}') ]; then
                grep -ilr $hash /hostipam
                fi
                done | xargs -r rm
                echo "Done cleaning up /var/lib/cni/networks/gke-pod-network at $(date)"
                sleep 120s
                done
            volumeMounts:
            - name: host-ipam
              mountPath: /hostipam
            - name: host-ctr
              mountPath: /run/containerd
          volumes:
          - name: host-ipam
            hostPath:
              path: /var/lib/cni/networks/gke-pod-network
          - name: host-ctr
            hostPath:
              path: /run/containerd
    
  2. Exécutez le daemonset sur le cluster :

    kubectl apply -f cleanup-ips.yaml
    

    Vous devez disposer d'un accès à kubectl en tant qu'administrateur du cluster pour exécuter cette commande.

  3. Vérifiez les journaux du DaemonSet en cours d'exécution :

    kubectl -n kube-system logs -l name=cleanup-ipam
    

La règle de réseau supprime une connexion en raison d'une recherche de suivi des connexions incorrecte

Lorsqu'un pod client se connecte lui-même via un Service ou l'adresse IP virtuelle d'un équilibreur de charge réseau interne à stratégie directe, le paquet de réponse n'est pas identifié comme faisant partie d'une connexion existante en raison d'une recherche conntrack incorrecte dans le plan de données. Cela signifie qu'une règle de réseau qui limite le trafic entrant pour le pod est appliquée de manière incorrecte sur le paquet.

L'impact de ce problème dépend du nombre de pods configurés pour le service. Par exemple, si le service dispose d'un pod de backend, la connexion échoue toujours. Si le service dispose de deux pods de backend, la connexion échoue la moitié du temps.

Versions corrigées

Pour résoudre ce problème, mettez à niveau votre cluster vers l'une des versions GKE suivantes :

  • 1.28.3-gke.1090000 (et versions ultérieures).

Solutions

Vous pouvez limiter les conséquences de ce problème en configurant la même valeur pour port et containerPort dans le fichier manifeste du Service.

Suppressions de paquets pour les flux de connexion "hairpin"

Lorsqu'un pod crée une connexion TCP vers lui-même à l'aide d'un service, de sorte que le pod est à la fois la source et la destination de la connexion, le suivi des connexions GKE Dataplane V2 eBPF suit les états de connexion de manière incorrecte, ce qui entraîne des fuites dans les entrées conntrack.

En cas de fuite d'un tuple de connexion (protocole, adresse IP source/de destination et port source/de destination), les nouvelles connexions utilisant le même tuple de connexion peuvent entraîner des suppressions de paquets de retour.

Versions corrigées

Pour résoudre ce problème, mettez à niveau votre cluster vers l'une des versions GKE suivantes :

  • 1.28.3-gke.1090000 (et versions ultérieures)
  • 1.27.11-gke.1097000 (et versions ultérieures)

Solutions

Utilisez l'une des solutions suivantes :

  • Activez la réutilisation TCP (message keep-alive) pour les applications exécutées dans des pods pouvant communiquer avec eux-mêmes à l'aide d'un service. Cette solution permet d'empêcher l'envoi de l'option TCP FIN et d'éviter les fuites sur l'entrée conntrack.

  • Lorsque vous utilisez des connexions de courte durée, exposez le pod à l'aide d'un équilibreur de charge proxy, tel que Gateway, pour exposer le service. La destination de la requête de connexion est alors définie sur l'adresse IP de l'équilibreur de charge, ce qui empêche GKE Dataplane V2 d'effectuer une traduction d'adresse réseau source (SNAT) vers l'adresse IP de rebouclage.

Étapes suivantes