Fehlerbehebung bei der Netzwerkbeobachtbarkeit in GKE

Dieses Dokument enthält Anleitungen und Diagnoseverfahren zur Diagnose von Netzwerkproblemen in GKE-Clustern (Google Kubernetes Engine) mithilfe der GKE Dataplane V2-Beobachtbarkeit, Hubble und Cloud Monitoring.

Eine Übersicht über die Architektur und konzeptionelle Best Practices finden Sie unter Best Practices für die Netzwerkbeobachtbarkeit.

Entscheidungsbaum für die Fehlerbehebung und wichtige Konzepte

Bevor Sie sich die Verfahren ansehen, können Sie anhand der folgenden Entscheidungsmatrix ermitteln, welche Ebene des GKE-Netzwerkstacks wahrscheinlich das Problem verursacht, und den entsprechenden Abschnitt aufrufen.

Symptom oder Frage zu Hauptlernbereichen Vermutete Stufe Empfohlenes Verfahren
Pods können externe Domains oder interne Kubernetes-Dienste nicht auflösen (DNS-Zeitüberschreitungen, NXDOMAIN, SERVFAIL). Stufe 1: Pod und Dienst (DNS) Fehler bei der DNS-Auflösung diagnostizieren
Dienste können nicht kommunizieren; Verbindungszeitüberschreitungen oder verworfene Pakete zwischen Pods. Stufe 1: Pod und Dienst (Richtlinien- oder Paketverluste) Paketverluste und NetworkPolicy-Blockierungen diagnostizieren
Arbeitslastreplikate haben eine ungleichmäßige Trafficlast oder Pods protokollieren hohe Raten von TCP-Zurücksetzungen (RST). Stufe 1: Pod und Dienst (Load Balancing oder Transport) Traffic-Ungleichgewicht und TCP-Zurücksetzungen diagnostizieren
Allgemeine Latenz, zeitweilige Zeitüberschreitungen oder CNI-Neustarts auf Knoten. Stufe 2: Knoten und CNI (Kernel) Fehlerbehebung bei Latenz auf Knotenebene und CNI-Engpässen
Pods können keine Ressourcen außerhalb von GKE (Cloud SQL, externe APIs oder andere VPCs) erreichen. Stufe 3: VPC und Routing GKE-Probleme von VPC- oder externen Verbindungsproblemen isolieren
Sie benötigen eine automatisierte Pfadsimulation, um zu prüfen, ob Firewallregeln, Routen oder NetworkPolicies Traffic blockieren. Stufe 3: VPC und Routing (Simulation) Konnektivität mit Konnektivitätstests diagnostizieren
Sie müssen ermitteln, welche Arbeitslasten Traffic an das Internet senden und NAT durchlaufen. Stufe 4: Externes Gateway und Kosten NAT-Traffic identifizieren (ausgehender Traffic zum Internet)
Hohe Kosten für die zonenübergreifende Datenübertragung oder die Notwendigkeit, die Top-Talker zu visualisieren, ohne SQL-Abfragen schreiben zu müssen. Stufe 4: Externes Gateway und Kosten Kosten und Leistung des Clustertraffics mit Flow Analyzer analysieren

Wichtige Netzwerkkonzepte

Wenn Sie mit Kubernetes oder dem Google Cloud -Netzwerk noch nicht vertraut sind, sollten Sie die folgenden Kernkonzepte beachten:

  • eBPF (Extended Berkeley Packet Filter): Eine Betriebssystemtechnologie, mit der sichere Monitoring- und Routingprogramme direkt im Linux-Kernel ausgeführt werden können. GKE Dataplane V2 verwendet eBPF, um Pakete weiterzuleiten und NetworkPolicies mit minimalem Leistungsaufwand durchzusetzen.
  • IP-Masquerading (SNAT): Der Prozess, bei dem die Quell-IP-Adresse eines Pakets umgeschrieben wird. Wenn ein GKE-Pod (mit einer privaten IP-Adresse) mit dem Internet oder externen VPC-Ressourcen kommuniziert, maskiert (überschreibt) GKE die Pod-IP-Adresse mit der Knoten-IP-Adresse, damit externe Systeme wissen, wie die Antwort weitergeleitet werden soll.
  • Verbindungsverfolgung (Conntrack): Ein Kernel-Feature, das alle aktiven Netzwerkverbindungen verfolgt. In GKE Dataplane V2-Clustern wird dieses Tracking auf zwei Tabellen aufgeteilt: die Standard-Linux-Kernel-Conntrack (vom ip-masq-agent verwendet) und eine von Cilium und GKE Dataplane V2 verwaltete Conntrack-Tabelle, die in einer eBPF-Zuordnung gespeichert ist. Wenn ein Knoten zu viele gleichzeitige Verbindungen verarbeitet, kann sich eine dieser Tracking-Tabellen füllen (Conntrack-Erschöpfung), was dazu führt, dass der Knoten neue Pakete ohne Benachrichtigung verwirft.
  • Hubble: Die Beobachtbarkeits-Engine für GKE Dataplane V2. Sie wird auf eBPF ausgeführt und bietet Echtzeit-Einblicke in Traffic-Flüsse, Paketverluste und die NetworkPolicy-Bewertung.

Stufe 1: Beobachtbarkeit von Pods und Diensten (Anwendungen)

