Zum Inhalt springen

Kubernetes-Netzwerk-Diagramm: Pods, Services, CNI und Network Policies

Wie Kubernetes-Netzwerke Schicht für Schicht funktionieren: Pod-IPs und CNI-Plugins, Overlays, Services und kube-proxy, CoreDNS, NetworkPolicy und Gateway API.

· Gründer & Entwickler

Veröffentlicht am

Zwei Worker-Node-Frames. Nutzer erreichen ein Gateway, das zu einem web-Pod auf worker-1 routet. Der web-Pod fragt den api-Service in CoreDNS ab und verbindet sich mit dessen ClusterIP, die zu zwei api-Pods auf worker-2 führt. Eine NetworkPolicy wählt sie aus; VXLAN verbindet die Nodes.

Ein Pod im Namespace shop ruft http://api auf, und der Request läuft in ein Timeout. Der Pod läuft, der Service existiert, und seine EndpointSlice listet zwei bereite Backends. Der Fehler kann im DNS liegen, in den Regeln, die kube-proxy auf den Node geschrieben hat, im Overlay zwischen den Nodes oder in einer NetworkPolicy, die jemand letzte Woche angewendet hat. Jedes davon ist eine eigene Schicht, die von einer eigenen Komponente betrieben wird.

Dieser Beitrag geht diese Schichten anhand eines Diagramms durch: das Netzwerkmodell, Pod-zu-Pod-Traffic, CNI-Plugins, Services, DNS, NetworkPolicy und den Traffic in den Cluster hinein und aus ihm heraus.

Das Kubernetes-Netzwerkmodell

Das Kubernetes-Netzwerkmodell hat drei Regeln. Jeder Pod bekommt eine eigene clusterweite IP-Adresse, die sich seine Container teilen. Jeder Pod kann jeden anderen Pod auf jedem Node ohne Proxys oder NAT erreichen. Und Node-Agents wie das kubelet können alle Pods auf ihrem Node erreichen.

Kubernetes definiert die APIs, und die Komponenten, die du installierst, erledigen die Arbeit:

Schicht Was du bekommst Umgesetzt von
Pod-Netzwerk Eine IP pro Pod, Erreichbarkeit von Pod zu Pod Einem CNI-Plugin
Services Eine stabile virtuelle IP und ein Name für eine Gruppe von Pods kube-proxy oder einem eBPF-Ersatz
DNS Namen wie api.shop.svc.cluster.local CoreDNS
NetworkPolicy Allow-Regeln für Pod-Traffic Dem CNI-Plugin
Ingress, Gateway API Routing von außerhalb des Clusters Einem Controller, den du installierst

Diese Aufteilung erklärt viele Überraschungen, etwa eine NetworkPolicy, die der API-Server akzeptiert, die dein Plugin aber stillschweigend ignoriert.

Pod zu Pod auf demselben Node

Wenn die Container-Runtime einen Pod startet, ruft sie das CNI-Plugin mit ADD auf. Die meisten Plugins erstellen ein veth-Paar, ein virtuelles Kabel mit eth0 im Pod und dem anderen Ende auf dem Host, und vergeben die IP. Flannel steckt das Host-Ende in eine Linux-Bridge, cni0; Calico verzichtet auf die Bridge: Jeder Pod bekommt eine /32-Route, und der Host fungiert als sein Router. In beiden Fällen braucht Traffic auf demselben Node weder Kapselung noch NAT.

Pod zu Pod über Nodes hinweg: Overlay oder natives Routing

Jeder Node besitzt meist einen Ausschnitt des Pod-Bereichs. Mit dem Standardwert --node-cidr-mask-size von 24 beim kube-controller-manager ergibt ein Bereich 10.244.0.0/16 für 256 Nodes je ein /24, also 256 Adressen für die 110 Pods, die das kubelet standardmäßig erlaubt. Über Nodes hinweg hat das Plugin zwei Optionen:

Overlay (VXLAN, Geneve, IP-in-IP) Natives Routing (BGP, Cloud-Routen, VPC-IPs)
Das Netzwerk zwischen den Nodes sieht Nur Node-IPs Pod-IPs
Voraussetzung IP-Erreichbarkeit zwischen den Nodes Ein Netzwerk, das Pod-Bereiche routet, oder VPC-Adressen für Pods
Overhead pro Paket 50 Byte bei IPv4-VXLAN, 20 bei IP-in-IP Keiner
Beispiele Standardmodi von Flannel und Cilium, Calico VXLAN Calico mit BGP, AWS VPC CNI, Azure CNI

Der Overhead ist ein MTU-Problem: In einem 1.500-Byte-Netzwerk brauchen Pods hinter IPv4-VXLAN laut Calicos MTU-Leitfaden eine MTU von 1.450. Wenn du das falsch einstellst, verschwinden große Pakete, was wie zufällige Hänger aussieht.

