Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.

Nota del traduttore.: l'adattamento di Kubernetes in GitLab è considerato uno dei due principali fattori alla base della crescita dell'azienda. Tuttavia, fino a poco tempo fa, l'infrastruttura del servizio online GitLab.com era costruita su macchine virtuali, e solo circa un anno fa è iniziata la sua migrazione in K8s, che non è ancora completata. Siamo lieti di presentare la traduzione di un recente articolo di un ingegnere SRE di GitLab su come sta avvenendo questo processo e quali conclusioni traggono gli ingegneri coinvolti nel progetto.

Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.

Da circa un anno, il nostro dipartimento infrastrutture è impegnato nella migrazione di tutti i servizi operanti su GitLab.com verso Kubernetes. Durante questo periodo, ci siamo trovati ad affrontare problemi non solo legati al trasferimento dei servizi in Kubernetes, ma anche alla gestione del deployment ibrido durante la transizione. Questa articolo parlerà di preziose lezioni che abbiamo appreso.

Sin dalla sua nascita, i server di GitLab.com hanno funzionato nel cloud su macchine virtuali. Queste macchine virtuali sono gestite da Chef, mentre la loro installazione avviene tramite il nostro pacchetto ufficiale per Linux. Strategia di deploy nel caso sia necessario aggiornare l'applicazione, consiste in un semplice aggiornamento del parco server coordinato in modo sequenziale tramite una CI pipeline. Questo metodo — sebbene lento e un po' noioso — garantisce che GitLab.com utilizzi gli stessi metodi di installazione e configurazione che usano gli utenti delle (installazioni self-managed) di GitLab, impiegando per questo i nostri pacchetti Linux.

Adottiamo questo metodo perché è assolutamente fondamentale sperimentare tutte le gioie e le difficoltà che affrontano i membri comuni della comunità durante l'installazione e la configurazione delle proprie copie di GitLab. Questo approccio ha funzionato bene per un certo periodo, ma quando il numero di progetti su GitLab ha superato i 10 milioni, abbiamo capito che non soddisfaceva più le nostre esigenze di scalabilità e distribuzione.

I primi passi verso Kubernetes e GitLab cloud-native

Nel 2017, è stato avviato il progetto GitLab Charts per preparare GitLab per il deployment nel cloud e per consentire agli utenti di installare GitLab in cluster Kubernetes. Allora sapevamo che il trasferimento di GitLab in Kubernetes avrebbe aumentato le capacità di scalabilità della piattaforma SaaS, semplificato i deployment e migliorato l'efficienza dell'uso delle risorse computazionali. Tuttavia, molte funzionalità della nostra applicazione dipendevano da partizioni NFS montate, il che rallentava la transizione dalle macchine virtuali.

La spinta verso il cloud native e Kubernetes ha permesso ai nostri ingegneri di pianificare una transizione graduale, durante la quale abbiamo abbandonato alcune dipendenze dell'applicazione dai storage di rete, continuando nel frattempo a sviluppare nuove funzionalità. Da quando abbiamo iniziato a pianificare la migrazione nell'estate del 2019, molte di queste limitazioni sono state eliminate, e il processo di trasferimento di GitLab.com su Kubernetes sta ora procedendo a ritmo intenso!

Caratteristiche operative di GitLab.com in Kubernetes

Per GitLab.com utilizziamo un cluster regionale GKE centralizzato che gestisce tutto il traffico dell'applicazione. Per ridurre la complessità della migrazione, già di per sé intricata, ci concentriamo su servizi indipendenti dallo storage locale o da NFS. GitLab.com impiega principalmente un codice monolitico su Rails e indirizziamo il traffico in base alle caratteristiche del carico di lavoro verso vari endpoint, isolati in propri pool di nodi.

Per quanto riguarda il frontend, questi tipi si dividono in richieste web, API, Git SSH/HTTPS e Registry. Sul fronte del backend, suddividiamo i job nella coda in base a diverse caratteristiche in base a limiti di risorse predefiniti, che ci consentono di impostare obiettivi di livello di servizio (Service-Level Objectives, SLO) per i vari carichi.

Tutti questi servizi di GitLab.com sono configurati utilizzando la chart Helm di GitLab non modificata. La configurazione avviene nei sub-chart, che possono essere inclusi selettivamente man mano che trasferiamo gradualmente i servizi nel cluster. Anche se è stato deciso di non includere nella migrazione alcuni dei nostri servizi stateful, come Redis, Postgres, GitLab Pages e Gitaly, l'uso di Kubernetes consente di ridurre radicalmente il numero di VM gestite attualmente da Chef.

Trasparenza e gestione della configurazione di Kubernetes

Tutte le impostazioni sono gestite dallo stesso GitLab. Per questo utilizziamo tre progetti di configurazione basati su Terraform e Helm. Cerchiamo di utilizzare GitLab stesso per avviare GitLab ovunque possibile, ma per le attività operative abbiamo un'installazione separata di GitLab. Questo è necessario per non dipendere dalla disponibilità di GitLab.com durante le distribuzioni e gli aggiornamenti di GitLab.com.