Die Pod- und Dienstebene deckt die Netzwerkkommunikation zwischen Pods, Diensten und Cluster-DNS ab. Probleme auf dieser Ebene äußern sich in der Regel als Zeitüberschreitungen bei Anwendungsverbindungen, Fehler bei der Namensauflösung oder ungleichmäßige Lastverteilung.

Fehler bei der DNS-Auflösung diagnostizieren

Prüfen Sie den Diagnosebereich und die Voraussetzungen, bevor Sie DNS-Probleme beheben:

  • Schwerpunkt: Kommunikation zwischen Pods und CoreDNS oder NodeLocal DNSCache, DNS-Latenz, Zeitüberschreitungen bei der Upstream-DNS-Auflösung und Validierung von FQDN-NetworkPolicy.
  • Voraussetzungen: GKE Dataplane V2-Messwerte aktiviert; kubectl-Zugriff.
  • CNI-Kompatibilität: GKE Dataplane V2 (Advanced Datapath) und Standard-GKE-CNI.
  • Symptom: Pods protokollieren dial tcp: lookup <domain>: i/o timeout, NXDOMAIN oder zeitweise Latenz bei ausgehenden API-Aufrufen.
  • Ziel: Feststellen, ob der DNS-Fehler innerhalb des Clusters (kube-dns oder NodeLocal DNSCache-Sättigung), durch eine NetworkPolicy, die UDP- oder TCP-Port 53 blockiert, oder durch eine Beeinträchtigung des Upstream-Netzwerks verursacht wird.

Schritt 1: Grundlegende Erreichbarkeitsprüfung

Bevor Sie Fehler in DNS-Ebenen beheben, prüfen Sie, ob das Ziel direkt über seine IP-Adresse aus dem betroffenen Pod erreichbar ist:

# 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
  • Wenn die IP-Verbindung erfolgreich ist, die Domain aber fehlschlägt: Das Problem ist auf die DNS-Auflösungsebene beschränkt. Fahre dann mit Schritt 2 fort.
  • Wenn beide fehlschlagen: Das Problem liegt beim Routing auf Netzwerkebene oder bei der Durchsetzung von Richtlinien. Fahren Sie mit Paketverluste und NetworkPolicy-Blöcke diagnostizieren fort.
DNS-Vorabbefüllung für FQDN-Netzwerkrichtlinie prüfen

Wenn Ihr Cluster FQDN-basierte NetworkPolicies (FQDNNetworkPolicy) verwendet, prüfen Sie, ob der Domainname explizit zugelassen ist. Wenn ein Pod eine externe Domain abfragt, die nicht im DNS-Proxy-Cache von GKE Dataplane V2 vorab ausgefüllt ist oder nicht durch eine Richtlinie zugelassen wird, blockiert GKE Dataplane V2 den ausgehenden Traffic an die aufgelöste IP-Adresse:

# 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"

Schritt 2: DNS-Messwerte in Cloud Monitoring prüfen

Die GKE stellt integrierte DNS-Messwerte in Cloud Monitoring unter dem Präfix kubernetes.io/networking/dns/ bereit.

So prüfen Sie DNS-Messwerte in Cloud Monitoring:

  1. Rufen Sie in der Google Cloud Console Cloud Monitoring > Dashboards auf.
  2. Wählen Sie das vordefinierte Dashboard GKE DNS Observability – Clusteransicht aus oder rufen Sie den Metrics Explorer auf und filtern Sie nach kubernetes.io/networking/dns/.
  3. Werten Sie die folgenden primären Signale aus (ersetzen Sie für NodeLocal DNSCache kubedns durch node_local_dns im Messwertpfad):
Messwertname Grenzwert für „Warnung“ Ursache
kubernetes.io/networking/dns/kubedns/max_concurrent_rejected_request_count > 0 Limit für gleichzeitige Abfragen erreicht. kube-dns oder NodeLocal DNSCache verwirft Abfragen.
kubernetes.io/networking/dns/kubedns/dns_request_latencies p99 > 100 ms Hohe End-to-End-DNS-Auflösungslatenz über kube-dns oder NodeLocal DNSCache.
kubernetes.io/networking/dns/kubedns/forwarding_request_latencies p99 > 100 ms Latenz oder Sättigung des Upstream-DNS-Servers.
DNS-Leistung und Zeitüberschreitungs-Triage-Sequenz

Folgen Sie dieser Triage-Sequenz, um DNS-Latenz, Cache-Fehler und Upstream-Zeitüberschreitungen zu diagnostizieren:

  1. Cache-Trefferquote prüfen: Abfrage kubernetes.io/networking/dns/kubedns/dns_cache_request_count (oder node_local_dns/dns_cache_request_count), gruppiert nach dem Label cache_status. Wenn cache_status="hit" niedrig und cache_status="miss" hoch ist, senden Anwendungen möglicherweise Abfragen, die keine FQDNs sind (z. B. my-service anstelle von my-service.default.svc.cluster.local), was dazu führt, dass der Suchpfad alle Einträge in /etc/resolv.conf durchläuft.
  2. Upstream-Latenz bewerten: Ein hoher forwarding_request_latencies-Wert weist auf Probleme mit dem Upstream-DNS-Server hin (z. B. Unternehmens-DNS, das lokal über Cloud Interconnect oder Cloud VPN erreicht wird, oder Cloud DNS-Limits).
  3. Benutzerdefinierte DNS-Überschreibungen prüfen: Prüfen Sie benutzerdefinierte kube-dns-ConfigMaps auf falsch konfigurierte Stubs oder vorgelagerte Weiterleitungen:

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

