Le nostre conclusioni dopo un anno di migrazione di GitLab.com su Kubernetes

Nota di traduzione.: l'adattamento di Kubernetes in GitLab è considerato uno dei due principali fattori che contribuiscono alla 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 a K8s, che non è ancora terminata. Siamo lieti di presentare la traduzione di un recente articolo di un ingegnere SRE di GitLab su come sta avvenendo questo e quali conclusioni traggono gli ingegneri coinvolti nel progetto.

Le nostre conclusioni dopo un anno di migrazione di GitLab.com su Kubernetes

Da circa un anno il nostro dipartimento infrastrutturale è impegnato nella migrazione di tutti i servizi che operano su GitLab.com a Kubernetes. Nel frattempo, abbiamo affrontato problemi legati non solo al trasferimento dei servizi in Kubernetes, ma anche alla gestione di un deployment ibrido durante la transizione. Di lezioni preziose che abbiamo appreso si parlerà in questo articolo.

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

Utilizziamo questo metodo poiché è estremamente importante vivere tutte le gioie e i dolori che i membri della comunità affrontano quando installano e configurano le proprie copie di GitLab. Questo approccio ha funzionato bene per un certo periodo, tuttavia 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 creato il progetto GitLab Charts per preparare GitLab al deployment nel cloud e per dare agli utenti la possibilità 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 nell'uso delle risorse computazionali. Allo stesso tempo, molte funzionalità della nostra applicazione dipendevano da partizioni NFS montate, il che rallentava il passaggio dalle macchine virtuali.

L'aspirazione al cloud native e Kubernetes ha permesso ai nostri ingegneri di pianificare una transizione graduale, durante la quale abbiamo ridotto alcune dipendenze dell'applicazione da archiviazioni di rete, continuando 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 migrazione di GitLab.com su Kubernetes è ora a tutto ritmo!

Caratteristiche del funzionamento di GitLab.com in Kubernetes

Per GitLab.com utilizziamo un unico cluster regionale GKE che gestisce tutto il traffico dell'applicazione. Per minimizzare la complessità (già piuttosto intricato) della migrazione, ci concentriamo su servizi che non dipendono da archiviazioni locali o NFS. GitLab.com utilizza principalmente una base di codice monolitica su Rails, e indirizziamo il traffico in base alle caratteristiche del carico di lavoro su vari endpoint, isolati in propri pool di nodi.

Nel caso del frontend, questi tipi si dividono in richieste web, API, Git SSH/HTTPS e Registry. Nel caso del backend, suddividiamo i job nella coda in base a diverse caratteristiche in funzione di limiti di risorse predefiniti, che ci consentono di stabilire obiettivi di livello di servizio (Service-Level Objectives, SLOs) per diversi carichi.

Tutti questi servizi di GitLab.com sono configurati utilizzando un Helm chart di GitLab non modificato. La configurazione avviene tramite subchart, che possono essere selettivamente attivati man mano che trasferiamo gradualmente i servizi nel cluster. Anche se è stata presa la decisione di non includere nella migrazione alcuni dei nostri servizi stateful, come Redis, Postgres, GitLab Pages e Gitaly, l'uso di Kubernetes consente di ridurre drasticamente il numero di VM gestite da Chef attualmente.

Trasparenza e gestione della configurazione di Kubernetes

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

Sebbene i nostri pipeline per il cluster Kubernetes funzionino su un'installazione separata di GitLab, i repository di codice hanno specchi, accessibili pubblicamente ai seguenti indirizzi:

  • k8s-workloads/gitlab-com — integrazione di configurazione di GitLab.com per il chart Helm di GitLab;
  • k8s-workloads/gitlab-helmfiles — contiene configurazioni per i servizi che non sono direttamente legati all'applicazione GitLab. Questi includono configurazioni per la registrazione e il monitoraggio del cluster, nonché per strumenti integrati come PlantUML;
  • Gitlab-com-infrastructure — configurazione Terraform per Kubernetes e vecchia infrastruttura VM. Qui vengono configurate tutte le risorse necessarie per avviare il cluster, incluso il cluster stesso, i pool di nodi, gli account di servizio, la prenotazione degli indirizzi IP.

Le nostre conclusioni dopo un anno di migrazione di GitLab.com su Kubernetes
Quando vengono apportate modifiche, viene mostrato un pubblico riepilogo con un collegamento alla differenza dettagliata, che SRE analizza prima di apportare modifiche al cluster.

Per SRE il collegamento porta alla differenza dettagliata nell'installazione di GitLab utilizzata per le operazioni, a cui l'accesso è 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 chiusa per i pipeline CI, manteniamo un flusso di lavoro uniforme, garantendo nel contempo l'indipendenza da GitLab.com durante gli aggiornamenti della configurazione.

Cosa abbiamo scoperto durante la migrazione

Durante il trasloco sono state accumulate esperienze che applichiamo a nuove migrazioni e distribuzioni in Kubernetes.

1. Aumento dei costi a causa del traffico tra le zone di disponibilità

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