CNI-Plugins im Vergleich

Plugin Traffic zwischen Nodes NetworkPolicy Hinweise
Flannel Standardmäßig VXLAN (UDP 8472); host-gw in einem gemeinsamen Layer-2-Netzwerk Wird von Flannel nicht durchgesetzt; kube-network-policies oder Calico ergänzen Klein und einfach
Calico BGP oder VXLAN-Overlay (UDP 4789) oder IP-in-IP-Overlay Vollständig, dazu Calicos namespacebezogene und globale Policies Data Planes für iptables, nftables, eBPF, VPP und Windows
Cilium Standardmäßig VXLAN (UDP 8472), Geneve oder natives Routing Vollständig, dazu Regeln auf Layer 7 und auf DNS-Basis eBPF-Datenpfad
AWS VPC CNI Kein Overlay; Pods bekommen VPC-Adressen Seit v1.14, mit enableNetworkPolicy Pods pro Node durch den Instanztyp begrenzt

Das AWS-Limit greift früh: Das Standardmaximum ist ENIs × (IPs pro ENI − 1) + 2, also betreibt eine m5.large mit 3 Interfaces zu je 10 Adressen 3 × 9 + 2 = 29 Pods. Prefix Delegation erhöht es.

Services: eine stabile IP vor wechselnden Pods

Pod-IPs ändern sich, sobald ein Pod ersetzt wird. Ein Service gibt einer Gruppe von Pods eine stabile virtuelle IP, die ClusterIP, und einen DNS-Namen; EndpointSlices verfolgen die Pods dahinter.

Typ Was du bekommst
ClusterIP (Standard) Eine virtuelle IP innerhalb des Clusters
NodePort Zusätzlich einen Port auf jedem Node, standardmäßig 30000–32767
LoadBalancer Zusätzlich einen Cloud- oder Add-on-Load-Balancer
ExternalName Einen DNS-Alias (CNAME), kein Proxying
Headless (clusterIP: None) Keine virtuelle IP; DNS liefert die Pod-IPs

Keine einzelne Maschine besitzt eine ClusterIP. Auf jedem Node programmiert kube-proxy den Kernel so, dass ein Paket an 10.96.48.20:80 (Destination NAT) auf eine Pod-Adresse wie 10.244.2.22:8080 umgeschrieben wird, bevor es den Node des Clients verlässt. Der Service ist ein logischer Schritt, kein Server. Die Regeln hängen vom Proxy-Modus ab:

Modus Status in Kubernetes 1.37 So funktioniert es
iptables Standard unter Linux Regeln pro Service und Endpoint; zufälliges Backend
nftables GA seit 1.33; der geplante künftige Standard Schnellere Updates im großen Maßstab; braucht Kernel 5.13 oder neuer
ipvs Deprecated seit 1.35; in 1.40 standardmäßig aus, in 1.43 entfernt IPVS-Tabellen im Kernel, mehr Balancing-Algorithmen
eBPF (Cilium, Calico) Ersetzt kube-proxy Load Balancing in eBPF-Programmen

Setze den Modus explizit, damit ein Upgrade ihn nicht ändern kann, und plane den Umstieg weg von IPVS. Im nftables-Modus lauschen NodePorts standardmäßig nur auf den primären Adressen des Nodes.

DNS mit CoreDNS

CoreDNS ist das Standard-Cluster-DNS, und kubeadm betreibt es hinter einem Service, der weiterhin kube-dns heißt. Jeder Service bekommt einen Namen, <service>.<namespace>.svc.cluster.local, der zu seiner ClusterIP aufgelöst wird, bei einem Headless Service zu den Pod-IPs. Das kubelet schreibt die /etc/resolv.conf jedes Pods; in shop auf einem kubeadm-Cluster lautet sie typischerweise:

nameserver 10.96.0.10
search shop.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

Der Haken ist ndots:5: Ein Name mit weniger als fünf Punkten, etwa api.stripe.com, wird zuerst mit jeder Search Domain probiert, sodass eine externe Abfrage drei fehlgeschlagene Queries kosten kann. Hänge bei häufig genutzten Namen einen Punkt an, senke ndots in der dnsConfig des Pods oder betreibe NodeLocal DNSCache. Externe Namen nehmen dann den Weg, der in So funktioniert DNS gezeigt wird.

NetworkPolicy: von Default Allow zu Least Privilege