Schritt 3: Live-DNS-Traffic mit der Hubble-Befehlszeile streamen

Verwenden Sie den Hubble-CLI-Hilfsalias, um Live-DNS-Anfragen und -Antworten zu prüfen, die vom Knotenkernel gestreamt werden:

# 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

Schritt 4: Korrektur validieren

Wenn gleichzeitige Abfragen abgelehnt wurden, wenden Sie NodeLocal DNSCache an, um hochfrequente DNS-Lookups direkt auf dem Knoten zu verarbeiten, ohne die clusterweiten kube-dns-Limits zu erreichen:

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

Paketverluste und NetworkPolicy-Blockierungen diagnostizieren

Prüfen Sie den Diagnoseumfang und die Voraussetzungen, bevor Sie Paketverluste und Richtlinienablehnungen untersuchen:

  • Schwerpunkt: Traffic-Abfälle zwischen Pod-Objekten oder zwischen Pod- und Service-Objekten, NetworkPolicy-Erzwingung, Kernel-eBPF-Abfallgründe.
  • Voraussetzungen: GKE Dataplane V2 Flow Observability aktiviert; NetworkPolicy-Logging konfiguriert.
  • CNI-Kompatibilität: Nur GKE Dataplane V2.
  • Symptom: Verbindungsversuche der Anwendung schlagen mit Connection timed out oder Connection reset by peer fehl.
  • Ziel: Die genaue NetworkPolicy oder den eBPF-Grund für das Verwerfen von Paketen ermitteln, ohne dass Sicherheitsrichtlinien durch Ausprobieren geändert werden müssen.

Schritt 1: Hubble-Drop-Messwerte überwachen

Wenn GKE Dataplane V2 ein Paket verwirft, wird der Messwert hubble_drop_total ausgegeben, der mit dem Grund für das Verwerfen sowie mit Quell- und Zielmetadaten getaggt ist. So überwachen Sie Hubble-Drop-Messwerte:

  1. Falls noch nicht geschehen, stellen Sie eine PodMonitoring-Ressource von Google Cloud Managed Service for Prometheus bereit, um Hubble-Messwerte zu extrahieren:

    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. Führen Sie die folgende Abfrage in Cloud Monitoring > Metrics Explorer aus, um die verworfenen Pakete nach Grund aufzurufen:

    sum by (reason) (rate(hubble_drop_total[5m])) > 0
    
  3. Interpretieren Sie die gängigen reason-Codes:

    • Policy denied: Eine Kubernetes-NetworkPolicy blockiert die Verbindung explizit oder implizit.
    • CT: Map insertion failed: Die Tabelle für das Verbindungstracking (conntrack) ist erschöpft.
    • Unsupported L3 protocol: Nicht-IPv4- oder IPv6-Paket oder beschädigter Header.

Schritt 2: NetworkPolicy-Logs in Cloud Logging prüfen

Beim NetworkPolicy-Logging werden strukturierte JSON-Logs für alle Richtlinienentscheidungen exportiert. So fragen Sie NetworkPolicy-Logs in Cloud Logging ab:

  1. Rufen Sie in der Google Cloud Console Cloud Logging > Log-Explorer auf.
  2. Führen Sie die folgende Abfrage aus:

    resource.type="k8s_node"
    log_name:"projects/PROJECT_ID/logs/events"
    jsonPayload.connection.verdict="DENY"
    jsonPayload.src.pod_name="my-source-pod"
    
  3. Prüfen Sie die JSON-Nutzlast:

    • jsonPayload.drop_reason: zeigt, warum das Paket verworfen wurde.
    • jsonPayload.policies: Listet auf, welche NetworkPolicies ausgewertet wurden. Wenn eine leere Liste mit dem Urteil DENY zurückgegeben wird, wird der Namespace im Standard-Deny-Modus ausgeführt und der Traffic wurde von keiner Richtlinie zugelassen.

Wenn keine NetworkPolicy-Logs angezeigt werden, prüfen Sie, ob das Logging in der benutzerdefinierten NetworkLogging-Ressource des Clusters aktiviert ist. Prüfen Sie beispielsweise, ob das Feld spec.cluster.deny.log auf true gesetzt ist:

kubectl get networklogging default -o yaml

Schritt 3: Live-Drops mit der Hubble-Befehlszeile verfolgen

Sie können Live-Drops direkt streamen, indem Sie die Hubble-Befehlszeile verwenden, um Echtzeitpakete zu prüfen:

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

Beispielausgabe:

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

Die Ausgabe gibt die genaue NetworkPolicy an, die den Traffic blockiert (backend-deny-all).

Schritt 4: Conntrack-Erschöpfung prüfen

Wenn der Löschgrund CT: Map insertion failed ist:

  1. Prüfen Sie das GKE Dataplane V2-Agent-Log auf eine Sättigung der conntrack-Tabelle:

    kubectl logs -n kube-system daemonset/anetd -c cilium-agent --tail=100 | grep "Conntrack table full"
    
  2. Prüfen Sie die maximale Größe der conntrack-Tabelle auf dem betroffenen Knoten:

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

    Wenn die Conntrack-Tabelle voll ist, skalieren Sie Ihre Arbeitslasten horizontal auf mehr Knoten oder reduzieren Sie die Verbindungsrate von Client-Pods.