Google suddivide la propria rete in regioni. Queste ultime, a loro volta, si articolano in zone di disponibilità (AZ). L'hosting Git è associato a grandi volumi di dati, quindi è importante monitorare l'egress di rete. Per il traffico interno, l'egress è gratuito solo se rimane all'interno di una singola zona di disponibilità. Al momento della stesura di questo articolo, stiamo trasferendo circa 100 TB di dati in un giorno lavorativo normale (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 pod Kubernetes diversi. Ciò significa che parte del traffico, che in precedenza era locale per la VM, potrebbe potenzialmente superare i limiti delle zone di disponibilità.

I cluster regionali GKE consentono di coprire più zone di disponibilità per la riserva. Stiamo considerando di dividere il cluster regionale GKE in cluster mono-zona per i servizi che generano grandi volumi di traffico. Questo ridurrà i costi di egress mantenendo la riserva a livello di cluster.

2. Limiti, richieste di risorse e scalabilità

Le nostre conclusioni dopo un anno di migrazione di GitLab.com su Kubernetes
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 spostato 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, poiché è un'applicazione stateless con poche dipendenze esterne. Il primo problema che abbiamo affrontato è stato il grande numero di pod espulsi a causa della mancanza di memoria sui nodi. Per questo motivo, abbiamo dovuto modificare le richieste e i limiti.

È emerso che, nel caso di un'applicazione il cui consumo di memoria cresce nel tempo, valori bassi per le richieste (che riservano memoria per ogni pod) insieme a un 'generoso' limite rigido sull'uso portavano a saturazione (saturazione) dei nodi e a un alto livello di espulsioni. Per affrontare questo problema, è stato deciso di aumentare le richieste e ridurre i limiti.. Questo ha ridotto la pressione sui nodi e ha fornito un ciclo di vita dei pod che non esercitava una pressione eccessiva sul nodo. Ora iniziamo le migrazioni con valori di richiesta e limiti generosi (e quasi identici), correggendoli secondo necessità.

3. Metriche e log

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

Nell'ultimo anno, uno degli eventi chiave nel dipartimento infrastrutturale è stato il miglioramento nel monitoraggio e nella gestione degli SLO. Gli SLO ci hanno permesso di stabilire obiettivi per i singoli servizi, che abbiamo monitorato attentamente durante la migrazione. Ma anche con una tale osservabilità migliorata, non sempre è possibile vedere immediatamente i problemi utilizzando metriche e allerte. Ad esempio, concentrandoci sui ritardi e sulla percentuale di errori, non copriamo completamente tutti gli scenari di utilizzo del servizio in fase di migrazione.

Questo problema è stato individuato quasi subito dopo aver trasferito parte dei carichi di lavoro nel cluster. Si è fatto sentire in particolare quando si è trattato di verificare funzionalità per le quali il numero di richieste è ridotto, ma che hanno dipendenze di configurazione molto specifiche. Una delle lezioni chiave emerse dalla migrazione è stata la necessità di considerare nel monitoraggio non solo le metriche, ma anche i log e il 'lungo coda' (riferendosi a tale distribuzione su un grafico — ndt.) di errori. Ora, per ogni migrazione, includiamo un elenco dettagliato di richieste ai log (log queries) e pianifichiamo procedure di rollback chiare, che in caso di problemi possono essere trasferite da un turno all'altro.

Servire in parallelo le stesse richieste sulla vecchia infrastruttura VM e su quella nuova, basata su Kubernetes, ha rappresentato una sfida unica. A differenza della migrazione lift-and-shift (trasferimento rapido delle applicazioni 'così come sono' nella nuova infrastruttura; maggiori dettagli possono essere letti, ad esempio, qui — nota del traduttore.), il lavoro parallelo su VM "vecchie" e Kubernetes richiede che gli strumenti di monitoraggio siano compatibili con entrambe le ambienti e in grado di unire le metriche in un'unica vista. È importante che utilizziamo gli stessi dashboard e le stesse query ai log per ottenere una visibilità coerente durante il periodo di transizione.

4. Reindirizzamento del traffico al nuovo cluster

Per GitLab.com, parte dei server è dedicata alla fase canary (canary). Il parco canary gestisce i nostri progetti interni e può essere attivato dagli utenti. Ma è principalmente destinato a testare le modifiche apportate all'infrastruttura e all'applicazione. Il primo servizio migrato ha iniziato ricevendo un volume limitato di traffico interno, e continuiamo a utilizzare questo metodo per assicurarci che vengano rispettati gli SLO prima di indirizzare tutto il traffico al cluster.

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

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

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

In questo caso, la lezione appresa è che, sebbene l'Horizontal Pod Autoscaler (HPA) in Kubernetes gestisca bene l'aumento del traffico, è importante tenere in considerazione le caratteristiche dei carichi di lavoro e riservare capacità ai pod (soprattutto in condizioni di domanda irregolare). Nel nostro caso, c'è stata un'improvvisa impennata di job, che ha comportato un rapido scalamento, causando l'esaurimento delle risorse CPU prima che potessimo scalare il pool dei nodi.

C'è sempre la tentazione di "estrarre" il massimo dal cluster, tuttavia, dopo aver inizialmente affrontato problemi di prestazioni, ora partiamo con un budget pod generoso e lo riduciamo successivamente, monitorando attentamente il SLO. L'avvio dei pod per il servizio Sidekiq è notevolmente accelerato e ora richiede in media circa 40 secondi. Dalla riduzione del tempo di avvio dei pod ha beneficiato sia GitLab.com che i nostri utenti delle installazioni self-managed che utilizzano l'official Helm chart di GitLab.

Conclusione

Dopo il trasferimento di ciascun servizio, abbiamo goduto dei vantaggi dell'uso di Kubernetes in produzione: distribuzione dell'applicazione più rapida e sicura, scalabilità e una distribuzione delle risorse più efficace. Inoltre, i benefici della migrazione vanno oltre il servizio GitLab.com. Ogni miglioramento dell'official Helm chart giova anche ai suoi utenti.

Spero che vi sia piaciuta la storia delle nostre avventure con la migrazione in Kubernetes. Continuiamo a trasferire nuovi servizi nel cluster. Maggiori informazioni possono essere trovate nei seguenti articoli:

P.S. dal traduttore

Leggi 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