Résoudre les problèmes d'observabilité du réseau GKE

Ce document fournit des instructions et des procédures de diagnostic pour identifier les problèmes de mise en réseau dans les clusters Google Kubernetes Engine (GKE) à l'aide de l'observabilité GKE Dataplane V2, Hubble et Cloud Monitoring.

Pour obtenir une présentation de l'architecture et des bonnes pratiques conceptuelles, consultez Bonnes pratiques pour l'observabilité du réseau.

Arbre de décision pour le dépannage et concepts fondamentaux

Avant de consulter les procédures, utilisez la matrice de décision suivante pour identifier le niveau de la pile réseau GKE qui est susceptible de provoquer votre problème, puis accédez à la section correspondante.

Problème constaté ou question de diagnostic Niveau suspecté Procédure recommandée
Les pods ne parviennent pas à résoudre les domaines externes ni les services Kubernetes internes (délai d'expiration DNS, NXDOMAIN, SERVFAIL). Niveau 1 : Pod et service (DNS) Diagnostiquer les échecs de résolution DNS
Les services ne peuvent pas communiquer : délais de connexion dépassés ou paquets supprimés entre les pods. Niveau 1 : Pod et service (perte de paquets ou de règles) Diagnostiquer les pertes de paquets et les blocages NetworkPolicy
Les répliques de charge de travail ont une charge de trafic inégale ou les pods enregistrent des taux élevés de réinitialisations TCP (RST). Niveau 1 : Pod et service (équilibrage de charge ou transport) Diagnostiquer le déséquilibre du trafic et les réinitialisations TCP
Latence générale, délais d'attente intermittents ou redémarrages CNI sur les nœuds. Niveau 2 : Nœud et CNI (noyau) Triage pour la latence au niveau des nœuds et les goulots d'étranglement CNI
Les pods ne peuvent pas accéder aux ressources en dehors de GKE (Cloud SQL, API externes ou autres VPC). Niveau 3 : VPC et routage Isoler les problèmes de connectivité GKE par rapport aux problèmes de connectivité VPC ou externe
Vous avez besoin d'une simulation de chemin automatisée pour vérifier si les règles de pare-feu, les routes ou les NetworkPolicies bloquent le trafic. Niveau 3 : VPC et routage (simulation) Diagnostiquer la connectivité à l'aide des tests de connectivité
Vous devez identifier les charges de travail qui envoient du trafic vers Internet et qui sont soumises à la traduction d'adresse réseau (NAT). Niveau 4 : Passerelle externe et coût Identifier le trafic NAT (sortie vers Internet)
Frais de transfert de données interzones élevés ou besoin de visualiser les principaux interlocuteurs sans écrire de requêtes SQL. Niveau 4 : Passerelle externe et coût Analyser les coûts et les performances du trafic de cluster à l'aide de Flow Analyzer

Concepts de base en termes de mise en réseau

Si vous débutez avec Kubernetes ou la mise en réseau Google Cloud , gardez à l'esprit les concepts de base suivants :

  • eBPF (Extended Berkeley Packet Filter) : technologie de système d'exploitation qui permet d'exécuter des programmes de surveillance et de routage sécurisés directement dans le noyau Linux. GKE Dataplane V2 utilise eBPF pour acheminer les paquets et appliquer les NetworkPolicies avec une surcharge de performances minimale.
  • Masquage d'adresses IP (SNAT) : processus de réécriture de l'adresse IP source d'un paquet. Lorsqu'un pod GKE (qui possède une adresse IP privée) communique avec Internet ou des ressources VPC externes, GKE masque (réécrit) l'adresse IP du pod en adresse IP du nœud afin que les systèmes externes sachent comment acheminer la réponse.
  • Suivi des connexions (conntrack) : fonctionnalité du noyau qui suit toutes les connexions réseau actives. Dans les clusters GKE Dataplane V2, ce suivi est réparti entre deux tables : la table conntrack standard du kernel Linux (utilisée par ip-masq-agent) et une table conntrack gérée par Cilium et GKE Dataplane V2, stockée dans une carte eBPF. Si un nœud gère trop de connexions simultanées, l'une ou l'autre de ces tables de suivi peut se remplir (épuisement de conntrack), ce qui entraîne la suppression silencieuse des nouveaux paquets par le nœud.
  • Hubble : moteur d'observabilité pour GKE Dataplane V2. Il s'exécute sur eBPF et offre une visibilité en temps réel sur les flux de trafic, les pertes de paquets et l'évaluation NetworkPolicy.

Niveau 1 : Observabilité des pods et des services (applications)

Le niveau "Pod et service" couvre la communication réseau entre les pods, les services et le DNS du cluster. Les problèmes de ce niveau se manifestent généralement par des délais d'expiration de connexion d'application, des échecs de résolution de noms ou une répartition inégale de la charge.

Diagnostiquer les échecs de résolution DNS

Avant de résoudre les problèmes DNS, examinez le champ d'application du diagnostic et les conditions préalables :

  • Domaine concerné : communication entre les pods et CoreDNS ou NodeLocal DNSCache, latence DNS, délais d'expiration de la résolution DNS en amont et validation NetworkPolicy du nom de domaine complet.
  • Conditions préalables : métriques GKE Dataplane V2 activées ; accès kubectl.
  • Compatibilité CNI : GKE Dataplane V2 (chemin de données avancé) et CNI GKE standard.
  • Symptôme : les journaux des pods indiquent dial tcp: lookup <domain>: i/o timeout, NXDOMAIN ou une latence intermittente sur les appels d'API sortants.
  • Objectif : déterminer si l'échec DNS provient de l'intérieur du cluster (saturation de kube-dns ou de NodeLocal DNSCache), d'une règle NetworkPolicy bloquant le port 53 UDP ou TCP, ou d'une dégradation du réseau en amont.

Étape 1 : Vérification de base de l'accessibilité

Avant de résoudre les problèmes liés aux couches DNS, vérifiez si la destination est directement accessible à l'aide de son adresse IP à partir du pod concerné :

# 1. Test raw IP reachability (bypasses DNS entirely)
kubectl exec -it my-pod -n default -- curl -v --connect-timeout 5 http://10.240.0.10:8080

# 2. Test domain resolution
kubectl exec -it my-pod -n default -- curl -v --connect-timeout 5 http://my-service.default.svc.cluster.local:8080
  • Si la connexion IP réussit, mais que le domaine échoue : le problème est isolé au niveau de la résolution DNS. Passez à l'étape 2.
  • Si les deux échouent : le problème concerne le routage ou l'application des règles au niveau du réseau. Passez à Diagnostiquer les pertes de paquets et les blocages NetworkPolicy.
Vérifier le préremplissage DNS de FQDNNetworkPolicy

Si votre cluster utilise des NetworkPolicies basées sur des FQDN (FQDNNetworkPolicy), vérifiez que le nom de domaine est explicitement autorisé. Si un pod interroge un domaine externe qui n'est pas prérempli dans le cache du proxy DNS GKE Dataplane V2 ou qui n'est pas autorisé par la règle, GKE Dataplane V2 bloque le trafic de sortie vers l'adresse IP résolue :

# Verify whether UDP or TCP port 53 egress is permitted in the Pod's namespace
kubectl get networkpolicy -n default -o yaml | grep -A 5 -B 2 "port: 53"

Étape 2 : Vérifier les métriques DNS dans Cloud Monitoring

GKE expose des métriques DNS intégrées dans Cloud Monitoring sous le préfixe kubernetes.io/networking/dns/.

Pour vérifier les métriques DNS dans Cloud Monitoring, procédez comme suit :

  1. Dans la console Google Cloud , accédez à Cloud Monitoring > Tableaux de bord.
  2. Sélectionnez le tableau de bord prédéfini Observabilité DNS GKE – Vue du cluster (ou accédez à l'explorateur de métriques et filtrez sur kubernetes.io/networking/dns/).
  3. Évaluez les signaux principaux suivants (pour NodeLocal DNSCache, remplacez kubedns par node_local_dns dans le chemin d'accès de la métrique) :
Nom de la métrique Seuil d'avertissement Origine du problème
kubernetes.io/networking/dns/kubedns/max_concurrent_rejected_request_count > 0 Limite de requêtes simultanées atteinte. kube-dns ou NodeLocal DNSCache abandonne des requêtes.
kubernetes.io/networking/dns/kubedns/dns_request_latencies p99 > 100 ms Latence de résolution DNS de bout en bout élevée dans kube-dns ou NodeLocal DNSCache.
kubernetes.io/networking/dns/kubedns/forwarding_request_latencies p99 > 100 ms Latence ou saturation du serveur DNS en amont.
Séquence de triage des performances et des délais d'expiration DNS

Suivez cette séquence de triage pour diagnostiquer la latence DNS, les échecs de cache et les délais d'expiration en amont :

  1. Vérifiez le taux d'accès au cache : requête kubernetes.io/networking/dns/kubedns/dns_cache_request_count (ou node_local_dns/dns_cache_request_count) regroupée par libellé cache_status. Si cache_status="hit" est faible et cache_status="miss" est élevé, il est possible que les applications émettent des requêtes non FQDN (par exemple, my-service au lieu de my-service.default.svc.cluster.local), ce qui entraîne une traversée du chemin de recherche dans toutes les entrées de /etc/resolv.conf.
  2. Évaluez la latence en amont : une valeur forwarding_request_latencies élevée indique des problèmes avec le serveur DNS en amont (par exemple, le DNS d'entreprise sur site accessible via Cloud Interconnect ou Cloud VPN, ou les limites de Cloud DNS).
  3. Auditez les substitutions DNS personnalisées : inspectez les ConfigMaps kube-dns personnalisés pour détecter les stubs ou les transferts en amont mal configurés :

    kubectl get configmap kube-dns -n kube-system -o yaml
    

Étape 3 : Diffusez le trafic DNS en direct avec la CLI Hubble

Utilisez l'alias d'assistance de la CLI Hubble pour inspecter les requêtes et réponses DNS en direct diffusées depuis le noyau du nœud :

# 1. Ensure the helper alias is set in your terminal session
alias gke-hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"

# 2. Observe live DNS (Port 53) traffic for a specific Pod
gke-hubble observe --pod default/my-pod --port 53

Étape 4 : Valider la correction

Si des rejets de requêtes simultanés se sont produits, appliquez NodeLocal DNSCache pour absorber les résolutions DNS à haute fréquence directement sur le nœud sans atteindre les limites kube-dns à l'échelle du cluster :

# Verify NodeLocal DNSCache DaemonSet is running
kubectl get daemonset node-local-dns -n kube-system

Diagnostiquer les pertes de paquets et les blocages NetworkPolicy

Avant d'examiner les pertes de paquets et les refus de règles, vérifiez le champ d'application du diagnostic et les conditions préalables :

  • Domaine concerné : baisse du trafic entre les objets Pod ou entre les objets Pod et Service, application de NetworkPolicy, raisons de suppression eBPF du noyau.
  • Conditions préalables : l'observabilité des flux GKE Dataplane V2 est activée et la journalisation NetworkPolicy est configurée.
  • Compatibilité CNI : GKE Dataplane V2 uniquement.
  • Problème : les tentatives de connexion à l'application échouent avec Connection timed out ou Connection reset by peer.
  • Objectif : identifier précisément la raison pour laquelle NetworkPolicy ou eBPF abandonne les paquets sans avoir à modifier les règles de sécurité par essais et erreurs.

Étape 1 : Surveillez les métriques de drop Hubble

Lorsque GKE Dataplane V2 supprime un paquet, il émet la métrique hubble_drop_total taguée avec le motif de suppression et les métadonnées de source et de destination. Pour surveiller les métriques de perte Hubble, procédez comme suit :

  1. Si ce n'est pas déjà fait, déployez une ressource PodMonitoring Google Cloud Managed Service pour Prometheus afin de récupérer les métriques Hubble :

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: hubble-metrics
      namespace: gke-managed-dpv2-observability
    spec:
      selector:
        matchLabels:
          k8s-app: cilium
      endpoints:
      - port: hubble-metrics
        interval: 30s
    
  2. Exécutez la requête suivante dans Cloud Monitoring > Explorateur de métriques pour afficher les abandons par motif :

    sum by (reason) (rate(hubble_drop_total[5m])) > 0
    
  3. Interprétez les codes reason courants :

    • Policy denied : une règle de réseau Kubernetes bloque explicitement ou implicitement la connexion.
    • CT: Map insertion failed : la table de suivi des connexions (conntrack) est épuisée.
    • Unsupported L3 protocol : paquet non IPv4 ou IPv6, ou en-tête corrompu.

Étape 2 : Vérifier les journaux NetworkPolicy dans Cloud Logging

La journalisation NetworkPolicy exporte des journaux JSON structurés pour toutes les décisions concernant les règles. Pour interroger les journaux NetworkPolicy dans Cloud Logging, procédez comme suit :

  1. Dans la console Google Cloud , accédez à Cloud Logging > Explorateur de journaux.
  2. Exécutez la requête suivante :

    resource.type="k8s_node"
    log_name:"projects/PROJECT_ID/logs/events"
    jsonPayload.connection.verdict="DENY"
    jsonPayload.src.pod_name="my-source-pod"
    
  3. Inspectez la charge utile JSON :

    • jsonPayload.drop_reason : indique la raison pour laquelle le paquet a été supprimé.
    • jsonPayload.policies : liste les NetworkPolicies qui ont été évaluées. Si une liste vide est renvoyée avec un verdict DENY, l'espace de noms fonctionne en mode "refus par défaut" et aucune règle n'a autorisé le trafic.

Si aucun journal NetworkPolicy ne s'affiche, vérifiez que la journalisation est activée dans la ressource personnalisée NetworkLogging du cluster. Par exemple, vérifiez que le champ spec.cluster.deny.log est défini sur true :

kubectl get networklogging default -o yaml

Étape 3 : Suivre les drops en direct avec la CLI Hubble

Diffusez des drops en direct en utilisant la CLI Hubble pour inspecter les paquets en temps réel :

gke-hubble observe --verdict DROPPED --namespace default --follow

Exemple de résultat :

TIMESTAMP             SOURCE               DESTINATION          TYPE     VERDICT
10:14:22.102          default/frontend     default/backend:80   to-stack DROPPED (Policy denied by NetworkPolicy: backend-deny-all)

Le résultat indique la NetworkPolicy exacte qui bloque le trafic (backend-deny-all).

Étape 4 : Vérifiez si le suivi des connexions est épuisé

Si le motif de la suppression indique CT: Map insertion failed :

  1. Inspectez le journal de l'agent GKE Dataplane V2 pour détecter la saturation de la table conntrack :

    kubectl logs -n kube-system daemonset/anetd -c cilium-agent --tail=100 | grep "Conntrack table full"
    
  2. Vérifiez la taille maximale de la table conntrack sur le nœud concerné :

    kubectl exec -it -n kube-system daemonset/anetd -c cilium-agent -- cilium status --all-controllers | grep -i conntrack
    

    Si la table conntrack est pleine, effectuer un scaling horizontal de vos charges de travail sur davantage de nœuds ou réduisez le taux de connexion des pods clients.


Diagnostiquer le déséquilibre du trafic et les réinitialisations TCP

Avant de résoudre les problèmes de déséquilibre du trafic et de réinitialisation de la connexion, examinez le champ d'application du diagnostic et les conditions préalables :

  • Domaine concerné : déséquilibre de l'équilibrage de charge, échecs de handshake TCP, arrêt soudain de la connexion.
  • Prérequis : métriques GKE Dataplane V2 activées.
  • Compatibilité CNI : GKE Dataplane V2.
  • Symptôme : certaines répliques de pod reçoivent un trafic excessif, tandis que d'autres restent inactives. Les applications clientes enregistrent connection reset by peer ou broken pipe.
  • Objectif : Déterminer si le déséquilibre du trafic est dû à la persistance des connexions au niveau de la couche transport (couche 4 de l'OSI, TCP) ou de la couche application (couche 7 de l'OSI, HTTP/2 ou gRPC), et identifier la source des paquets TCP RST.

Étape 1 : Comparez le flux de trafic au niveau du pod

Pour déterminer si le trafic est réparti de manière uniforme sur vos répliques, procédez comme suit :

  1. Dans Cloud Monitoring, interrogez le nombre de flux d'entrée pour tous les pods d'un déploiement :

    sum by (pod) (rate(pod_flow_ingress_flows_count{destination_workload="my-service"}[5m]))
    
  2. Évaluez la répartition du trafic entre les pods. Si un seul pod reçoit la majorité du trafic, examinez la réutilisation des connexions ou les sessions persistantes :

    • gRPC ou HTTP/2 : les connexions TCP de longue durée entraînent la traversée d'un seul flux TCP vers un seul pod de backend pour toutes les requêtes. Le routage des services Kubernetes de la couche transport (couche 4 de l'OSI, TCP) ne peut pas équilibrer les requêtes à l'intérieur d'une connexion HTTP/2 établie.
    • Affinité de session ClientIP : vérifiez si le service est configuré avec sessionAffinity: ClientIP.
    • Services sans adresse IP de cluster : les clients peuvent résoudre le DNS une seule fois et mettre en cache l'adresse IP unique de manière permanente.

Étape 2 : Analysez les métriques de réinitialisation TCP

Les réinitialisations TCP (RST) mettent fin immédiatement aux connexions. Ils sont émis par le noyau du système d'exploitation lorsqu'un point de terminaison reçoit un paquet pour un port inconnu ou lorsqu'une application ferme une connexion avec des données non lues dans le tampon.

Exécutez la requête MQL suivante dans Cloud Monitoring :

fetch prometheus_target
| metric 'prometheus.googleapis.com/hubble_tcp_flags_total/counter'
| filter (metric.flag == 'RST')
| align rate(1m)
| every 1m
| group_by [metric.source, metric.destination, metric.traffic_direction], sum(val())

Examinez les résultats de la requête pour déterminer la source de la réinitialisation :

  • RST sortant (traffic_direction=egress) : le pod local génère la réinitialisation. Vérifiez si l'application Pod plante, atteint sa limite de connexion ou rejette activement la connexion.
  • RST entrant (traffic_direction=ingress) : le pair distant (base de données externe, API ou pod distant) a envoyé la réinitialisation. Vérifiez l'état du serveur de destination et du pare-feu.

Étape 3 : Diffusez les réinitialisations TCP en direct

Utilisez la CLI Hubble pour capturer l'établissement de liaison de réinitialisation en direct :

gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST --namespace default

Étape 4 : Correction et solutions pratiques

Appliquez les étapes de résolution suivantes en fonction de la cause de votre déséquilibre de trafic ou de vos réinitialisations TCP :

  • Pour la persistance de connexion au niveau de l'application (couche 7 de l'OSI) ou gRPC :
    • Déployez Cloud Service Mesh pour activer l'équilibrage de charge au niveau des requêtes de la couche application (couche 7 de l'OSI).
    • Configurez des limites de connexion côté client ou des délais d'inactivité (par exemple, gRPC MAX_CONNECTION_AGE et MAX_CONNECTION_AGE_GRACE) pour forcer le rétablissement périodique de la connexion.
  • Pour l'affinité d'adresse IP de service : supprimez service.spec.sessionAffinity, sauf si l'état de l'application l'exige strictement.
  • Pour la mise en cache DNS des services sans adresse IP de cluster : assurez-vous que les environnements d'exécution des applications (tels que JVM networkaddress.cache.ttl) ne mettent pas en cache les résultats DNS indéfiniment.
  • En cas de dépassement de la capacité de la file d'attente des applications : lorsque la file d'attente d'écoute d'une application est pleine, le noyau Linux supprime les paquets SYN entrants ou envoie un paquet TCP RST. Effectuez un scaling horizontal des répliques de pod ou augmentez le backlog d'écoute de l'application (somaxconn).

Niveau 2 : Observabilité des nœuds et des CNI (noyau)

Le niveau du nœud et du CNI englobe le noyau Linux de l'hôte, les programmes eBPF et les interfaces réseau du nœud. Les goulots d'étranglement à ce niveau affectent toutes les charges de travail exécutées sur le nœud concerné.

Vérification de l'intégrité du système : détection des correctifs non autorisés d'anetd

GKE Dataplane V2 s'exécute en tant que DaemonSet géré (anetd) dans l'espace de noms kube-system. Dans Cloud Logging, vous pouvez interroger les journaux d'audit Kubernetes pour détecter si des utilisateurs non autorisés ou des scripts automatisés ont corrigé ou redémarré anetd :

protoPayload.methodName="io.k8s.core.v1.daemonsets.patch" OR
protoPayload.methodName="io.k8s.core.v1.daemonsets.update"
protoPayload.resourceName="namespaces/kube-system/daemonsets/anetd"

Si un correctif non autorisé est détecté, rétablissez la configuration par défaut du DaemonSet ou déclenchez la recréation d'un pool de nœuds pour restaurer l'état géré.


Triage pour la latence au niveau des nœuds et les goulots d'étranglement CNI

Avant de diagnostiquer la latence au niveau des nœuds et les goulots d'étranglement du kernel, examinez le champ d'application du diagnostic et les prérequis :

  • Domaine d'intérêt : latence du noyau hôte, perte de paquets au niveau de l'interface de la VM, saturation de l'agent eBPF GKE Dataplane V2, épuisement de conntrack.
  • Prérequis : métriques de VM Compute Engine activées ; accès kubectl.
  • Compatibilité CNI : GKE Dataplane V2 et CNI GKE standard.
  • Symptôme : le trafic entre les nœuds connaît des pics de latence ou des baisses aléatoires, tandis que le trafic à l'intérieur des nœuds reste normal.
  • Objectif : différencier la limitation de bande passante réseau des VM hôtes, les pertes de paquets du noyau Linux et les goulots d'étranglement au niveau du CNI.

Étape 1 : Différencier les problèmes extérieurs à GKE de ceux qui se produisent dans GKE

Exécutez le test de référence de VM Compute Engine : déployez une VM Compute Engine autonome dans le même sous-réseau VPC que les nœuds du cluster GKE. Testez la connectivité de la VM à la destination cible.

Étape 2 : Différencier les problèmes liés aux applications de ceux liés aux nœuds et au niveau CNI

Pour déterminer si la latence provient de l'application ou du niveau CNI et du nœud, procédez comme suit :

  1. Vérifiez la saturation des ressources de l'application : assurez-vous que le nœud ne subit pas de limitation du processeur ni de pression sur la mémoire, ce qui retarde le traitement des paquets dans l'espace utilisateur :

    kubectl top nodes
    kubectl top pods -n default
    
  2. Inspecter le nombre de connexions suivies du noyau Linux : vérifiez le nombre de connexions suivies actives sur l'hôte :

    # On a node where you have debugging access
    cat /proc/sys/net/netfilter/nf_conntrack_count
    cat /proc/sys/net/netfilter/nf_conntrack_max
    

    Si nf_conntrack_count approche de nf_conntrack_max, le kernel hôte supprime les nouveaux paquets TCP SYN.

Étape 3 : Vérifiez les pertes de paquets au niveau de la VM à l'aide de la télémétrie Compute Engine

Google Cloud Compute Engine exporte les métriques d'interface réseau au niveau de la VM vers Cloud Monitoring.

Dans Cloud Monitoring > Explorateur de métriques, exécutez la requête suivante :

sum by (drop_reason) (rate(compute_googleapis_com:instance_network_dropped_packets_count[5m]))
  • FQ_CODEL_DROP : paquet supprimé en raison de la saturation de la file d'attente Fair Queuing ou CoDel (limite de bande passante de sortie de la VM dépassée).
  • FIREWALL_RULE_DROP : paquet supprimé par une règle de pare-feu VPC.
  • RATE_LIMIT_DROP : paquet supprimé, car la VM a dépassé son quota maximal de paquets par seconde (PPS) pour l'interface réseau.

Étape 4 : Examiner les pertes au niveau du noyau à l'aide d'eBPF

Si les métriques au niveau de la VM n'indiquent aucune perte, mais que les pods GKE perdent toujours des paquets, inspectez l'agent GKE Dataplane V2 (anetd) pour détecter les pertes de cartes eBPF :

kubectl logs -n kube-system daemonset/anetd -c cilium-agent --tail=200 | grep -i "drop"

Recherchez ct-map-insertion-failed ou fib-lookup-failed.


Niveau 3 : Observabilité du VPC et du routage (réseau cloud)

Le niveau de routage VPC et cloud connecte les nœuds GKE à d'autres services Google Cloud , aux réseaux sur site et à Internet. Les échecs à ce niveau proviennent généralement des règles de pare-feu VPC, des routes personnalisées ou des configurations de passerelle.

Isoler les problèmes de connectivité GKE par rapport aux problèmes de connectivité VPC ou externe

Avant de distinguer les problèmes de réseau externe des échecs dans le cluster, examinez le champ d'application du diagnostic et les conditions préalables :

  • Domaine d'intérêt : isolation des limites entre le routage interne Kubernetes et le routage cloud VPC.
  • Prérequis : gcloud CLI, autorisations pour créer des tests de connectivité.
  • Compatibilité CNI : tous les clusters.
  • Symptôme : les pods ne parviennent pas à se connecter à une ressource externe (par exemple, Cloud SQL, une API sur site ou un point de terminaison tiers).
  • Objectif : déterminer rapidement si la perte de paquets se produit au niveau du nœud GKE ou à l'intérieur du réseau VPC Google Cloud ou du réseau externe.

Étape 1 : Test de référence de la VM Compute Engine

Pour déployer une VM de référence et évaluer si le problème persiste en dehors de GKE, procédez comme suit :

  1. Déployez une instance de VM Compute Engine temporaire dans le même sous-réseau et la même zone VPC que votre pool de nœuds GKE :

    gcloud compute instances create gke-baseline-tester \
        --zone=us-central1-a \
        --subnet=gke-subnet \
        --machine-type=e2-micro
    
  2. Connectez-vous à l'instance à l'aide de SSH et testez la connectivité à la destination :

    curl -v --connect-timeout 5 https://api.example.com
    
  3. Évaluer le résultat :

    • Si la VM Compute Engine ne peut pas se connecter, le problème se situe au niveau du réseau VPC ou externe (règles de pare-feu, tables de routage, épuisement des adresses IP Cloud NAT ou mise sur liste blanche des adresses IP externes).
    • Si la VM Compute Engine se connecte correctement, le problème se situe dans GKE (NetworkPolicy bloquant le trafic sortant, CIDR de pod non masqué ou DNS au niveau du conteneur).

Étape 2 : Exécutez un test de connectivité à la demande

Exécutez un test de connectivité Google Cloud depuis la VM du nœud vers la destination :

gcloud network-management connectivity-tests create test-node-to-dest \
    --source-instance=projects/PROJECT_ID/zones/us-central1-a/instances/gke-baseline-tester \
    --destination-ip-address=203.0.113.10 \
    --destination-port=443 \
    --protocol=TCP

Vérifiez le résultat dans la console Google Cloud pour identifier si une règle ou une route de pare-feu VPC supprime le trafic.


Diagnostiquer la connectivité à l'aide de Tests de connectivité

Les tests de connectivité simulent les chemins de paquets entre les ressources GKE et VPC sans envoyer de trafic en direct. Cette simulation évalue la résolution DNAT de ClusterIP vers le pod de service, les règles d'entrée et de sortie NetworkPolicy de GKE Dataplane V2, ainsi que le masquage d'adresse IP de nœud (SNAT). Avant d'exécuter des simulations de chemin automatisées, vérifiez le champ d'application des diagnostics et les conditions préalables :

  • Domaine d'intérêt : simulation automatisée de chemins statiques pour les pods, les services, les NetworkPolicies et les routes VPC de GKE.
  • Conditions préalables : Network Intelligence Center et l'API Network Management doivent être activés.
  • Compatibilité CNI : GKE Dataplane V2 (analyse améliorée).
  • Symptôme : des pertes de connectivité inexpliquées alors que toutes les configurations semblent valides après inspection manuelle.
  • Objectif : simuler et tracer statiquement l'intégralité du chemin des paquets d'une source de pod vers une destination, en identifiant la ligne exacte de la règle à l'origine d'une perte.

Scénario A : Vérifier si une règle de réseau GKE bloque la collecte de métriques

Lors de l'extraction de métriques à partir de pods dans un espace de noms sécurisé, les collecteurs Google Cloud Managed Service pour Prometheus peuvent être bloqués par une règle NetworkPolicy par défaut :

gcloud network-management connectivity-tests create test-gmp-to-pod \
    --source-ip-address=10.0.0.15 \
    --destination-gke-pod=projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME/k8s/namespaces/prod/pods/backend-pod \
    --destination-port=8080 \
    --protocol=TCP

Inspectez la trace de test dans la console Google Cloud . Si le test se termine à l'étape GKE Network Policy evaluation avec DROP, une règle d'entrée doit être ajoutée pour autoriser le trafic provenant des pods du collecteur.

Scénario B : Vérifier l'accessibilité d'un service GKE

Simulez l'accessibilité d'une VM cliente à un service Kubernetes interne :

gcloud network-management connectivity-tests create test-vm-to-service \
    --source-instance=projects/PROJECT_ID/zones/us-central1-a/instances/client-vm \
    --destination-ip-address=10.96.0.100 \
    --destination-port=80 \
    --protocol=TCP

La trace simulée affiche les éléments suivants :

  1. Correspondance de la route VPC.
  2. Autorisation de sortie et d'entrée du pare-feu VPC.
  3. Arrivée au nœud GKE.
  4. DNAT de service vers l'adresse IP du pod de backend.
  5. Évaluation de NetworkPolicy Ingress sur le pod de backend.

Scénario C : Diagnostiquer les problèmes de sortie du pod vers Internet

Lorsque les pods ne peuvent pas accéder à une API externe sur Internet :

  1. Créez un test du pod à l'adresse IP publique externe (par exemple, 8.8.8.8) :

    gcloud network-management connectivity-tests create test-pod-to-internet \
        --source-gke-pod=projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME/k8s/namespaces/prod/pods/app-pod \
        --destination-ip-address=8.8.8.8 \
        --destination-port=53 \
        --protocol=UDP
    
  2. Examinez le point de dépôt :

    • Trafic abandonné au niveau de NetworkPolicy : le pod ne dispose pas d'une règle NetworkPolicy de sortie autorisant le trafic vers 0.0.0.0/0.
    • Trafic supprimé au niveau du pare-feu VPC : une règle de pare-feu VPC refuse le trafic sortant du sous-réseau de nœuds.
    • Supprimé au niveau de Cloud NAT ou de la route : le sous-réseau ne dispose pas de route par défaut vers la passerelle Internet ou Cloud NAT n'est pas configuré pour le sous-réseau.

Niveau 4 : Observabilité de la passerelle externe et des coûts (Internet et NAT)

Le niveau de passerelle externe gère le trafic sortant vers les destinations Internet publiques via Cloud NAT ou des passerelles externes. L'observabilité à ce niveau permet d'identifier les charges de travail à sortie élevée et de contrôler les coûts de transfert de données.

Identifier le trafic NAT (sortie vers Internet)

Avant d'analyser le trafic Internet sortant et le trafic NAT, examinez le champ d'application du diagnostic et les prérequis :

  • Domaine d'intérêt : trafic Internet sortant, utilisation des ports Cloud NAT, coûts de transfert de données externes.
  • Prérequis : l'observabilité des flux GKE Dataplane V2 doit être activée.
  • Compatibilité CNI : GKE Dataplane V2.
  • Symptôme : erreurs d'épuisement des ports Cloud NAT ou coûts de sortie Internet sortants anormalement élevés.
  • Objectif : identifier les objets Pod et Service GKE spécifiques qui transmettent du trafic vers des points de terminaison Internet externes.

Étape 1 : Comprendre les concepts "to-stack" et "world" dans GKE Dataplane V2

Dans GKE Dataplane V2 :

  • world : représente toute destination en dehors du cluster GKE et du VPC (Internet public).
  • to-stack : représente les paquets passant de l'interface veth du conteneur eBPF à la pile réseau Linux de l'hôte pour subir le masquage d'adresse IP (SNAT) avant d'atteindre Cloud NAT.

Étape 2 : Diffuser et filtrer le trafic NAT avec la CLI Hubble

Diffusez en direct les flux Internet sortants provenant de votre cluster :

# Stream egress flows heading to external internet ("world")
gke-hubble observe \
    --traffic-direction egress \
    --verdict FORWARDED \
    --to-identity world \
    --follow

Exemple de résultat :

TIMESTAMP             SOURCE               DESTINATION          TYPE     VERDICT
10:25:01.120          default/worker-pod   142.250.190.46:443   to-stack FORWARDED

Pour identifier les principaux émetteurs sortants, vous pouvez également rediriger la sortie JSON de Hubble vers jq afin de comptabiliser les flux de sortie externes par pod :

timeout 60s gke-hubble observe \
    --traffic-direction egress \
    --verdict FORWARDED \
    --to-identity world \
    -o json | jq -r '.flow.source.namespace + "/" + .flow.source.pod_name' | sort | uniq -c | sort -nr | head -n 10

Étape 3 : Surveiller le trafic externe à l'aide de métriques

Dans Cloud Monitoring, suivez le volume des flux externes :

fetch prometheus_target
| metric 'prometheus.googleapis.com/pod_flow_egress_flows_count/counter'
| filter (metric.destination_identity == 'world')
| align rate(1m)
| every 1m
| group_by [metric.source_workload, metric.source_namespace], sum(val())

Analyser les coûts et les performances du trafic de cluster à l'aide de Flow Analyzer

Avant de visualiser les flux de trafic et les coûts entre zones, examinez le champ d'application du diagnostic et les conditions préalables :

  • Domaine d'intérêt : coûts de transfert de données interzones, principaux émetteurs, visibilité du trafic entre les nœuds sans requêtes SQL.
  • Conditions préalables : les journaux de flux VPC doivent être activés avec INCLUDE_ALL_METADATA, la visibilité intranœud doit être activée et l'analyse de l'observabilité doit être activée dans le bucket de journaux.
  • Compatibilité CNI : tous les clusters.
  • Symptôme : frais de transfert de données interzones élevés sur les factures mensuellesGoogle Cloud .
  • Objectif : identifier visuellement les charges de travail GKE qui génèrent du trafic multizone et optimiser leur emplacement sans interroger les journaux bruts.

Prérequis

Pour utiliser Flow Analyzer pour GKE :

  1. Les journaux de flux VPC doivent être activés sur le sous-réseau du cluster avec metadata="INCLUDE_ALL_METADATA".
  2. La visibilité intranœud doit être activée sur le cluster pour que le trafic entre pods soit exposé au pipeline de journalisation des flux VPC.
  3. Analyse de journaux : le bucket _Default dans Cloud Logging doit être mis à niveau pour utiliser Observability Analytics.

Étape 1 : Identifier les top talkers GKE dans Flow Analyzer

Pour afficher les charges de travail à volume élevé dans Flow Analyzer, procédez comme suit :

  1. Dans la console Google Cloud , accédez à la page Flow Analyzer.
  2. Cliquez sur Bucket source, puis sélectionnez le bucket de journaux contenant vos journaux de flux. Sauf si vous les avez acheminés ailleurs, il s'agit du bucket _Default.
  3. Dans Agrégation du trafic, sélectionnez Source - Destination.
  4. Définissez la période de votre fenêtre d'analyse.
  5. Sous Organiser les flux par, sélectionnez les champs de pod ou de charge de travail GKE.
  6. Cliquez sur Exécuter une nouvelle requête. Le graphique Flux de données les plus élevés indique les charges de travail qui déplacent le plus de données.

Étape 2 : Analyser les coûts du trafic interzone

Le trafic interzone entraîne des frais de transfert de données. Pour localiser les charges de travail qui transmettent des données entre les zones :

  1. Sous Organiser les flux par, sélectionnez les champs "Zone source" et "Zone de destination".
  2. Cliquez sur Exécuter une nouvelle requête et consultez le tableau Tous les flux de données. Les lignes où les zones source et de destination sont différentes correspondent à votre trafic interzones. Les filtres de Flow Analyzer correspondent aux valeurs. Vous ne pouvez donc pas filtrer sur "n'est pas égal à". Comparez plutôt les paires de zones dans les résultats.
  3. Développez une paire de zones à volume élevé pour afficher les charges de travail GKE source et de destination sous-jacentes.

Résolution :

  • Implémentez topologySpreadConstraints ou podAffinity Kubernetes pour colocaliser les services de communication dans la même zone de disponibilité.
  • Activez le routage basé sur la topologie (service.kubernetes.io/topology-mode: Auto) sur le service pour conserver le trafic dans la zone d'origine.

Étape 3 : Accéder à Observability Analytics (pour les requêtes SQL avancées)

Dans Flow Analyzer, cliquez sur Afficher dans l'Analyse de journaux pour exécuter des requêtes SQL sur les données de flux.

La requête SQL suivante calcule les principaux communicateurs de pods multizones :

SELECT
  JSON_VALUE(json_payload.src_gke_details.pod.workload.workload_name) AS src_workload,
  JSON_VALUE(json_payload.dest_gke_details.pod.workload.workload_name) AS dest_workload,
  JSON_VALUE(json_payload.src_instance.zone) AS src_zone,
  JSON_VALUE(json_payload.dest_instance.zone) AS dest_zone,
  SUM(CAST(JSON_VALUE(json_payload.bytes_sent) AS INT64)) / 1024 / 1024 / 1024 AS total_gb_sent
FROM
  `PROJECT_ID.global._Default._AllLogs`
WHERE
  log_name LIKE '%vpc_flows%'
  AND timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND JSON_VALUE(json_payload.src_instance.zone) != JSON_VALUE(json_payload.dest_instance.zone)
GROUP BY
  1, 2, 3, 4
ORDER BY
  total_gb_sent DESC
LIMIT 20;

Aide-mémoire sur la CLI Hubble et les requêtes

La CLI Hubble diffuse et filtre les données de flux réseau en direct directement à partir du tampon circulaire du noyau GKE Dataplane V2.

Configuration : créer un alias d'assistance

Comme Hubble s'exécute dans le plan de contrôle du cluster, configurez un alias de shell pour exécuter les commandes Hubble sans déployer de binaires locaux :

alias gke-hubble="kubectl exec -it -n gke-managed-dpv2-observability deployment/hubble-relay -c hubble-cli -- hubble"

Recettes de filtrage courantes

Résoudre les problèmes d'objectif Commande Hubble CLI
Observer tous les paquets supprimés en temps réel dans le cluster gke-hubble observe --verdict DROPPED --follow
Diffuser tout le trafic pour un pod spécifique dans n'importe quel espace de noms gke-hubble observe --pod default/my-pod --follow
Filtrer le trafic entre deux espaces de noms spécifiques gke-hubble observe --from-namespace frontend --to-namespace backend
Isoler le trafic sur un port spécifique (par exemple, le port 80) gke-hubble observe --port 80
Inspecter les requêtes et les réponses DNS en direct gke-hubble observe --port 53
Afficher les réinitialisations TCP en direct (paquets RST) gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST
Diffuser tout le trafic sortant vers l'Internet public gke-hubble observe --traffic-direction egress --to-identity world
Inspecter le trafic HTTP de la couche application (couche 7 de l'OSI) gke-hubble observe --protocol http

Filtrage avancé avec négation (--not)

Vous pouvez exclure le trafic connu à volume élevé ou sain pour vous concentrer sur les anomalies :

# Observe drops, but exclude internal kube-system health probes and DNS
gke-hubble observe \
    --verdict DROPPED \
    --not --namespace kube-system \
    --not --port 53

Mise en forme des résultats et intégration de jq

Pour traiter les enregistrements de flux de manière programmatique, générez la sortie au format JSON :

# Extract only source, destination, and drop reason from the last 100 flows
gke-hubble observe --verdict DROPPED -o json --last 100 | \
    jq -r '[.time, .flow.source.pod_name, .flow.destination.pod_name, .flow.drop_reason_desc] | @tsv'

Limites

Lorsque vous utilisez la CLI Hubble pour le dépannage en direct, tenez compte des limites techniques suivantes :

  • Tampon circulaire éphémère local au nœud : les flux Hubble sont stockés dans un tampon circulaire en mémoire sur chaque nœud individuel. Lors d'événements à fort trafic, les anciens journaux de flux sont écrasés en quelques secondes. Pour l'analyse historique, reposez-vous sur la journalisation NetworkPolicy et les journaux de flux VPC dans Cloud Logging.
  • Pas de OU logique intégré : les indicateurs de la CLI Hubble évaluent plusieurs arguments à l'aide du ET logique. Pour rechercher plusieurs conditions (par exemple, "Port 80 OU Port 443"), exécutez des commandes distinctes ou filtrez la sortie JSON à l'aide de jq.

Étapes suivantes