Traffic-Ungleichgewicht und TCP-Zurücksetzungen diagnostizieren

Prüfen Sie den Diagnoseumfang und die Voraussetzungen, bevor Sie Probleme mit Traffic-Ungleichgewicht und Verbindungszurücksetzungen beheben:

  • Schwerpunkt: Ungleichmäßiges Load Balancing, TCP-Handshake-Fehler, plötzlicher Verbindungsabbruch.
  • Voraussetzungen: GKE Dataplane V2-Messwerte müssen aktiviert sein.
  • CNI-Kompatibilität: GKE Dataplane V2.
  • Symptom: Bestimmte Pod-Replikate erhalten übermäßigen Traffic, während andere inaktiv bleiben. Clientanwendungen protokollieren connection reset by peer oder broken pipe.
  • Ziel: Ermitteln, ob ein Traffic-Ungleichgewicht durch die Verbindungsbindung auf der Transportebene (OSI-Ebene 4, TCP) oder auf der Anwendungsebene (OSI-Ebene 7, HTTP/2 oder gRPC) verursacht wird, und die Quelle von TCP-RST-Paketen identifizieren.

Schritt 1: Trafficfluss auf Pod-Ebene vergleichen

So stellen Sie fest, ob der Traffic gleichmäßig auf Ihre Replikate verteilt ist:

  1. Fragen Sie in Cloud Monitoring die Anzahl der eingehenden Datenflüsse für alle Pods in einem Deployment ab:

    sum by (pod) (rate(pod_flow_ingress_flows_count{destination_workload="my-service"}[5m]))
    
  2. Traffic-Verteilung auf Pods bewerten Wenn ein einzelner Pod den Großteil des Traffics empfängt, sollten Sie die Wiederverwendung von Verbindungen oder Sticky Sessions prüfen:

    • gRPC oder HTTP/2: Langlebige TCP-Verbindungen führen dazu, dass alle Anfragen einen einzelnen TCP-Stream zu einem Backend-Pod durchlaufen. Das Kubernetes-Dienstrouting auf der Transportschicht (OSI-Schicht 4, TCP) kann Anfragen innerhalb einer hergestellten HTTP/2-Verbindung nicht ausgleichen.
    • ClientIP-Sitzungsaffinität: Prüfen Sie, ob der Dienst mit sessionAffinity: ClientIP konfiguriert ist.
    • Monitorlose Dienste: Clients können DNS einmal auflösen und die einzelne IP-Adresse dauerhaft im Cache speichern.

Schritt 2: TCP-Reset-Messwerte analysieren

TCP-Zurücksetzungen (RST) beenden Verbindungen sofort. Sie werden vom Betriebssystemkernel ausgegeben, wenn ein Endpunkt ein Paket für einen unbekannten Port empfängt oder wenn eine Anwendung eine Verbindung mit ungelesenen Daten im Zwischenspeicher schließt.

Führen Sie die folgende MQL-Abfrage in Cloud Monitoring aus:

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())

Sehen Sie sich die Abfrageergebnisse an, um die Quelle des Zurücksetzens zu ermitteln:

  • Ausgehendes RST (traffic_direction=egress): Der lokale Pod generiert den Reset. Prüfen Sie, ob die Pod-Anwendung abstürzt, ihr Verbindungslimit erreicht oder die Verbindung aktiv ablehnt.
  • Eingehendes RST (traffic_direction=ingress): Der Remote-Peer (externe Datenbank, API oder Remote-Pod) hat den Reset gesendet. Prüfen Sie den Zustand des Zielservers und der Firewall.

Schritt 3: TCP-Zurücksetzungen live streamen

Verwenden Sie die Hubble-Befehlszeile, um den Live-Reset-Handshake zu erfassen:

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

Schritt 4: Abhilfe und umsetzbare Korrekturen

Führen Sie je nach Ursache des Traffic-Ungleichgewichts oder der TCP-Zurücksetzungen die folgenden Schritte zur Behebung aus:

  • Für die Sitzungsaffinität auf Anwendungsebene (OSI-Ebene 7) oder gRPC-Verbindung:
    • Stellen Sie Cloud Service Mesh bereit, um Load Balancing auf Anfrageebene (OSI-Ebene 7) zu ermöglichen.
    • Konfigurieren Sie clientseitige Verbindungslimits oder Keepalive-Zeitlimits (z. B. gRPC MAX_CONNECTION_AGE und MAX_CONNECTION_AGE_GRACE), um eine regelmäßige Wiederherstellung der Verbindung zu erzwingen.
  • Für die Dienst-IP-Affinität: Entfernen Sie service.spec.sessionAffinity, es sei denn, der Anwendungsstatus erfordert dies unbedingt.
  • Für das DNS-Caching von monitorlosen Diensten: Achten Sie darauf, dass Anwendungs-Laufzeiten (z. B. JVM networkaddress.cache.ttl) DNS-Ergebnisse nicht unbegrenzt im Cache speichern.
  • Bei Überlauf der Anwendungswarteschlange: Wenn eine Anwendungswarteschlange voll ist, verwirft der Linux-Kernel eingehende SYN-Pakete oder sendet einen TCP-RST. Skalieren Sie Pod-Replikate horizontal oder erhöhen Sie den Backlog für die Anwendung (somaxconn).

