In DoiT International lavoriamo con clienti di ogni dimensione e, di tanto in tanto, ci capita di individuare problematiche ricorrenti, soprattutto tra i clienti di maggiori dimensioni. Vogliamo condividere un problema emerso di recente durante l'upgrade di GKE (il Kubernetes gestito di Google), nel caso in cui altri stiano pianificando i propri upgrade o si trovino ad affrontare difficoltà analoghe.

Sintomi
È bene precisare che non tutti i clienti riscontrano questo problema, ma i sintomi che abbiamo osservato sono i seguenti:
- dopo l'upgrade, la CLI kubectl non riesce a interagire con il cluster (l'API-Server non risponde)
- il processo di upgrade sembra essere "in stallo" e non si completa nemmeno dopo oltre 20 minuti
- nella console o nei log compare un messaggio di errore simile a questo: "All cluster resources were brought up, but: component \"kube-apiserver\" from endpoint \"gke-XXXXXXXX-XXXXXXX\" is unhealthy."
Diagnosi del rischio
Sebbene il problema non si presenti per tutti, gli elementi comuni che abbiamo riscontrato sono:
- versione del cluster GKE inferiore a 1.16
- cluster zonale (master a singola zona per il control plane)
- workloads "chatty" che dialogano in modo continuo con l'API-Server, come Istio, Flux o ArgoCD
- upgrade tra versioni come 1.12 -> 1.13, 1.13 -> 1.14, 1.14 -> 1.15, 1.15 -> 1.16 (di norma non si verifica con i patch update)
Chi potrebbe esserne colpito?
Vogliamo ribadire che, finora, il fenomeno si è manifestato solo presso pochi clienti e la maggior parte rientra in quel profilo: cluster zonali e workloads pesanti che sollecitano l'API-Server al punto da far impiegare troppo tempo al superamento degli health check durante gli upgrade, lasciandolo così in uno stato "in stallo". Ci auguriamo che queste informazioni siano utili sia per pianificare i prossimi upgrade di versione sia per risolvere problemi già in corso.
Soluzioni
Aprire un caso al supporto Google per aumentare il timeout degli health check
Se sta già riscontrando il problema ma i suoi worker node continuano a servire il traffico (le manca solo l'accesso kubectl al control plane), può aprire una richiesta presso Google Support o presso il suo partner di supporto tecnico (ci auguriamo sia DoiT International) per portare il timeout degli health check a 3 minuti. In questo modo l'API-Server avrà più tempo per riprendersi, evitando un ciclo di health check falliti.
Ridurre la dimensione del node pool e il carico sull'API-Server
Se può tollerare un potenziale downtime dei worker node, per alleggerire la pressione sull'API-Server può disabilitare i workloads "chatty" e ridurli di scala per un certo periodo, oppure semplicemente portare il node pool a 0, lasciare che l'upgrade si completi e poi riportarlo alla dimensione originale.
Altre possibili cause
Alcuni dei nostri engineer si sono imbattuti in scenari in cui il control plane risultava inaccessibile a causa di una race condition legata alla tabella netfilter/conntrack di Linux. Il problema è stato risolto, ma le versioni meno recenti ne erano soggette.
Soluzione a lungo termine
Gli engineer di Google sono a conoscenza del problema e una correzione è prevista entro il prossimo mese per la versione 1.16 o successive (upgrade manuale). Alla data di pubblicazione di questo articolo non è disponibile alcun link pubblico all'issue tracker.
Aggiornare il cluster da zonale a regionale
Purtroppo non esiste un "pulsante magico" per portare un cluster da zonale a regionale, ma uno dei nostri cloud architect ha scritto un articolo che illustra un possibile approccio alla migrazione utilizzando un noto strumento open-source, Velero.