Fehlerbehebung bei der Netzwerkbeobachtbarkeit in GKE

Dieses Dokument enthält Anleitungen und Diagnoseverfahren zum Diagnostizieren von Netzwerkproblemen in Google Kubernetes Engine-Clustern (GKE) mit GKE Dataplane V2-Beobachtbarkeit, Hubble und Cloud Monitoring.

Einen architektonischen Überblick 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, verwenden Sie die folgende Entscheidungsmatrix, um zu ermitteln, welche Ebene des GKE-Netzwerkstacks wahrscheinlich das Problem verursacht, und rufen Sie den entsprechenden Abschnitt auf.

Symptom oder Frage zu Hauptlernbereichen Vermutete Stufe Empfohlene Vorgehensweise
Pods können externe Domains oder interne Kubernetes-Dienste nicht auflösen (DNS-Timeouts, NXDOMAIN, SERVFAIL). Stufe 1: Pod und Dienst (DNS) Fehler bei der DNS-Auflösung diagnostizieren
Dienste können nicht kommunizieren. Es kommt zu Zeitüberschreitungen bei Verbindungen oder verworfenen Paketen 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-Resets (RST). Stufe 1: Pod und Dienst (Load-Balancing oder Transport) Ungleichgewicht beim Traffic und TCP-Resets diagnostizieren
Allgemeine Latenz, zeitweilige Zeitüberschreitungen oder CNI-Neustarts auf Knoten. Stufe 2: Knoten und CNI (Kernel) Latenz auf Knotenebene und CNI-Engpässe beheben
Pods können nicht auf Ressourcen außerhalb von GKE zugreifen (Cloud SQL, externe APIs oder andere VPCs). Stufe 3: VPC und Routing GKE- von VPC- oder externen Verbindungsproblemen isolieren
Sie benötigen eine automatisierte Pfadsimulation, um zu prüfen, ob Firewallregeln, Routen oder NetworkPolicies den Traffic blockieren. Stufe 3: VPC und Routing (Simulation) Verbindungsprobleme mithilfe von 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 Datenübertragung zwischen Zonen oder die Notwendigkeit, die wichtigsten Kommunikationspartner zu visualisieren, ohne SQL-Abfragen zu schreiben. Stufe 4: Externes Gateway und Kosten Kosten und Leistung von Cluster-Traffic mit Flow Analyzer analysieren

Wichtige Netzwerkkonzepte

Wenn Sie neu in Kubernetes oder Google Cloud Networking sind, sollten Sie die folgenden Kernkonzepte beachten:

  • eBPF (Extended Berkeley Packet Filter): Eine Betriebssystemtechnologie, mit der sichere Überwachungs- und Routing-Programme direkt im Linux-Kernel ausgeführt werden können. GKE Dataplane V2 verwendet eBPF, um Pakete weiterzuleiten und NetworkPolicies mit minimalem Leistungsaufwand durchzusetzen.
  • IP-Maskierung (SNAT): Das Umschreiben der Quell-IP-Adresse eines Pakets. Wenn ein GKE-Pod (mit einer privaten IP-Adresse) mit dem Internet oder externen VPC-Ressourcen kommuniziert, maskiert (schreibt um) GKE die Pod-IP-Adresse in die Knoten-IP-Adresse, damit externe Systeme wissen, wie die Antwort weitergeleitet werden soll.
  • Connection Tracking (Conntrack): Eine Kernelfunktion, die alle aktiven Netzwerkverbindungen verfolgt. In GKE Dataplane V2-Clustern wird diese Nachverfolgung auf zwei Tabellen aufgeteilt: die standardmäßige Linux-Kernel-Conntrack-Tabelle (die von der ip-masq-agent verwendet wird) und eine von Cilium und GKE Dataplane V2 verwaltete Conntrack-Tabelle, die in einer eBPF-Karte gespeichert ist. Wenn ein Knoten zu viele gleichzeitige Verbindungen verarbeitet, kann eine der beiden Tracking-Tabellen voll werden (conntrack exhaustion). In diesem Fall verwirft der Knoten neue Pakete, ohne dass eine Fehlermeldung ausgegeben wird.
  • Hubble:Die Beobachtbarkeits-Engine für GKE Dataplane V2. Es basiert auf eBPF und bietet Echtzeitinformationen zu Traffic-Flüssen, Paketverlusten und der Auswertung von NetworkPolicy.