Stufe 2: Knoten- und CNI-Beobachtbarkeit (Kernel)

Die Knoten- und CNI-Ebene umfasst den Linux-Kernel des Hosts, eBPF-Programme und Knotenschnittstellen. Engpässe auf dieser Ebene wirken sich auf alle Arbeitslasten aus, die auf dem betroffenen Knoten ausgeführt werden.

Systemintegritätsprüfung: Nicht autorisiertes Patching von anetd erkennen

GKE Dataplane V2 wird als verwaltetes DaemonSet (anetd) im Namespace kube-system ausgeführt. In Cloud Logging können Sie Kubernetes-Audit-Logs abfragen, um festzustellen, ob nicht autorisierte Nutzer oder automatisierte Skripts anetd gepatcht oder neu gestartet haben:

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

Wenn ein nicht autorisiertes Patching erkannt wird, setzen Sie das DaemonSet auf die Standardkonfiguration zurück oder lösen Sie eine Neuerstellung des Knotenpools aus, um den verwalteten Zustand wiederherzustellen.


Fehlerbehebung bei Latenz auf Knotenebene und CNI-Engpässen

Prüfen Sie den Diagnoseumfang und die Voraussetzungen, bevor Sie Latenz- und Kernel-Engpässe auf Knotenebene diagnostizieren:

  • Schwerpunkt: Host-Kernel-Latenz, Paketverluste an der VM-Schnittstelle, Sättigung des GKE Dataplane V2-eBPF-Agents, Conntrack-Erschöpfung.
  • Voraussetzungen: Compute Engine-VM-Messwerte aktiviert; kubectl-Zugriff.
  • CNI-Kompatibilität: GKE Dataplane V2 und Standard-GKE-CNI.
  • Symptom: Bei knotenübergreifendem Traffic kommt es zu Latenzspitzen oder zufälligen Abfällen, während der Traffic innerhalb des Knotens fehlerfrei bleibt.
  • Ziel: Unterscheidung zwischen Netzwerkdrosselung der Host-VM, Linux-Kernel-Drops und Engpässen auf CNI-Ebene.

Schritt 1: Probleme außerhalb von GKE von Problemen innerhalb von GKE unterscheiden

Führen Sie den Compute Engine-VM-Basistest aus: Stellen Sie eine eigenständige Compute Engine-VM im selben VPC-Subnetz wie die GKE-Clusterknoten bereit. Testen Sie die Verbindung von der VM zum Ziel.

  • Wenn auf der eigenständigen VM dieselben Paketverluste oder Latenzen auftreten: Das Problem liegt außerhalb von GKE (VPC-Firewalls, Cloud NAT, Cloud Interconnect oder der externe Server). Fahren Sie mit GKE-Probleme von VPC- oder externen Verbindungsproblemen isolieren fort.
  • Wenn die eigenständige VM normal kommuniziert, aber GKE-Pods fehlschlagen: Das Problem liegt innerhalb von GKE (eBPF, conntrack oder CNI auf Knotenebene). Fahre dann mit Schritt 2 fort.

Schritt 2: Anwendungsprobleme von Problemen auf Knoten- und CNI-Ebene unterscheiden

So ermitteln Sie, ob die Latenz in der Anwendung oder auf der Knoten- und CNI-Ebene entsteht:

  1. Ressourcensättigung der Anwendung prüfen: Prüfen Sie, ob der Knoten keine CPU-Drosselung oder Arbeitsspeicherauslastung aufweist, die die Paketverarbeitung im Nutzerbereich verzögert:

    kubectl top nodes
    kubectl top pods -n default
    
  2. Linux-Kernel-conntrack-Anzahl prüfen: Prüfen Sie die Anzahl der aktiven conntracks auf dem Host:

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

    Wenn sich nf_conntrack_count dem Wert nf_conntrack_max nähert, verwirft der Hostkernel neue TCP-SYN-Pakete.

Schritt 3: Paketverluste auf VM-Ebene mithilfe von Compute Engine-Telemetriedaten prüfen

Google Cloud Compute Engine exportiert Netzwerkschnittstellenmesswerte auf VM-Ebene nach Cloud Monitoring.

Führen Sie in Cloud Monitoring > Metrics Explorer die folgende Abfrage aus:

sum by (drop_reason) (rate(compute_googleapis_com:instance_network_dropped_packets_count[5m]))
  • FQ_CODEL_DROP: Paket wurde aufgrund von Fair Queuing oder CoDel-Warteschlangensättigung verworfen (Bandbreitenlimit für ausgehenden VM-Traffic überschritten).
  • FIREWALL_RULE_DROP: Paket wurde von einer VPC-Firewallregel verworfen.
  • RATE_LIMIT_DROP: Paket verworfen, weil die VM das Kontingent für die maximale Anzahl von Paketen pro Sekunde (PPS) ihrer Netzwerkschnittstelle überschritten hat.

Schritt 4: Verluste auf Kernelebene mit eBPF untersuchen

Wenn auf VM-Ebene keine verworfenen Pakete angezeigt werden, GKE-Pods aber weiterhin Pakete verwerfen, prüfen Sie den GKE Dataplane V2-Agent (anetd) auf verworfene eBPF-Zuordnungen:

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

Suchen Sie nach ct-map-insertion-failed oder fib-lookup-failed.