Sebbene le nostre pipeline per il cluster Kubernetes funzionino su un'installazione separata di GitLab, ci sono specchi dei repository di codice accessibili pubblicamente ai seguenti indirizzi:

  • k8s-workloads/gitlab-com — wrapper di configurazione di GitLab.com per la chart Helm di GitLab;
  • k8s-workloads/gitlab-helmfiles — contiene configurazioni per i servizi che non sono direttamente associati all'applicazione GitLab. Queste includono configurazioni per la registrazione e il monitoraggio del cluster, oltre a strumenti integrati come PlantUML;
  • Gitlab-com-infrastructure — configurazione Terraform per Kubernetes e l'infrastruttura VM legacy. Qui si impostano tutte le risorse necessarie per avviare il cluster, inclusi il cluster stesso, i pool di nodi, gli account di servizio e il riservamento degli indirizzi IP.

Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.
Le modifiche apportate vengono mostrate pubblicamente un riepilogo con un link al diff dettagliato che gli SRE analizzano prima di apportare modifiche al cluster.

Per SRE, il link porta a un diff dettagliato nell'installazione di GitLab, utilizzata per l'operatività e a cui si accede in modo limitato. Questo consente ai dipendenti e alla comunità senza accesso al progetto operativo (aperto solo per SRE) di visualizzare le modifiche proposte nella configurazione. Combinando un'istanza pubblica di GitLab per il codice con un'istanza privata per i pipeline CI, manteniamo un flusso di lavoro unico, garantendo al contempo l'indipendenza da GitLab.com durante gli aggiornamenti della configurazione.

Cosa abbiamo appreso durante la migrazione

Durante il processo di migrazione abbiamo acquisito esperienze che applichiamo a nuove migrazioni e deployment in Kubernetes.

1. Aumento dei costi dovuto al traffico tra le zone di disponibilità

Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.
Statistiche giornaliere di egress (byte al giorno) per il parco di repository Git su GitLab.com

Google suddivide la propria rete in regioni. Queste vengono ulteriormente suddivise in zone di disponibilità (AZ). L'hosting Git comporta grandi volumi di dati, rendendo fondamentale monitorare l'egress di rete. In caso di traffico interno, l'egress è gratuito solo se rimane all'interno di una singola zona di disponibilità. Al momento della scrittura di questo articolo, trasferiamo circa 100 TB di dati in un giorno lavorativo tipico (e questo è solo per i repository Git). I servizi che nella nostra vecchia topologia basata su VM si trovavano sulle stesse macchine virtuali ora operano in diversi pod di Kubernetes. Ciò significa che parte del traffico che prima era locale alla VM potrebbe potenzialmente andare oltre le zone di disponibilità.

I cluster regionali GKE consentono di coprire più zone di disponibilità per la ridondanza. Stiamo considerando la possibilità di suddividere il cluster regionale GKE in cluster a zona singola per i servizi che generano grandi volumi di traffico. Questo permetterà di ridurre i costi dell'egress mantenendo la ridondanza a livello di cluster.

2. Limiti, richieste di risorse e scalabilità

Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.
Il numero di repliche che gestiscono il traffico di produzione su registry.gitlab.com. Il traffico raggiunge il suo picco intorno alle 15:00 UTC.

La nostra storia di migrazione è iniziata nell'agosto 2019, quando abbiamo trasferito il primo servizio — il registro dei container GitLab (GitLab Container Registry) — in Kubernetes. Questo servizio critico ad alto traffico si è rivelato adatto per la prima migrazione, in quanto si tratta di un'applicazione stateless con poche dipendenze esterne. Il primo problema che abbiamo affrontato è stato l'elevato numero di pod espulsi a causa della carenza di memoria sui nodi. Questo ci ha costretto a modificare i valori di request e limit.

È emerso che, nei casi di applicazioni con un consumo di memoria crescente nel tempo, valori bassi per i request (riservando memoria per ogni pod) combinati con un 'generoso' limite rigido sull'utilizzo portavano a saturazione (saturazione) dei nodi e a un alto livello di espulsione. Per affrontare questo problema, è stato deciso di aumentare i request e ridurre i limit.. Questo ha alleviato la pressione sui nodi e ha garantito un ciclo di vita dei pod che non esercitava una pressione eccessiva sul nodo. Ora iniziamo le migrazioni con valori di request e limit generosi (e quasi identici), correggendoli secondo necessità.

3. Metriche e log

Le nostre conclusioni sulla migrazione di GitLab.com su Kubernetes nell'anno passato.
Il reparto infrastrutture si concentra sui ritardi, sulla percentuale di errori e sulla saturazione rispetto agli obiettivi stabiliti per il livello di servizio (SLO), legati a disponibilità complessiva del nostro sistema..

