101 Series - Preserve Client IP und External Traffic Policies
)
Overview
Bei der Einstellung externalTrafficPolicy
geht es, wie aus dem Namen schon hervorgeht, um eingehenden Traffic von einem externen Host.
Mit ihr wird geregelt, ob eine Netzwerkanfrage auf alle Pods einer Anwendung im gesamten Cluster geleitet werden darf, oder auf der Node und deren Pods bleiben muss, wo sie ankommt.
Beide Optionen haben verschiedene Vor- und Nachteile sowie unterschiedliche Anwendungsfälle.
ExternalTrafficPolicy: cluster
Dies ist der Standardwert der externalTrafficPolicy
. Eingehender Netzwerkverkehr wird an alle Pods einer Anwendung geleitet, auch wenn diese in einer anderen Node liegen – also an das gesamte Cluster.
Selbst wenn sich auf der eigenen Node noch Pods befinden, wird der Traffic gleichmäßig auf alle Nodes verteilt, sodass es zu teils unnötigen "Network Hops" kommt.
Das wahrscheinlich schwerwiegendere Problem ist das Maskieren der Netzwerkpakete. Bei dem zusätzlichen Sprung werden die Pakete an andere Nodes geschickt, wodurch die erste Node zum neuen Absender wird; wir verlieren die originale IP des externen Clients. Diesen Vorgang nennt man SNAT – Source Network Address Translation.
Der erste Gedanke ist jetzt vielleicht, einfach das SNAT wegzulassen und den NodePort Proxy die Source-Adresse auf die Client IP setzen zu lassen. Der Pod würde dann die originale IP erhalten und könnte mit ihr arbeiten.
Jetzt schickt der Client seine Pakete an die externe IP der Node mit Port (eIP/NP) und erwartet bei der Antwort diese externe IP als Quelle. Der Pod überspringt aber den NodePort Proxy und sendet direkt an den externen Client, welcher dann die lokale IP des Pods als Sender bekommt. Das führt zu einem Verbindungsfehler.
ExternalTrafficPolicy: local
Bei der externalTrafficPolicy: local
bleibt alles in der Node an der es ankommt. Somit werden unnötige Netzwerksprünge vermieden und die Pods erhalten immer die originale IP der anfragenden Clients, da wir nicht mehr über einen Proxy SNATen müssen. Hiermit erreichen wir also ein häufig gewünschtes Ziel, dass die Pods und Applikationen die Original IP des Clients bekommen (Preserve Client IP).
Beim Versuch, diese Policy bei einem Service zu setzen, wirst du diese Fehlermeldung bekommen:
$ kubectl apply -f my-service.yml
The Service "my-service" is invalid: spec.externalTrafficPolicy: Invalid value:
"Local": ExternalTrafficPolicy can only be set on NodePort and LoadBalancer service
Wir benötigen zwingend einen Load Balancer – eine Komponente die eingehenden Traffic gleichmäßig auf alle verfügbaren Nodes verteilt, die Pods mit dem richtigen Service am laufen haben. Ein Load Balancer sorgt auch dafür, dass der Traffic nur auf Nodes mit laufenden Pods der jeweiligen Applikation geleitet wird.
Da der Load Balancer die Anzahl der laufenden Pods in einer Node nicht kennt und den Netzwerkverkehr immer gleichmäßig an alle Nodes verteilt, kann es zu unausgeglichenen Workloads kommen.
Um eine ungleichmäßige Verteilung des Datenverkehrs zu vermeiden, können wir die Anti-Affinity
von Pods (gegenüber dem Hostname-Label der Node) verwenden, so dass die Pods auf so viele Nodes wie möglich verteilt werden:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values:
- my-app
topologyKey: kubernetes.io/hostname
Wenn die Anwendung skaliert und auf mehr Nodes verteilt wird, entsteht eine geringerere Ungleichverteilung des Datenverkehrs.
Fazit
In der Regel ist es sinnvoll, bei einem Dienst, der externen Traffic über einen Load Balancer empfängt, externalTrafficPolicy: local
zu verwenden. Durch die Nutzung von Pod-Anti-Affinity
kann die Ungleichverteilung der Anfragen reduziert werden.
In bestimmten Fällen kann externalTrafficPolicy: cluster
eine Alternative sein, sie führt jedoch zum Verlust der Client-IP und zu zusätzlichen Network Hops.
Habt ihr noch Fragen oder Feedback zu External Traffic Policies? Weitere Details dazu lernt ihr zum Beispiel in unserer Kubernetes Einführungsschulung! Zögert nicht, uns zu kontaktieren – schreibt uns eine kurze Nachricht oder nutzt den Chat auf unserer Website. Wir freuen uns auf eure Rückmeldungen!