Stufe 3: Beobachtbarkeit von VPC und Routing (Cloud-Netzwerk)

Die VPC- und Cloud-Routing-Stufe verbindet GKE-Knoten mit anderen Google Cloud -Diensten, lokalen Netzwerken und dem Internet. Fehler hier sind in der Regel auf VPC-Firewallregeln, benutzerdefinierte Routen oder Gateway-Konfigurationen zurückzuführen.

GKE-Verbindungsprobleme von VPC- oder externen Verbindungsproblemen isolieren

Prüfen Sie den Diagnosebereich und die Voraussetzungen, bevor Sie externe Netzwerkprobleme von Fehlern im Cluster isolieren:

  • Schwerpunkt: Grenzisolierung zwischen internem Kubernetes-Routing und VPC-Cloud-Routing.
  • Voraussetzungen: gcloud CLI; Berechtigungen zum Erstellen von Konnektivitätstests.
  • CNI-Kompatibilität: alle Cluster.
  • Symptom: Pods können keine Verbindung zu einer externen Ressource herstellen (z. B. Cloud SQL, eine lokale API oder ein Endpunkt eines Drittanbieters).
  • Ziel: Schnell feststellen, ob der Paketverlust innerhalb des GKE-Knotens oder innerhalb des VPC- oder externen Netzwerks von Google Cloud auftritt.

Schritt 1: Baseline-Test für Compute Engine-VMs

So stellen Sie eine Baseline-VM bereit und prüfen, ob das Problem außerhalb von GKE weiterhin besteht:

  1. Stellen Sie eine temporäre Compute Engine-VM-Instanz im selben VPC-Subnetz und in derselben Zone wie Ihr GKE-Knotenpool bereit:

    gcloud compute instances create gke-baseline-tester \
        --zone=us-central1-a \
        --subnet=gke-subnet \
        --machine-type=e2-micro
    
  2. Stellen Sie eine SSH-Verbindung zur Instanz her und testen Sie die Verbindung zum Ziel:

    curl -v --connect-timeout 5 https://api.example.com
    
  3. Ergebnis bewerten:

    • Wenn die Compute Engine-VM keine Verbindung herstellen kann, liegt das Problem im VPC- oder externen Netzwerk (Firewallregeln, Routingtabellen, Erschöpfung der Cloud NAT-IP-Adressen oder Whitelisting externer IP-Adressen).
    • Wenn die Compute Engine-VM erfolgreich eine Verbindung herstellt: Das Problem liegt innerhalb von GKE (NetworkPolicy blockiert ausgehenden Traffic, nicht maskierte Pod-CIDR oder DNS auf Containerebene).

Schritt 2: On-Demand-Konnektivitätstest ausführen

Führen Sie einen Google Cloud -Konnektivitätstest von der Knoten-VM zum Ziel aus:

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 \
    --round-trip

Prüfen Sie das Ergebnis in der Google Cloud Console, um festzustellen, ob eine VPC-Firewallregel oder -Route den Traffic verwirft.


Konnektivität mit Konnektivitätstests diagnostizieren

Konnektivitätstests simulieren Paketpfade über GKE- und VPC-Ressourcen, ohne Live-Traffic zu senden. Bei dieser Simulation werden die DNAT-Auflösung von Service ClusterIP zu Pod, die Regeln für eingehenden und ausgehenden Traffic der GKE Dataplane V2-NetworkPolicy sowie das IP-Masquerading (SNAT) von Knoten ausgewertet. Prüfen Sie den Diagnosebereich und die Voraussetzungen, bevor Sie automatisierte Pfadsimulationen ausführen:

  • Schwerpunkt: Automatisierte statische Pfadsimulation für GKE-Pods, -Dienste, -NetworkPolicies und -VPC-Routen.
  • Voraussetzungen: Network Intelligence Center aktiviert; Network Management API aktiviert.
  • CNI-Kompatibilität: GKE Dataplane V2 (erweiterte Analyse).
  • Symptom: Unerklärliche Verbindungsabbrüche, bei denen alle Konfigurationen bei manueller Prüfung gültig erscheinen.
  • Ziel: Den gesamten Paketpfad von einer Pod-Quelle zum Ziel statisch simulieren und verfolgen, um die genaue Richtlinienzeile zu identifizieren, die einen Paketverlust verursacht.

Szenario A: Prüfen, ob eine GKE-NetworkPolicy die Messwerterfassung blockiert

Beim Scraping von Messwerten aus Pods in einem sicheren Namespace werden Google Cloud Managed Service for Prometheus-Collectors möglicherweise durch eine NetworkPolicy mit der Standardeinstellung „Ablehnen“ blockiert:

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 \
    --round-trip

Prüfen Sie den Test-Trace in der Google Cloud Console. Wenn der Test beim Schritt GKE Network Policy evaluation mit DROP beendet wird, muss eine Regel für eingehenden Traffic hinzugefügt werden, um Traffic von den Collector-Pods zuzulassen.

Szenario B: Erreichbarkeit eines GKE-Dienstes prüfen

Simulieren Sie die Erreichbarkeit von einer Client-VM zu einem internen Kubernetes-Dienst:

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 \
    --round-trip

Der simulierte Trace zeigt Folgendes:

  1. VPC-Routenübereinstimmung.
  2. VPC-Firewall-Regeln für ausgehenden und eingehenden Traffic zulassen.
  3. Ankunft am GKE-Knoten.
  4. Dienst-DNAT zur Backend-Pod-IP-Adresse.
  5. Auswertung der Ingress-NetworkPolicy auf dem Backend-Pod.

