Kubernetes Load Balancer Konfiguration – Vorsicht beim Drainen von Nodes

English version

Wir haben letztens bei einem Kubernetes Cluster in GKE einen neuen Node-Pool erstellt, um dorthin die Workloads von einem bestehenden Node-Pool zu migrieren.

Beim Drainen der alten Nodes ist irgendwann aufgefallen, dass keine Services mehr von aussen ueber unseren ingress-nginx erreichbar waren.

Beim Ueberpruefen des ingress-nginx Load Balancer Services und der nginx-ingress-controller Pods haben wir folgendes festgestellt:

  • Der Load Balancer Service wurde angepasst, so dass die Backend-Pool Config in GCP auf die Nodes im neuen Node-Pool zeigt, aber NICHT mehr auf die alten.
  • Die nginx-ingress-controller Pods liefen allerdings noch auf den alten Nodes, da das Drainen durch einige Pod Disruption Budgets laenger gedauert hat

Warum aber waren aber die Services ueber den Ingress nicht erreichbar, wenn doch eigentlich der kube-proxy transparent dafuer sorgen sollte, den Traffic an den richtigen Node zu schicken, egal wo der Eintrittspunkt ist?

Kubernetes hat ein Feature, um die originale Client-Quell-IP beizubehalten (anstatt sie durch die interne IP eines Nodes ersetzen), was fuer Webserver-Logs sehr hilfreich ist, um etwaige Angriffe zu identifizieren. service.spec.externalTrafficPolicy auf den Wert Local zu setzen, proxiet Requests nur zu Endpoints auf dem aktuellen Node und leitet sie nicht auf andere Nodes weiter, womit Requests die urspruengliche Client-Quell-IP behalten. Diese Einstellung ist fuer den ingress-nginx Controller auch standardmaessig so gesetzt.

In GCP wird nun zu dem Load Balancer automatisch ein HTTP Health-Check erstellt, der auf dem Load Balancer healthCheckNodePort auf den /healthz Endpunkt prueft. Durch die oben erwaehnte externalTrafficPolicy schlaegt dieser aber auf allen Nodes fehl, auf denen kein nginx-ingress-controller Pod laeuft.

Der Kubernetes Service Controller konfiguriert naemlich nur Nodes in den LB HealthCheck, die Ready und Schedulable sind, sobald ein Node nicht mehr Schedulable ist, wird er aus der Load Balancer Backend Config entfernt; obwohl hierdurch eigentlich Master-Server gefiltert werden sollen, hat das den Effekt, dass auch Nodes, die Cordoned sind, aber noch Pods am Laufen haben, da rausfliegen.

Wir hatten also nur noch die neuen Nodes im Load Balancer Healthcheck, die aber alle fehlschlugen, da die nginx-ingress-controller Pods noch auf den alten Nodes liefen, womit ueber den Ingress-Controller nun ueberhaupt kein Traffic mehr in den Cluster kam.

Durch das Loeschen der Pods (und dadurch neues Scheduling auf den neuen Nodes) wurde die Situation geloest.

Das zeigt aber, dass bei Wartungsarbeiten und vor allem Aenderungen, die das Netzwerk betreffen, noch einmal besonders auf etwaige Nebeneffekte geachtet werden sollte.

Schreib einen Kommentar