De upgrade
Productie ging in twaalf minuten van 1.33 naar 1.34, met vooraf een geschreven plan, controlescripts en een nacontrole. Wat er toch misging, was leerzamer dan wat goed ging:
- DNS op Gardener luistert op poort 8053. De service
kube-dnsbiedt poort 53 aan, maar de pods luisteren op 8053. Een NetworkPolicy die alleen 53 toestaat, breekt DNS. Een lokaal kind-cluster vangt dit niet, want daar is het wél 53. - Twee PDB's op dezelfde pods blokkeren elke eviction. De Helm-chart had zijn eigen PodDisruptionBudget, en er stond nog een handmatige naast. De eviction-API weigert dan alles. Na het verwijderen bleef de status van de overgebleven PDB hangen, tot een annotatie op een pod de controller liet herberekenen.
- Cilium heeft tijd nodig. Een pod op een verse node krijgt ~40 seconden
Operation not permittedtot de policy actief is.
NetworkPolicies op basis van metingen
In plaats van policies te schrijven op basis van wat je denkt dat er praat, heb ik eerst gemeten. Hubble per Cilium-agent legde een uur lang alle verbindingen vast in acceptatie en drie kwartier in productie. Samen met de routes van de ingress gaf dat een volledige verkeersmatrix.
De policies zijn daarna gesimuleerd tegen die meting: nul gemeten verbindingen geblokkeerd. Eerst een periode op acceptatie zonder drops, daarna productie. Valkuilen: selectors op app.kubernetes.io/name in plaats van app, en langlopende verbindingen die in een SYN-meting niet voorkomen.
Rightsizing
Een dashboard "Clustercapaciteit en rightsizing" zet per workload de requests naast het werkelijke gebruik over dagen. Door Loki, istiod en caches op maat te zetten, ging de gereserveerde capaciteit van ~45 naar ~27 GiB, en kon de autoscaler een node terugschalen.
Kleine fixes die grote storingen voorkomen
- RabbitMQ-cookie na een kubelet-herstart.
fsGroupmet de standaardfsGroupChangePolicy: Alwayszette groepsrechten op het Erlang-cookie, en RabbitMQ weigert dan te starten.OnRootMismatchlost het blijvend op. - RabbitMQ en het geheugen van de node. RabbitMQ rekende zijn watermark uit op het geheugen van de hele node, niet op zijn eigen limiet. Bij een limiet van 2 GiB betekent dat een OOMKill in plaats van flow control. Een expliciete
total_memory_available_override_valuerepareert dat. - Een Helm-release in
pending-upgradeblokkeert elke volgende upgrade, terwijl Flux zichtbaar niets doet. Diagnose: vergelijk de laatst geprobeerde config-digest met de geschiedenis; oplossing: eenhelm rollbacknaar de laatste goede versie.
Werkwijze
Alles loopt via Git: wijzigingen op een ontwikkelbranch, een merge request, en Flux rolt main uit. Productiewijzigingen staan klaar als merge request met een beschrijving van impact en terugdraaien, en worden door een tweede persoon gemerged.