Szenario C: Probleme mit ausgehendem Traffic von Pods zum Internet diagnostizieren

Wenn Pods eine externe API im Internet nicht erreichen können:

  1. Erstellen Sie einen Test vom Pod zur externen öffentlichen IP-Adresse (z. B. 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 \
        --round-trip
    
  2. Prüfen Sie den Ablagepunkt:

    • Bei NetworkPolicy verworfen: Dem Pod fehlt eine ausgehende NetworkPolicy, die Traffic zu 0.0.0.0/0 zulässt.
    • Bei VPC-Firewall verworfen: Eine VPC-Firewallregel lehnt ausgehenden Traffic vom Knoten-Subnetz ab.
    • Bei Cloud NAT oder Route verworfen: Dem Subnetz fehlt eine Standardroute zum Internetgateway oder Cloud NAT ist nicht für das Subnetz konfiguriert.

Stufe 4: Beobachtbarkeit von externem Gateway und Kosten (Internet und NAT)

Die externe Gateway-Stufe verwaltet ausgehenden Traffic zu öffentlichen Internetzielen über Cloud NAT oder externe Gateways. Die Beobachtbarkeit auf dieser Ebene hilft, Arbeitslasten mit hohem ausgehendem Traffic zu identifizieren und die Kosten für die Datenübertragung zu kontrollieren.

NAT-Traffic identifizieren (ausgehend zum Internet)

Prüfen Sie den Diagnoseumfang und die Voraussetzungen, bevor Sie ausgehenden Internet- und NAT-Traffic analysieren:

  • Schwerpunkt: ausgehender Internettraffic, Cloud NAT-Portnutzung, Kosten für externe Datenübertragung.
  • Voraussetzungen: GKE Dataplane V2 Flow Observability muss aktiviert sein.
  • CNI-Kompatibilität: GKE Dataplane V2.
  • Symptom: Cloud NAT-Port-Erschöpfungsfehler oder unerwartet hohe Kosten für ausgehenden Internet-Traffic.
  • Ziel: Ermitteln, welche GKE-Pod- und Dienstobjekte Traffic an externe Internetendpunkte übertragen.

Schritt 1: Konzepte „to-stack“ und „world“ in GKE Dataplane V2 verstehen

In GKE Dataplane V2:

  • world: steht für ein beliebiges Ziel außerhalb des GKE-Cluster und außerhalb der VPC (das öffentliche Internet).
  • to-stack: Stellt Pakete dar, die von der veth-Schnittstelle des eBPF-Containers zum Linux-Netzwerkstack des Hosts wechseln, um IP-Masquerading (SNAT) zu durchlaufen, bevor sie Cloud NAT erreichen.

Schritt 2: NAT-Traffic mit der Hubble-Befehlszeile streamen und filtern

Streamen Sie ausgehende Live-Internet-Datenflüsse, die von Ihrem Cluster stammen:

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

Beispielausgabe:

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

Wenn Sie die wichtigsten ausgehenden Talker identifizieren möchten, können Sie die Hubble-JSON-Ausgabe auch an jq weiterleiten, um die externen ausgehenden Abläufe nach Pod zu zählen:

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

Schritt 3: Externen Traffic mithilfe von Messwerten überwachen

Verfolgen Sie in Cloud Monitoring das Volumen der externen Abläufe:

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())

Kosten und Leistung des Clustertraffics mit Flow Analyzer analysieren

Prüfen Sie den Diagnoseumfang und die Voraussetzungen, bevor Sie Trafficflüsse und zonenübergreifende Kosten visualisieren:

  • Schwerpunkt: Kosten für die zonenübergreifende Datenübertragung, Top Talker, Sichtbarkeit des Traffics zwischen Knoten ohne SQL-Abfragen.
  • Voraussetzungen: VPC-Flusslogs mit INCLUDE_ALL_METADATA aktiviert; knoteninterne Sichtbarkeit aktiviert; Observability Analytics für den Log-Bucket aktiviert.
  • CNI-Kompatibilität: alle Cluster.
  • Symptom: Erhöhte Gebühren für die zonenübergreifende Datenübertragung auf monatlichen Rechnungen vonGoogle Cloud .
  • Ziel: Visuell erkennen, welche GKE-Arbeitslasten zonenübergreifenden Traffic generieren, und die Platzierung optimieren, ohne Rohlogs abzufragen.

Vorbereitung

So verwenden Sie Flow Analyzer für GKE:

  1. VPC-Flusslogs: müssen im Cluster-Subnetz mit metadata="INCLUDE_ALL_METADATA" aktiviert sein.
  2. Knoteninterne Sichtbarkeit: Muss im Cluster aktiviert sein, damit der Pod-zu-Pod-Traffic für die VPC-Flusslog-Pipeline sichtbar ist.
  3. Log-Analyse: Für den Bucket _Default in Cloud Logging muss ein Upgrade durchgeführt werden, damit Observability Analytics verwendet werden kann.

Schritt 1: GKE-Top-Talker in Flow Analyzer identifizieren