Standardmäßig nimmt jeder Pod Traffic von überall an. Sobald irgendeine NetworkPolicy einen Pod für Ingress (oder Egress) auswählt, kommt nur durch, was eine Policy erlaubt; Antworten sind automatisch erlaubt. Policies fügen nur Allow-Regeln hinzu, deshalb spielt die Reihenfolge nie eine Rolle. Beginne jeden Namespace mit einem Default Deny:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: shop
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Öffne dann, was du brauchst, hier TCP 8080 von web zu api:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-web
  namespace: shop
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: web
    ports:
    - protocol: TCP
      port: 8080

Vier Details erwischen viele:

  • Der Port ist der Port des Pods, 8080, nicht der Service-Port 80.
  • Das Default Deny isoliert auch die web-Pods, das Gateway braucht also eine eigene Regel, um sie zu erreichen.
  • Ein Bindestrich ändert die Bedeutung. Ein namespaceSelector und ein podSelector in einem from-Eintrag müssen beide passen; als zwei Einträge genügt einer von beiden.
  • Default Deny bei Egress blockiert DNS, erlaube also zuerst Port 53 zu kube-dns.

NetworkPolicy kennt keine Deny-Regeln, keinen clusterweiten Geltungsbereich und nichts für TLS; für Mutual TLS zwischen Workloads siehe das Service-Mesh-Architekturdiagramm.

Traffic hinein und hinaus: Ingress, Gateway API und Egress

Ingress ist stabil, aber eingefroren, und das Kubernetes-Projekt empfiehlt stattdessen die Gateway API. Der Community-Controller Ingress NGINX wurde im März 2026 eingestellt und bekommt keine Sicherheitsfixes mehr, doch bestehende Installationen laufen unbemerkt weiter.

Die Gateway API teilt die Aufgabe nach Rollen auf: Plattform-Verantwortliche betreiben das Gateway mit seinen Listeners und Zertifikaten, und Anwendungsteams hängen HTTPRoutes aus ihren eigenen Namespaces an. Sie erreichte im Oktober 2023 GA, und die Releases von 2026 machten auch TLSRoute, TCPRoute und UDPRoute zum Standard. Das Kubernetes-Ingress-Diagramm folgt diesem Pfad Hop für Hop.

Egress ist die vergessene Richtung. Traffic, der den Cluster verlässt, wird meist auf die IP des Nodes übersetzt, wie es das AWS VPC CNI für Ziele außerhalb der VPC tut. Begrenze ihn mit Egress-Regeln, die externe Ziele nur als IP-Bereiche sehen, mit DNS-fähigen Regeln wie Ciliums toFQDNs oder mit einem Egress Gateway, wenn ein Partner eine feste Quell-IP braucht.

Das Kubernetes-Netzwerk-Diagramm

Zwei Worker-Node-Frames. Nutzer erreichen ein Gateway, das zu einem web-Pod auf worker-1 routet. Der web-Pod fragt den api-Service in CoreDNS ab und verbindet sich mit dessen ClusterIP, die zu zwei api-Pods auf worker-2 führt. Eine NetworkPolicy wählt sie aus; VXLAN verbindet die Nodes.

15 Komponenten · 9 Verbindungen

In Archboard öffnen
Diagramminhalt
  • worker-1 · pods 10.244.1.0/24
  • worker-2 · pods 10.244.2.0/24
  • Users
  • public-gw
  • web · 10.244.1.12
  • coredns · 10.244.1.5
  • api · 10.244.2.21
  • api · 10.244.2.22
  • api · 10.96.48.20
  • api-allow-web
  • HTTPS 443
  • HTTPRoute
  • DNS: api.shop.svc.cluster.local via kube-dns 10.96.0.10
  • TCP 10.96.48.20:80
  • DNAT 10.244.2.21:8080
  • DNAT 10.244.2.22:8080
  • VXLAN overlay over UDP · node IP to node IP
Ein Request durch einen Cluster mit zwei Nodes: herein durch ein Gateway, eine DNS-Abfrage, eine ClusterIP, die kube-proxy auf eine Pod-IP umschreibt, ein VXLAN-Hop zum anderen Node und eine NetworkPolicy, die entscheidet, wer sich verbinden darf. Jede Schicht fällt anders aus.

So liest du es:

  • Zwei Worker-Nodes, jeder mit seinem /24-Pod-Bereich beschriftet.
  • Blau ist Nord-Süd: Nutzer erreichen public-gw über HTTPS 443, und eine HTTPRoute schickt sie zum web-Pod.
  • Bernstein ist DNS: web fragt CoreDNS über kube-dns unter 10.96.0.10 nach api.shop.svc.cluster.local und erhält 10.96.48.20.
  • Türkis ist der Service-Pfad: web verbindet sich mit 10.96.48.20:80, und kube-proxy-Regeln auf worker-1 schreiben das auf einen api-Pod an Port 8080 um.
  • Grau ist das Overlay: Das Paket quert in VXLAN zwischen den Node-IPs zu worker-2.
  • Rot ist die Policy: api-allow-web lässt nur app=web-Pods die api-Pods erreichen.
  • Der Markdown-Block listet die Standardwerte hinter den Zahlen auf.