Stufe 1: Beobachtbarkeit von Pod und Dienst (Anwendung)

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

Fehler bei der DNS-Auflösung diagnostizieren

Sehen Sie sich vor der Fehlerbehebung bei DNS-Problemen den Diagnosebereich und die Voraussetzungen an:

  • Fokusbereich:Kommunikation zwischen Pods und CoreDNS oder NodeLocal DNSCache, DNS-Latenz, Upstream-DNS-Auflösungszeitüberschreitungen und FQDN-NetworkPolicy-Validierung.
  • Voraussetzungen:GKE Dataplane V2-Messwerte aktiviert; kubectl-Zugriff.
  • CNI-Kompatibilität:GKE Dataplane V2 (Advanced Datapath) und Standard-GKE-CNI.
  • Symptom:In den Logs der Pods werden dial tcp: lookup <domain>: i/o timeout, NXDOMAIN oder zeitweise Latenz bei ausgehenden API-Aufrufen protokolliert.
  • Ziel:Ermitteln, ob der DNS-Fehler im Cluster (kube-dns- oder NodeLocal DNSCache-Sättigung), durch eine NetworkPolicy, die UDP- oder TCP-Port 53 blockiert, oder durch eine Verschlechterung des Upstream-Netzwerks verursacht wird.

Schritt 1: Grundlegende Erreichbarkeitsprüfung

Bevor Sie mit der Fehlerbehebung bei DNS-Ebenen beginnen, prüfen Sie, ob das Ziel direkt über seine IP-Adresse vom betroffenen Pod aus 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 jedoch nicht, liegt das Problem an der DNS-Auflösung. Fahre mit Schritt 2 fort.
  • Wenn beide fehlgeschlagen sind:Das Problem liegt am Routing auf Netzwerkebene oder an der Durchsetzung von Richtlinien. Fahren Sie mit Paketverluste und NetworkPolicy-Blockierungen diagnostizieren fort.
Prüfen, ob DNS-Einträge für FQDN-Netzwerkrichtlinien vorab ausgefüllt werden

Wenn Ihr Cluster FQDN-basierte NetworkPolicies (FQDNNetworkPolicy) verwendet, prüfen Sie, ob der Domainname explizit zulässig 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 die Richtlinie zugelassen wird, blockiert GKE Dataplane V2 den ausgehenden Traffic zur aufgelösten 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

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 – Cluster View aus oder rufen Sie Metrics Explorer auf und filtern Sie nach kubernetes.io/networking/dns/.
  3. Bewerten Sie die folgenden primären Signale (für NodeLocal DNSCache ersetzen Sie kubedns im Messwertpfad durch node_local_dns):
Messwertname Grenzwert für „Warnung“ Ursache
kubernetes.io/networking/dns/kubedns/max_concurrent_rejected_request_count > 0 Limit für gleichzeitige Anfragen erreicht. kube-dns oder NodeLocal DNSCache verwirft Anfragen.
kubernetes.io/networking/dns/kubedns/dns_request_latencies p99 > 100 ms Hohe End-to-End-DNS-Auflösungslatenz bei kube-dns oder NodeLocal DNSCache.
kubernetes.io/networking/dns/kubedns/forwarding_request_latencies p99 > 100 ms Latenz oder Überlastung des Upstream-DNS-Servers.
DNS-Leistung und Triage-Sequenz für Zeitüberschreitungen

Führen Sie die folgenden Schritte aus, um DNS-Latenz, Cache-Fehler und Upstream-Timeouts 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 Anfragen ohne FQDN (z. B. my-service anstelle von my-service.default.svc.cluster.local), was zu einem Path Traversal über alle Einträge in /etc/resolv.conf führt.
  2. Upstream-Latenz bewerten:Ein hoher forwarding_request_latencies weist auf Probleme mit dem Upstream-DNS-Server hin, z. B. mit dem lokalen DNS des Unternehmens, auf den über Cloud Interconnect oder Cloud VPN zugegriffen wird, oder mit Cloud DNS-Limits.
  3. Benutzerdefinierte DNS-Überschreibungen prüfen:Untersuchen Sie benutzerdefinierte kube-dns-ConfigMaps auf falsch konfigurierte Stubs oder Upstream-Weiterleitungen:

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

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

Verwenden Sie den Hubble-CLI-Helper-Alias, um Live-DNS-Anfragen und ‑Antworten zu prüfen, die vom Knoten-Kernel 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 überprüfen

Wenn es zu gleichzeitigen Ablehnungen von Anfragen gekommen ist, wenden Sie NodeLocal DNSCache an, um DNS-Lookups mit hoher Frequenz direkt auf dem Knoten zu verarbeiten, ohne die clusterweiten kube-dns-Limits zu überschreiten:

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

Paketverluste und NetworkPolicy-Blockierungen diagnostizieren

Sehen Sie sich den Diagnosebereich und die Voraussetzungen an, bevor Sie Paketverluste und Richtlinienablehnungen untersuchen:

  • Fokusbereich:Traffic-Rückgänge zwischen Pod-Objekten oder zwischen Pod- und Service-Objekten, NetworkPolicy-Durchsetzung, Kernel-eBPF-Ablehnungsgründe.
  • Voraussetzungen:GKE Dataplane V2-Ablaufbeobachtbarkeit aktiviert; NetworkPolicy-Logging konfiguriert.
  • CNI-Kompatibilität:Nur GKE Dataplane V2.
  • Symptom:Verbindungsversuche der App schlagen mit Connection timed out oder Connection reset by peer fehl.
  • Ziel:Die genaue NetworkPolicy- oder eBPF-Ursache für das Verwerfen von Paketen ermitteln, ohne dass Änderungen an Sicherheitsrichtlinien erforderlich sind.

Schritt 1: Hubble-Drop-Messwerte beobachten

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

  1. Wenn noch nicht konfiguriert, stellen Sie eine PodMonitoring-Ressource für Google Cloud Managed Service for Prometheus bereit, um Hubble-Messwerte zu erfassen:

    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 Gründe für das Löschen von Paketen aufzurufen:

    sum by (reason) (rate(hubble_drop_total[5m])) > 0
    
  3. Häufige reason-Codes interpretieren:

    • Policy denied: Eine Kubernetes-Netzwerkrichtlinie blockiert die Verbindung explizit oder implizit.
    • CT: Map insertion failed: Die conntrack-Tabelle (Connection Tracking) 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. JSON-Nutzlast prüfen:

    • jsonPayload.drop_reason: Hier wird angezeigt, warum das Paket verworfen wurde.
    • jsonPayload.policies: Hier wird aufgeführt, welche NetworkPolicies ausgewertet wurden. Wenn mit dem Ergebnis DENY eine leere Liste zurückgegeben wird, wird der Namespace im Standardablehnungsmodus ausgeführt und es wurde keine Richtlinie gefunden, die den Traffic zulässt.

Wenn keine NetworkPolicy-Logs angezeigt werden, prüfen Sie, ob die Protokollierung 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 mit der Hubble-Befehlszeile Echtzeitpakete 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: Prüfen, ob die conntrack-Tabelle voll ist

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

  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, horizontal skalieren Sie Ihre Arbeitslasten auf mehr Knoten oder reduzieren Sie die Verbindungsrate von Client-Pods.


Ungleichgewicht beim Traffic und TCP-Resets diagnostizieren

Sehen Sie sich den Diagnosebereich und die Voraussetzungen an, bevor Sie Probleme mit Traffic-Ungleichgewicht und Verbindungsrücksetzungen beheben:

  • Fokusbereich:Ungleichmäßiges Load-Balancing, fehlgeschlagene TCP-Handshakes, plötzliches Beenden von Verbindungen.
  • Voraussetzungen:GKE Dataplane V2-Messwerte sind aktiviert.
  • CNI-Kompatibilität:GKE Dataplane V2.
  • Symptom:Bestimmte Pod-Replikate empfangen übermäßigen Traffic, während andere im Leerlauf bleiben. Clientanwendungen protokollieren connection reset by peer oder broken pipe.
  • Ziel:Ermitteln, ob das Ungleichgewicht des Traffics durch die Verbindungshaftung auf der Transportebene (OSI-Schicht 4, TCP) oder auf der Anwendungsebene (OSI-Schicht 7, HTTP/2 oder gRPC) verursacht wird, und die Quelle der TCP-RST-Pakete identifizieren.

Schritt 1: Traffic-Flow auf Pod-Ebene vergleichen

So prüfen Sie, ob der Traffic gleichmäßig auf Ihre Replikate verteilt ist:

  1. So fragen Sie in Cloud Monitoring die Anzahl der Ingress-Flows für alle Pods in einer Bereitstellung ab:

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

    • gRPC oder HTTP/2:Bei langlebigen TCP-Verbindungen werden alle Anfragen über einen einzelnen TCP-Stream an einen Backend-Pod gesendet. Transportebene (OSI-Schicht 4, TCP): Das Kubernetes-Service-Routing kann Anfragen innerhalb einer bestehenden HTTP/2-Verbindung nicht ausgleichen.
    • ClientIP-Sitzungsaffinität:Prüfen Sie, ob der Dienst mit sessionAffinity: ClientIP konfiguriert ist.
    • Monitorlose Dienste:Clients lösen DNS möglicherweise einmal auf und cachen die einzelne IP-Adresse dauerhaft.

Schritt 2: TCP-Reset-Messwerte analysieren