So rufen Sie Arbeitslasten mit hohem Volumen in Flow Analyzer auf:

  1. Rufen Sie in der Google Cloud Console die Seite Flow Analyzer auf.
  2. Klicken Sie auf Quell-Bucket und wählen Sie den Log-Bucket aus, der Ihre Flusslogs enthält. Wenn Sie sie nicht an einen anderen Ort weitergeleitet haben, ist dies der Bucket _Default.
  3. Wählen Sie unter Traffic-Zusammenfassung die Option Quelle – Ziel aus.
  4. Legen Sie den Zeitraum für das Analysefenster fest.
  5. Wählen Sie unter Flüsse organisieren nach die GKE-Pod- oder Arbeitslastfelder aus.
  6. Klicken Sie auf Neue Abfrage ausführen. Im Diagramm Höchste Datenflüsse sehen Sie, welche Arbeitslasten die meisten Daten verschieben.

Schritt 2: Kosten für zonenübergreifenden Traffic analysieren

Für zonenübergreifenden Traffic fallen Gebühren für die Datenübertragung an. So finden Sie Arbeitslasten, die über Zonen hinweg übertragen werden:

  1. Wählen Sie unter Datenflüsse organisieren nach die Felder für die Quell- und Zielzone aus.
  2. Klicken Sie auf Neue Abfrage ausführen und lesen Sie die Tabelle Alle Datenflüsse. Zeilen, in denen sich die Quell- und Zielzonen unterscheiden, sind Ihr zonenübergreifender Traffic. Flow Analyzer-Filter stimmen mit Werten überein. Sie können also nicht nach „ungleich“ filtern. Vergleichen Sie stattdessen die Zonenpaare in den Ergebnissen.
  3. Maximieren Sie ein Zonenpaar mit hohem Volumen, um die zugrunde liegenden GKE-Quell- und Zielarbeitslasten aufzurufen.

Abhilfe:

  • Implementieren Sie Kubernetes-topologySpreadConstraints oder podAffinity, um kommunizierende Dienste in derselben Verfügbarkeitszone zu platzieren.
  • Aktivieren Sie Topologie-fähiges Routing (service.kubernetes.io/topology-mode: Auto) für den Dienst, damit der Traffic in der Ursprungszone bleibt.

Schritt 3: Observability Analytics aufrufen (für erweiterte SQL-Abfragen)

Klicken Sie in Flow Analyzer auf In Loganalyse ansehen, um SQL-Abfragen für die Flussdaten auszuführen.

Mit der folgenden SQL-Abfrage werden die Top-Pod-Talker über Zonen hinweg berechnet:

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;

Hubble-Befehlszeilenreferenz und Spickzettel für Abfragen

Die Hubble-Befehlszeile streamt und filtert Live-Netzwerkflussdaten direkt aus dem GKE Dataplane V2-Kernel-Ringpuffer.

Einrichtung: Helper-Alias erstellen

Da Hubble in der Steuerungsebene des Clusters ausgeführt wird, konfigurieren Sie einen Shell-Alias, um Hubble-Befehle auszuführen, ohne lokale Binärdateien bereitzustellen:

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

Häufig verwendete Filterrezepte

Zielvorhaben zur Fehlerbehebung Hubble-Befehlszeilenbefehl
Alle verworfenen Pakete im gesamten Cluster in Echtzeit beobachten gke-hubble observe --verdict DROPPED --follow
Gesamten Traffic für einen bestimmten Pod in einem beliebigen Namespace streamen gke-hubble observe --pod default/my-pod --follow
Traffic zwischen zwei bestimmten Namespaces filtern gke-hubble observe --from-namespace frontend --to-namespace backend
Traffic auf einem bestimmten Port (z. B. Port 80) isolieren gke-hubble observe --port 80
Live-DNS-Abfragen und -Antworten prüfen gke-hubble observe --port 53
Live-TCP-Zurücksetzungen (RST-Pakete) ansehen gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST
Gesamten ausgehenden Traffic streamen, der an das öffentliche Internet gerichtet ist gke-hubble observe --traffic-direction egress --to-identity world
HTTP-Traffic auf Anwendungsebene (OSI-Layer 7) prüfen gke-hubble observe --protocol http

Erweiterte Filterung mit Negation (--not)

Sie können bekannten Traffic mit hohem Volumen oder unbedenklichen Traffic ausschließen, um sich auf Anomalien zu konzentrieren:

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

Ausgabeformatierung und jq-Integration

Wenn Sie Flussdatensätze programmatisch verarbeiten möchten, geben Sie sie im JSON-Format aus:

# 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'

Beschränkungen

Beachten Sie bei der Verwendung der Hubble-Befehlszeile für die Live-Fehlerbehebung die folgenden technischen Einschränkungen:

  • Flüchtiger knotenlokaler Ringpuffer: Hubble-Flüsse werden in einem speicherinternen Ringpuffer auf jedem einzelnen Knoten gespeichert. Bei Ereignissen mit hohem Traffic werden ältere Flusslogs innerhalb von Sekunden überschrieben. Für historische Analysen können Sie NetworkPolicy-Logging und VPC-Flusslogs in Cloud Logging verwenden.
  • Kein integriertes logisches ODER: Hubble-Befehlszeilen-Flags werten mehrere Argumente mit einem logischen UND aus. Wenn Sie nach mehreren Bedingungen suchen möchten (z. B. Port 80 ODER Port 443), führen Sie separate Befehle aus oder filtern Sie die JSON-Ausgabe mit jq.

Nächste Schritte