Kubernetes-Netzwerk-Diagramme klar zeichnen

  • Beschrifte Nodes mit Pod-Bereichen und Pods mit IPs, den Details, nach denen du in Logs suchst.
  • Zeichne den Service als logischen Schritt und notiere, wo das Umschreiben stattfindet.
  • Beschrifte Kanten mit Adresse, Port und Protokoll und wechsle nach dem Service zum Pod-Port.
  • Färbe Nord-Süd und Ost-West unterschiedlich und zeichne das Overlay einmal, zwischen den Nodes.
  • Hänge jede Policy an die Pods, die sie auswählt, mit der erlaubten Quelle.
  • Lass weg: das kubelet, den API-Server und zusätzliche Replicas; das Kubernetes-Architekturdiagramm deckt die Control Plane ab.
  • Typische Fehler: kube-proxy im Paketpfad (er schreibt Regeln, der Kernel leitet weiter), kein DNS und eine Policy auf einem Plugin, das sie ignoriert.

In Archboard nachbauen

  1. Melde dich mit Google oder GitHub an und erstelle ein Diagramm. Das kostenlose Tool Kubernetes YAML zu Diagramm macht aus vorhandenen Manifests einen ersten Entwurf.
  2. Füge zwei Rahmen-Nodes aus dem Pack Basis für worker-1 und worker-2 hinzu und beschrifte sie mit ihren Pod-Bereichen.
  3. Füge aus dem Pack Kubernetes vier Pod-Nodes mit ihren IPs hinzu: web und coredns in worker-1, zwei api-Pods in worker-2.
  4. Füge einen Service (ClusterIP, Port 80 auf 8080) zwischen den Frames hinzu, mit beschrifteten Kanten von web und zu beiden api-Pods.
  5. Füge eine NetworkPolicy hinzu, die app=api auswählt, mit gepunkteten Kanten zu den api-Pods.
  6. Füge einen Internet-Node aus dem Pack Netzwerk und ein Gateway mit einem HTTPS-443-Listener hinzu und verkette sie mit dem web-Pod.
  7. Zeichne eine gestrichelte DNS-Kante von web zu coredns und eine dicke, beidseitige VXLAN-Kante zwischen den Frames.
  8. Füge einen Markdown-Block aus dem Pack Basis mit den Standardwerten und kurze Text-Notizen hinzu.

Die Kubernetes-Use-Case-Seite listet weitere Objekte. Das Beispiel nutzt 11 Diagramm-Nodes und bleibt damit im Free-Plan.

FAQ

Wie kommunizieren Pods in Kubernetes über Nodes hinweg? Über das CNI-Plugin: Ein Overlay verpackt Pod-Pakete zwischen Node-IPs, oder natives Routing transportiert Pod-Adressen direkt. In beiden Fällen sehen sich Pods gegenseitig mit ihren echten IPs.

Was ist der Unterschied zwischen einer Pod-IP und einer ClusterIP? Eine Pod-IP gehört zu einem Pod und ändert sich, wenn der Pod ersetzt wird. Eine ClusterIP ist die stabile virtuelle IP eines Service, die kube-proxy oder ein eBPF-Ersatz auf eine aktuelle Pod-IP umschreibt.

Welchen kube-proxy-Modus sollte ich verwenden? In Kubernetes 1.37 ist iptables der Standard, nftables ist seit 1.33 GA und wird zum Standard, und IPVS ist deprecated. Mit Kernel 5.13 oder neuer ist nftables die bessere langfristige Wahl.

Funktionieren NetworkPolicies mit jedem CNI-Plugin? Nein. Die API akzeptiert sie überall, aber nur Plugins, die NetworkPolicy implementieren, setzen sie durch: Calico, Cilium und das AWS VPC CNI mit aktivierter Network Policy tun es; Flannel allein nicht.

Sollte ich Ingress oder die Gateway API verwenden? Die Gateway API für Neues: Kubernetes empfiehlt sie, und Ingress ist eingefroren. Bestehende Ingress-Ressourcen laufen weiter, aber plane den Umstieg weg von Ingress NGINX, das keine Sicherheitsfixes mehr bekommt.

Kostenlos starten — ein Seat, keine Kreditkarte.

Ähnliche Beiträge

← Zurück zum Blog

In einer Minute ein Canvas öffnen

Melden Sie sich mit Google oder GitHub an. Kostenlos für einen Sitzplatz. Upgraden Sie, wenn das Team dazukommt.