TCP-Resets (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 Puffer 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 Ergebnisse der Abfrage an, um die Quelle des Zurücksetzens zu ermitteln:

  • Ausgehender 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 das Zurücksetzen gesendet. Prüfen Sie den Systemstatus des Zielservers und die Firewallstatus.

Schritt 3: TCP-Resets 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: Behebung und umsetzbare Korrekturen

Führen Sie je nach Ursache für das Ungleichgewicht beim Traffic oder die TCP-Resets die folgenden Schritte zur Fehlerbehebung aus:

  • Für die Stickiness von Verbindungen auf Anwendungsebene (OSI-Schicht 7) oder gRPC-Verbindungen:
    • Stellen Sie Cloud Service Mesh bereit, um das Load-Balancing auf Anwendungsebene (OSI-Schicht 7) auf Anfrageebene zu aktivieren.
    • Konfigurieren Sie clientseitige Verbindungslimits oder Keep-Alive-Timeouts (z. B. gRPC MAX_CONNECTION_AGE und MAX_CONNECTION_AGE_GRACE), um das regelmäßige Wiederherstellen von Verbindungen zu erzwingen.
  • Für die Service-IP-Affinität:Entfernen Sie service.spec.sessionAffinity, sofern der Anwendungsstatus dies nicht unbedingt erfordert.
  • DNS-Caching für monitorlose Dienste:Achten Sie darauf, dass Anwendungs-Runtimes (z. B. JVM networkaddress.cache.ttl) DNS-Ergebnisse nicht unbegrenzt im Cache speichern.
  • Bei einem Überlauf der Anwendungs-Backlog-Warteschlange:Wenn eine Anwendungs-Listen-Warteschlange voll ist, verwirft der Linux-Kernel eingehende SYN-Pakete oder sendet ein TCP-RST. Skalieren Sie Pod-Replikate horizontal oder erhöhen Sie den Listen-Backlog der Anwendung (somaxconn).

Stufe 2: Beobachtbarkeit von Knoten und CNI (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: Unautorisiertes Patchen 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 zu erkennen, 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 nicht autorisiertes Patchen erkannt wird, setzen Sie das DaemonSet auf die Standardkonfiguration zurück oder lösen Sie die Neuerstellung eines Knotenpools aus, um den verwalteten Zustand wiederherzustellen.


Triage für Latenz auf Knotenebene und CNI-Engpässe

Sehen Sie sich den Diagnosebereich und die Voraussetzungen an, bevor Sie die Latenz auf Knotenebene und Kernel-Engpässe diagnostizieren:

  • Fokusbereich:Host-Kernel-Latenz, Paketverluste an der VM-Schnittstelle, Sättigung des GKE Dataplane V2-eBPF-Agents, Erschöpfung von „conntrack“.
  • Voraussetzungen:Compute Engine-VM-Messwerte aktiviert; kubectl-Zugriff.
  • CNI-Kompatibilität:GKE Dataplane V2 und Standard-GKE-CNI.
  • Symptom:Beim Traffic zwischen Knoten treten Latenzspitzen oder zufällige Einbrüche auf, während der Traffic innerhalb von Knoten normal bleibt.
  • Ziel:Unterscheidung zwischen der 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 bei der eigenständigen VM dieselben Paketverluste oder Latenz 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, GKE-Pods jedoch fehlschlagen:Das Problem liegt in GKE (eBPF auf Knotenebene, conntrack oder CNI). Fahre mit Schritt 2 fort.

Schritt 2: Anwendungs- von Knoten- und CNI-Problemen unterscheiden

So stellen Sie fest, ob die Latenz in der Anwendung oder auf der Knoten- und CNI-Ebene auftritt:

  1. Anwendungssättigung der Ressourcen prüfen:Prüfen Sie, ob auf dem Knoten CPU-Drosselung oder Arbeitsspeicherbelastung auftritt, wodurch die Paketverarbeitung im Nutzerbereich verzögert wird:

    kubectl top nodes
    kubectl top pods -n default
    
  2. Anzahl der conntrack-Einträge des Linux-Kernels prüfen:Prüfen Sie die Anzahl der aktiven conntrack-Einträge 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 nf_conntrack_count sich nf_conntrack_max nähert, verwirft der Host-Kernel neue TCP-SYN-Pakete.

Schritt 3: Paketverluste auf VM-Ebene mit Compute Engine-Telemetrie prüfen

Google Cloud Compute Engine exportiert Messwerte für Netzwerkschnittstellen 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 (VM-Ausgangsbandbreitenlimit überschritten).
  • FIREWALL_RULE_DROP: Paket, das von einer VPC-Firewallregel verworfen wurde.
  • RATE_LIMIT_DROP: Das Paket wurde verworfen, weil die VM das Kontingent für die maximale Anzahl von Paketen pro Sekunde (PPS) für die Netzwerkschnittstelle überschritten hat.

Schritt 4: Paketverluste auf Kernelebene mit eBPF untersuchen

Wenn auf VM-Ebene keine Paketverluste auftreten, aber in GKE-Pods weiterhin Pakete verloren gehen, prüfen Sie den GKE Dataplane V2-Agenten (anetd) auf eBPF-Kartendrops:

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.


Tier 3: VPC- und Routing-Beobachtbarkeit (Cloud Network)

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

GKE-Probleme von VPC- oder externen Verbindungsproblemen isolieren

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

  • Fokusbereich:Grenzisolierung zwischen dem internen Kubernetes-Routing und dem 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 Drittanbieterendpunkt).
  • Ziel:Schnell feststellen, ob der Drop auf dem GKE-Knoten oder im Google Cloud VPC- oder externen Netzwerk auftritt.

Schritt 1: Compute Engine-VM-Basistest

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 mit SSH eine 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:Das Problem liegt im VPC- oder externen Netzwerk (Firewallregeln, Routingtabellen, Cloud NAT-IP-Erschöpfung oder Whitelisting externer IP-Adressen).
    • Wenn die Compute Engine-VM erfolgreich eine Verbindung herstellt, liegt das Problem in GKE (NetworkPolicy blockiert den Egress, nicht maskierter Pod-CIDR oder DNS auf Containerebene).

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

Führen Sie einen Google Cloud Konnektivitätstests-Test 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

Prüfen Sie das Ergebnis in der Google Cloud -Konsole, um festzustellen, ob der Traffic durch eine VPC-Firewallregel oder ‑Route verworfen wird.


Konnektivität mit Konnektivitätstests diagnostizieren

Bei Konnektivitätstests werden Paketpfade für GKE- und VPC-Ressourcen simuliert, ohne dass Live-Traffic gesendet wird. Bei dieser Simulation wird die DNAT-Auflösung von Service-ClusterIP zu Pod, die Ingress- und Egress-Regeln von GKE Dataplane V2 NetworkPolicy und die IP-Maskierung (SNAT) des Knotens ausgewertet. Prüfen Sie den Diagnosebereich und die Voraussetzungen, bevor Sie automatisierte Pfadsimulationen ausführen:

  • Fokusbereich:Automatisierte Simulation statischer Pfade für GKE-Pods, -Dienste, -NetworkPolicies und VPC-Routen.
  • Voraussetzungen:Network Intelligence Center und Network Management API müssen aktiviert sein.
  • CNI-Kompatibilität:GKE Dataplane V2 (erweiterte Analyse).
  • Symptom:Unerklärliche Verbindungsabbrüche, bei denen alle Konfigurationen bei manueller Überprüfung gültig erscheinen.
  • Ziel:Den gesamten Paketpfad von einer Pod-Quelle zum Ziel statisch simulieren und nachvollziehen, um die genaue Richtlinienzeile zu ermitteln, die einen Drop verursacht.

Szenario A: Prüfen, ob eine GKE-NetworkPolicy die Erfassung von Messwerten blockiert

Beim Erfassen von Messwerten aus Pods in einem sicheren Namespace werden die Collectors von Google Cloud Managed Service for Prometheus möglicherweise durch eine NetworkPolicy mit Standardablehnung 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

Sehen Sie sich den Testlauf in der Google Cloud -Konsole an. Wenn der Test im Schritt GKE Network Policy evaluation mit DROP beendet wird, muss eine Ingress-Regel hinzugefügt werden, um Traffic von den Collector-Pods zuzulassen.

Szenario B: Erreichbarkeit eines GKE-Dienstes prüfen

Erreichbarkeit von einer Client-VM zu einem internen Kubernetes-Dienst simulieren:

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

Der simulierte Trace zeigt Folgendes:

  1. VPC-Routenübereinstimmung.
  2. VPC-Firewall für ausgehenden und eingehenden Traffic zulassen.
  3. Ankunft am GKE-Knoten.
  4. Service-DNAT zur IP-Adresse des Backend-Pods.
  5. Auswertung von Ingress-NetworkPolicy für den Backend-Pod.

Szenario C: Probleme beim Pod-to-Internet-Ausgang diagnostizieren

Wenn Pods keine Verbindung zu einer externen API im Internet herstellen 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
    
  2. Untersuchen Sie den Drop-Punkt:

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

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

In der externen Gatewayschicht wird ausgehender Traffic zu Zielen im öffentlichen Internet über Cloud NAT oder externe Gateways verwaltet. Die Beobachtbarkeit auf dieser Ebene hilft, Arbeitslasten mit hohem ausgehenden Traffic zu identifizieren und die Kosten für die Datenübertragung zu kontrollieren.

NAT-Traffic identifizieren (Ausgang zum Internet)

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

  • Fokusbereich:Ausgehender Internet-Traffic, Cloud NAT-Portauslastung, Kosten für externe Datenübertragung.
  • Voraussetzungen:Die Beobachtbarkeit von GKE Dataplane V2-Flows ist aktiviert.
  • CNI-Kompatibilität:GKE Dataplane V2.
  • Symptom:Cloud NAT-Fehler aufgrund von Portauslastung oder unerwartet hohe Kosten für ausgehenden Internet-Traffic.
  • Ziel:Ermitteln, welche spezifischen GKE-Pod- und Dienstobjekte Traffic an externe Internetendpunkte übertragen.

Schritt 1: „To-Stack“- und „World“-Konzepte in GKE Dataplane V2 verstehen

In GKE Dataplane V2:

  • world: steht für jedes Ziel außerhalb des GKE-Cluster und außerhalb der VPC (das öffentliche Internet).
  • to-stack: Stellt Pakete dar, die von der eBPF-Container-veth-Schnittstelle zum Linux-Netzwerkstack des Hosts übergehen, um vor dem Erreichen von Cloud NAT IP-Masquerading (SNAT) zu durchlaufen.

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

Ausgehende Internet-Streams aus Ihrem Cluster streamen:

# 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

Um die wichtigsten ausgehenden Kommunikationspartner zu ermitteln, können Sie die Hubble-JSON-Ausgabe auch an jq weiterleiten, um externe ausgehende Traffic-Flows 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 mit Messwerten im Blick behalten

So verfolgen Sie das Volumen externer Flows in Cloud Monitoring:

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 von Cluster-Traffic mit Flow Analyzer analysieren

Sehen Sie sich den Diagnosebereich und die Voraussetzungen an, bevor Sie Traffic-Flüsse und zonenübergreifende Kosten visualisieren:

  • Fokusbereich:Kosten für die zonenübergreifende Datenübertragung, Top-Talker, Sichtbarkeit des Knotenverkehrs 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:Auf monatlichen Rechnungen vonGoogle Cloud werden erhöhte Gebühren für die Datenübertragung zwischen Zonen ausgewiesen.
  • 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 für den Cluster aktiviert sein, damit Pod-zu-Pod-Traffic für die VPC-Flusslog-Pipeline verfügbar gemacht wird.
  3. Log Analytics:Der _Default-Bucket in Cloud Logging muss für die Verwendung von Observability Analytics aktualisiert werden.

Schritt 1: GKE-Top-Talkers 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 Flow-Logs enthält. Sofern 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 Abläufe organisieren nach die Felder für GKE-Pod oder Arbeitslast aus.
  6. Klicken Sie auf Neue Abfrage ausführen. Im Diagramm Höchste Datenflüsse sehen Sie, bei welchen Arbeitslasten die meisten Daten übertragen werden.

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

Für zonenübergreifenden Traffic fallen Datenübertragungskosten an. So finden Sie Arbeitslasten, die zonenübergreifend übertragen werden:

  1. Wählen Sie unter Datenflüsse organisieren nach die Felder für Quellzone und Zielzone aus.
  2. Klicken Sie auf Neue Abfrage ausführen und lesen Sie die Tabelle Alle Datenflüsse. In Zeilen, in denen sich die Quell- und Zielzonen unterscheiden, sehen Sie Ihren zonenübergreifenden Traffic. Flow Analyzer-Filter werden auf Werte abgestimmt. 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-Arbeitslasten für Quelle und Ziel zu sehen.

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 Log Analytics 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 Kernel-Ringpuffer von GKE Dataplane V2.

Einrichtung: Helper-Alias erstellen

Da Hubble auf 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 für die Fehlerbehebung Hubble-Befehlszeilenbefehl
Alle verworfenen Pakete im 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 an 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-Resets (RST-Pakete) ansehen gke-hubble observe --type trace --verdict FORWARDED --tcp-flags RST
Gesamten ausgehenden Traffic, der an das öffentliche Internet gerichtet ist, streamen gke-hubble observe --traffic-direction egress --to-identity world
HTTP-Traffic auf Anwendungsebene (OSI-Schicht 7) prüfen gke-hubble observe --protocol http

Erweiterte Filterung mit Negation (--not)

Sie können bekannten Traffic mit hohem Volumen oder normalen 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

So verarbeiten Sie Flussdatensätze programmatisch und geben die Ausgabe 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-Flows werden auf jedem einzelnen Knoten in einem In-Memory-Ringpuffer gespeichert. Bei Ereignissen mit hohem Traffic werden ältere Flow-Logs innerhalb von Sekunden überschrieben. Für die Verlaufsanalyse können Sie sich auf NetworkPolicy-Logging und VPC-Flusslogs in Cloud Logging verlassen.
  • Kein integriertes logisches ODER:Hubble-CLI-Flags werten mehrere Argumente mit logischem 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