Nel corso dell'ultimo anno, uno degli eventi chiave nel reparto infrastrutture è stato il miglioramento nel monitoraggio e nella gestione degli SLO. Gli SLO ci hanno permesso di stabilire obiettivi per singoli servizi, che abbiamo monitorato attentamente durante la migrazione. Tuttavia, anche con una visibilità migliorata, non è sempre possibile rilevare subito i problemi utilizzando metriche e avvisi. Ad esempio, concentrandoci sui ritardi e sulla percentuale di errori, non copriamo completamente tutti gli scenari d'uso del servizio in fase di migrazione.

Questo problema è stato riscontrato quasi subito dopo il trasferimento di parte dei carichi di lavoro nel cluster. Si è manifestato in particolare quando è stato necessario testare le funzionalità, il cui numero di richieste è ridotto, ma con dipendenze di configurazione molto specifiche. Una delle lezioni chiave apprese dalla migrazione è stata la necessità di tenere conto nel monitoraggio non solo delle metriche, ma anche dei log e del "long tail". (si tratta di tale distribuzione nel grafico — nota del traduttore) di errori. Ora per ogni migrazione includiamo un elenco dettagliato delle richieste ai log (log queries) e pianifichiamo procedure di rollback chiare, che in caso di problemi possano essere trasferite da un turno all'altro.

La gestione parallela delle stesse richieste sull'infrastruttura VM vecchia e su quella nuova basata su Kubernetes rappresentava una sfida unica. A differenza della migrazione tipo lift-and-shift (trasferimento rapido delle applicazioni "così come sono" nella nuova infrastruttura; si può approfondire, ad esempio, qui — nota di traduzione), il funzionamento parallelo su VM "vecchie" e Kubernetes richiede che gli strumenti di monitoraggio siano compatibili con entrambi gli ambienti e siano in grado di unire le metriche in un'unica vista. È fondamentale utilizzare gli stessi dashboard e le stesse query sui log per garantire una visibilità coerente durante il periodo di transizione.

4. Reindirizzamento del traffico al nuovo cluster

Per GitLab.com, parte dei server è riservata alla fase canary. Il parco canary gestisce i nostri progetti interni e può essere attivato dagli utenti. Tuttavia, è principalmente destinato a testare le modifiche apportate all'infrastruttura e all'applicazione. Il primo servizio migrato ha iniziato ad accettare un volume limitato di traffico interno e continuiamo a utilizzare questo metodo per garantire il rispetto degli SLO prima di indirizzare tutto il traffico verso il cluster.

In caso di migrazione, questo significa che inizialmente le richieste in Kubernetes vengono dirette ai progetti interni e poi gradualmente switchiamo il resto del traffico sul cluster modificando il peso per il backend tramite HAProxy. Durante il passaggio da VM a Kubernetes, è diventato evidente che avere un semplice modo per reindirizzare il traffico tra la vecchia e la nuova infrastruttura è molto vantaggioso e, di conseguenza, mantenere la vecchia infrastruttura pronta per il rollback nei primi giorni dopo la migrazione.

5. Capacità di riserva dei pod e il loro utilizzo

Quasi subito è emerso il seguente problema: i pod per il servizio Registry si avviavano rapidamente, ma l'avvio dei pod per Sidekiq richiedeva fino a due minuti.L'avvio prolungato dei pod per Sidekiq è diventato un problema quando abbiamo iniziato a migrare i carichi di lavoro dei worker in Kubernetes, i quali devono elaborare rapidamente le job e scalare rapidamente.

In questo caso, la lezione è che, sebbene l'Horizontal Pod Autoscaler (HPA) in Kubernetes gestisca bene l'aumento del traffico, è fondamentale considerare le caratteristiche dei carichi di lavoro e riservare capacità aggiuntive ai pod (soprattutto in condizioni di domanda irregolare). Nel nostro caso, abbiamo osservato un'improvvisa impennata di job, che ha comportato un rapido scaling, saturando le risorse CPU prima che potessimo aumentare il pool di nodi.

C'è sempre la tentazione di estrarre il massimo dal cluster, tuttavia, affrontando inizialmente problemi di prestazioni, ora partiamo con un budget pod generoso e lo riduciamo successivamente, prestando particolare attenzione agli SLO. L'avvio dei pod per il servizio Sidekiq è notevolmente accelerato e ora richiede in media circa 40 secondi. Dalla riduzione dei tempi di avvio dei pod sia GitLab.com che i nostri utenti delle installazioni self-managed, che utilizzano il chart Helm ufficiale di GitLab, ne hanno beneficiato.

Conclusione

Dopo la migrazione di ciascun servizio, abbiamo apprezzato i vantaggi dell'utilizzo di Kubernetes in produzione: un deploy più veloce e sicuro delle applicazioni, scalabilità e una distribuzione delle risorse più efficiente. Inoltre, i benefici della migrazione superano il servizio di GitLab.com. Ogni miglioramento dell'Helm chart ufficiale porta vantaggi anche agli utenti.

Spero che vi sia piaciuta la storia delle nostre avventure con la migrazione su Kubernetes. Continuiamo a trasferire sempre più servizi nel cluster. Ulteriori informazioni possono essere trovate nelle seguenti pubblicazioni:

P.S. dal traduttore

Leggete anche nel nostro blog:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster