Che cos'è GitOps?

Nota del traduttore.: Dopo una recente pubblicazione di materiale sui metodi pull e push in GitOps, abbiamo notato un crescente interesse per questo modello in generale. Tuttavia, ci sono pochissime pubblicazioni in lingua russa su questo argomento (non ci sono affatto su Habr). Perciò, siamo felici di presentare la traduzione di un altro articolo — anche se quasi un anno fa! — dell'azienda Weaveworks, il cui fondatore ha coniato il termine «GitOps». Nel testo viene spiegata l'essenza dell'approccio e le sue principali differenze rispetto a quelli già esistenti.

Un anno fa abbiamo pubblicato un'introduzione a GitOps. Allora abbiamo raccontato come il team di Weaveworks ha lanciato un SaaS interamente basato su Kubernetes e ha sviluppato un insieme di best practices normative per l'implementazione, gestione e monitoraggio in un ambiente cloud native.

L'articolo è stato popolare. Altri hanno iniziato a parlare di GitOps e a pubblicare nuovi strumenti per git push, sviluppo, segreti, funzioni, integrazione continua ecc. Sul nostro sito è apparso un gran numero di pubblicazioni e casi d'uso di GitOps. Ma alcune persone hanno ancora domande. Qual è la differenza tra questo modello e il tradizionale infrastructure as code e la consegna continua (continuous delivery)? È obbligatorio utilizzare Kubernetes?

Presto ci siamo resi conto della necessità di una nuova descrizione che offrisse:

  1. Un gran numero di esempi e storie;
  2. Una definizione chiara di GitOps;
  3. Un confronto con la continuous delivery tradizionale.

In questo articolo abbiamo cercato di coprire tutti questi temi. Troverete un'introduzione aggiornata su GitOps e una prospettiva da parte degli sviluppatori e del CI/CD. Ci concentriamo principalmente su Kubernetes, anche se il modello può essere generalizzato.

Presentiamo: GitOps

Immagina Alice. Gestisce l'azienda Family Insurance, che offre polizze per assicurazioni sanitarie, auto, immobili e viaggi a persone troppo occupate per districarsi tra le complessità dei contratti da sole. La sua attività è iniziata come un progetto secondario, mentre Alice lavorava in banca come data scientist. Un giorno si è resa conto di poter utilizzare algoritmi computazionali avanzati per un'analisi dei dati più efficace e per la creazione di pacchetti assicurativi. Gli investitori hanno finanziato il progetto e ora la sua azienda genera oltre 20 milioni di dollari all'anno ed è in rapida crescita. Attualmente, impiega 180 persone in vari ruoli. Tra di loro c'è il team tecnologico che si occupa dello sviluppo, della manutenzione del sito, del database e dell'analisi dei clienti. Il team di 60 persone è guidato da Bob, il direttore tecnico dell'azienda.

Il team di Bob distribuisce sistemi di produzione nel cloud. Le loro applicazioni principali funzionano su GKE, sfruttando i vantaggi di Kubernetes in Google Cloud. Inoltre, utilizzano vari strumenti per l'elaborazione dei dati e l'analisi.

Family Insurance non intendeva utilizzare i container, ma si è lasciata contagiare dall'entusiasmo per Docker. Ben presto, gli specialisti dell'azienda hanno scoperto che GKE offre la possibilità di distribuire cluster per testare nuove funzionalità in modo semplice e senza sforzo. Sono stati aggiunti Jenkins per la CI e Quay per la gestione del registro dei container, e sono stati scritti script per Jenkins che inviavano nuovi container e configurazioni a GKE.

È passato del tempo. Alice e Bob si sono sentiti delusi dalle prestazioni dell'approccio scelto e dal suo impatto sul business. L'implementazione dei container non ha migliorato le prestazioni quanto sperava il team. A volte i deployment fallivano, ed era difficile capire se fossero dovuti a modifiche nel codice. Inoltre, è stato complicato tenere traccia delle modifiche delle configurazioni. Spesso era necessario creare un nuovo cluster e trasferirvi le applicazioni, poiché era il modo più semplice per risolvere il disordine che era diventato il sistema. Alice temeva che la situazione peggiorasse man mano che l'applicazione si evolveva (inoltre, stava per iniziare un nuovo progetto basato sul machine learning). Bob aveva automatizzato gran parte del lavoro e non capiva perché la pipeline fosse ancora instabile, scalasse male, e richiedesse periodicamente intervento manuale.

Poi hanno scoperto GitOps. Questa soluzione si è rivelata esattamente ciò di cui avevano bisogno per procedere con fiducia.

Alice e Bob sentono parlare dei flussi di lavoro basati su Git, DevOps e infrastructure as code da diversi anni. L'unicità di GitOps risiede nel fatto che introduce un insieme di best practice - categoriche e normative - per l'implementazione di queste idee nel contesto di Kubernetes. Questo argomento è stato sollevato più volte, incluso nel blog di Weaveworks.

Family Insurance ha deciso di adottare GitOps. Ora l'azienda dispone di un modello operativo automatizzato, compatibile con Kubernetes, che combina velocità e stabilità, poiché hanno:

  • scoperto che la produttività del team è raddoppiata senza che nessuno impazzisca;
  • smettere di gestire script. Invece, ora possono concentrarsi su nuove funzionalità e perfezionare le pratiche ingegneristiche - ad esempio, implementare rilasci canary e migliorare i test;
  • migliorato il processo di distribuzione - ora si rompe raramente;
  • ottenuto la possibilità di ripristinare le distribuzioni dopo parziali guasti senza intervento manuale;
  • acquisito maggiore fiducia nei sistemi di fornitura. Alice e Bob hanno scoperto che è possibile suddividere il team in gruppi che si occupano di microservizi e lavorano in parallelo;unmaggiore fiducia nei sistemi di fornitura. Alice e Bob hanno scoperto che è possibile suddividere il team in gruppi dedicati ai microservizi che lavorano in parallelo;
  • possono apportare 30-50 modifiche al progetto ogni giorno grazie ai contributi di ciascun gruppo e sperimentare nuove tecniche;
  • attirano facilmente nuovi sviluppatori al progetto, che possono implementare aggiornamenti in produzione attraverso pull request già dopo poche ore;
  • superano facilmente l'audit SOC2 (per la conformità dei fornitori di servizi ai requisiti per la gestione sicura dei dati; leggi di più, ad esempio, qui — nota di traduzione).

Cosa è successo?

GitOps è due cose:

  1. Un modello operativo per Kubernetes e cloud native. Fornisce un insieme di best practice per il deployment, la gestione e il monitoraggio di cluster e applicazioni containerizzati. Una definizione elegante in forma di una slide da Luis Faceira:
  2. Il percorso per creare un ambiente orientato agli sviluppatori per la gestione delle applicazioni. Applichiamo il flusso di lavoro Git sia per le operazioni che per lo sviluppo. Si noti che non si tratta semplicemente di Git push, ma di organizzare l'intero set di strumenti CI/CD e UI/UX.

Qualche parola su Git

Se non sei familiare con i sistemi di controllo delle versioni e il flusso di lavoro basato su Git, ti consigliamo vivamente di approfondire l'argomento. All'inizio, lavorare con i rami e le pull request può sembrare magia nera, ma i vantaggi valgono gli sforzi. Ecco un buon articolo per iniziare.

Come funziona Kubernetes

Nella nostra storia, Alice e Bob si sono avvicinati a GitOps dopo aver lavorato a lungo con Kubernetes. Infatti, GitOps è strettamente legato a Kubernetes: è un modello operativo per infrastrutture e applicazioni basate su Kubernetes.

Cosa offre Kubernetes agli utenti?

Ecco alcune delle principali funzionalità:

  1. Nel modello Kubernetes, tutto può essere descritto in modo dichiarativo.
  2. Il server API di Kubernetes accetta tale dichiarazione come input e poi cerca costantemente di riportare il cluster nello stato descritto nella dichiarazione.
  3. Le dichiarazioni sono sufficienti per descrivere e gestire una vasta gamma di carichi di lavoro - "applicazioni".
  4. Di conseguenza, le modifiche all'applicazione e al cluster avvengono a causa di:
    • cambiamenti nelle immagini dei container;
    • cambiamenti nella specifica dichiarativa;
    • errori nell'ambiente - ad esempio, il crash dei container.

Eccellenti capacità di convergenza di Kubernetes

Quando un amministratore apporta modifiche alla configurazione, l'orchestratore Kubernetes le applicherà al cluster finché il suo stato non si avvicinerà alla nuova configurazione. Questo modello funziona per qualsiasi risorsa Kubernetes ed è estensibile tramite Custom Resource Definitions (CRDs). Pertanto, i deployment Kubernetes hanno le seguenti straordinarie proprietà:

  • Automazione: gli aggiornamenti di Kubernetes forniscono un meccanismo per automatizzare il processo di applicazione delle modifiche in modo corretto e tempestivo.
  • Convergenza: Kubernetes continuerà a tentare aggiornamenti fino a quando non avrà successo.
  • Idempotenza: le applicazioni ripetute della convergenza portano allo stesso risultato.
  • Determinismo: se le risorse sono sufficienti, lo stato del cluster aggiornato dipende solo dallo stato desiderato.

Come funziona GitOps

Abbiamo appreso abbastanza su Kubernetes per spiegare i principi di funzionamento di GitOps.

Torniamo ai team di Family Insurance legati ai microservizi. Di cosa si occupano di solito? Dai un'occhiata l'elenco qui sotto (se alcuni punti ti sembrano strani o poco familiari, ti chiediamo di non criticare subito e di rimanere con noi). Questi sono solo esempi di flussi di lavoro basati su Jenkins. Ci sono anche molti altri processi con altri strumenti.

La cosa principale è che vediamo che ogni aggiornamento termina con modifiche ai file di configurazione e ai repository Git. Queste modifiche in Git fanno sì che l'«operatore GitOps» aggiorni il cluster:

1. Flusso di lavoro: «Build Jenkins — branch master».
Elenco delle attività:

  • Jenkins invia le immagini taggate in Quay;
  • Jenkins invia la configurazione e i chart Helm nel bucket del master repository;
  • Una funzione cloud copia la configurazione e i chart dal bucket del master repository nel repository Git master;
  • L'operatore GitOps aggiorna il cluster.

2. Build Jenkins — branch release o hotfix:

  • Jenkins invia le immagini non taggate in Quay;
  • Jenkins invia la configurazione e i chart Helm nel bucket dello staging repository;
  • Una funzione cloud copia la configurazione e i chart dal bucket dello staging repository nel repository Git staging;
  • L'operatore GitOps aggiorna il cluster.

3. Build Jenkins — branch develop o feature:

  • Jenkins invia le immagini non taggate in Quay;
  • Jenkins invia il config e i chart Helm nel bucket di archiviazione develop;
  • La funzione cloud copia il config e i chart dal bucket di archiviazione develop al repository Git develop;
  • L'operatore GitOps aggiorna il cluster.

4. Aggiunta di un nuovo cliente:

  • Il manager o l'amministratore (LCM/ops) invoca Gradle per il primo deploy e la configurazione dei bilanciatori di carico (NLB);
  • LCM/ops effettua il commit del nuovo config per preparare il deploy agli aggiornamenti;
  • L'operatore GitOps aggiorna il cluster.

Descrizione breve di GitOps

  1. Descrivi lo stato desiderato dell'intero sistema utilizzando specifiche dichiarative per ogni ambiente (nella nostra storia, il team di Bob definisce tutta la configurazione del sistema in Git).
    • Il repository Git è l'unica fonte di verità riguardo allo stato desiderato dell'intero sistema.
    • Tutte le modifiche allo stato desiderato vengono effettuate tramite commit in Git.
    • Tutti i parametri desiderati del cluster sono inoltre osservabili all'interno del cluster stesso. In questo modo possiamo determinare se lo stato desiderato e quello osservato coincidono (convergono, converge) o differiscono (divergono, diverge) dallo stato desiderato e osservato.
  2. Se gli stati desiderato e osservato differiscono, allora:
    • Esiste un meccanismo di convergenza che prima o poi sincronizza automaticamente lo stato desiderato e quello osservato. All'interno del cluster, questo è gestito da Kubernetes.
    • Il processo viene avviato immediatamente con la notifica "cambiamento confermato".
    • Dopo un intervallo di tempo configurabile, può essere inviata una notifica "differenza" se gli stati sono differenti.
  3. Pertanto, tutti i commit in Git generano aggiornamenti verificabili e idempotenti nel cluster.
    • Un rollback è una convergenza verso uno stato desiderato precedente.
  4. La convergenza è definitiva. La sua attuazione è testimoniata da:
    • Assenza di notifiche "differenza" per un certo intervallo di tempo.
    • Notifica "convergente" (ad esempio, webhook, evento di scrittura Git).

Che cos'è la divergenza?

Ripetiamo ancora una volta: tutte le proprietà desiderate del cluster devono essere osservabili nel cluster stesso.

Alcuni esempi di divergenza:

  • Modifica nel file di configurazione a causa della fusione di branch in Git.
  • Modifica nel file di configurazione a causa di un commit in Git effettuato da un client GUI.
  • Modifiche multiple nello stato desiderato a causa di una PR in Git con successiva creazione dell'immagine del container e modifiche nella configurazione.
  • Cambiamento dello stato del cluster a causa di errori, conflitti di risorse che portano a "comportamenti anomali" o semplicemente per deviazione casuale dallo stato originale.

Cosa rappresenta il meccanismo di convergenza?

Esempi di applicazione:

  • Per i container e i cluster, il meccanismo di convergenza è fornito da Kubernetes.
  • Lo stesso meccanismo può essere utilizzato per gestire applicazioni e architetture basate su Kubernetes (ad esempio, Istio e Kubeflow).
  • Il meccanismo per gestire l'interazione lavorativa tra Kubernetes, i repository delle immagini e Git è fornito da Weave Flux GitOps operator, che fa parte di Weave Cloud.
  • Per le macchine di base, il meccanismo di convergenza deve essere dichiarativo e autonomo. Dalla nostra esperienza, possiamo dire che Terraform è il più vicino a questa definizione, ma richiede comunque supervisione umana. In questo senso, GitOps estende le tradizioni dell'Infrastructure as Code.

GitOps unisce Git a un ottimo meccanismo di convergenza di Kubernetes, offrendo un modello per l'operatività.

GitOps ci permette di affermare che: solo i sistemi che possono essere descritti e monitorati sono soggetti ad automazione e controllo..

GitOps è destinato all'intero stack cloud native (ad esempio, Terraform e simili).

GitOps non si limita a Kubernetes. Vogliamo che l'intero sistema sia gestito in modo dichiarativo e utilizzi la convergenza. Con l'intero sistema intendiamo l'insieme degli ambienti che lavorano con Kubernetes, come ad esempio "dev cluster 1", "production" e così via. Ogni ambiente comprende macchine, cluster, applicazioni, così come interfacce per servizi esterni che forniscono dati, monitoraggio, ecc.

Notate quanto sia importante Terraform per il problema del bootstrapping. Kubernetes deve essere distribuito da qualche parte, e l'uso di Terraform significa che possiamo applicare gli stessi workflow di GitOps per creare uno strato di controllo alla base di Kubernetes e delle applicazioni. Questa è una buona prassi.

Si presta particolare attenzione all'applicazione dei concetti di GitOps agli strati sopra Kubernetes. Al momento esistono soluzioni di tipo GitOps per Istio, Helm, Ksonnet, OpenFaaS e Kubeflow, così come per Pulumi, che creano uno strato per lo sviluppo di applicazioni cloud native.

Kubernetes CI/CD: confronto tra GitOps e altri approcci.

Come detto, GitOps è due cose:

  1. Un modello operativo per Kubernetes e cloud native, descritto sopra.
  2. Un percorso per organizzare un ambiente orientato agli sviluppatori per la gestione delle applicazioni.

Per molti, GitOps è prima di tutto un flusso di lavoro basato su push di Git. Anche a noi piace. Ma non è tutto: ora diamo un'occhiata alle pipeline CI/CD.

GitOps consente il Continuous Deployment (CD) su Kubernetes.

GitOps offre un meccanismo di distribuzione continua che elimina la necessità di sistemi separati di gestione delle distribuzioni. Tutto il lavoro viene eseguito da Kubernetes.

  • L'aggiornamento dell'applicazione richiede un aggiornamento in Git. Questo è un aggiornamento transazionale al stato desiderato. La "distribuzione" viene quindi eseguita all'interno del cluster direttamente da Kubernetes in base alla descrizione aggiornata.
  • A causa delle specificità di Kubernetes, questi aggiornamenti sono convergenti. Questo fornisce un meccanismo per il Continuous Deployment in cui tutti gli aggiornamenti sono atomici.
  • Nota: Weave Cloud offre un operatore GitOps che integra Git e Kubernetes e consente di eseguire CD allineando lo stato desiderato con quello attuale del cluster.

Senza kubectl e script

È consigliabile evitare l'uso di Kubectl per aggiornare il cluster, in particolare per gli script di raggruppamento dei comandi kubectl. Invece, tramite una pipeline GitOps, l'utente può aggiornare il proprio cluster Kubernetes tramite Git.

I vantaggi includono:

  1. Correttezza. Un gruppo di aggiornamenti può essere applicato, convergente e infine validato, avvicinandoci all'obiettivo del deployment atomico. Al contrario, l'uso di script non offre alcuna garanzia di convergenza (ne parlerò più avanti).
  2. Sicurezza. Citando Kelsey Hightower: «Limitate l'accesso al cluster Kubernetes agli strumenti di automazione e agli amministratori responsabili per il debug o la manutenzione». Vedi anche il mio post sulla sicurezza e la conformità alle specifiche tecniche, così come l'articolo sul hacking di Homebrew attraverso il furto di credenziali da uno script Jenkins mal scritto.
  3. L'esperienza utente. Kubectl espone la meccanica del modello degli oggetti di Kubernetes, che è piuttosto complessa. Idealmente, gli utenti dovrebbero interagire con il sistema a un livello di astrazione più elevato. Qui citerò di nuovo Kelsey e consiglio di dare un'occhiata un curriculum del genere.

La differenza tra CI e CD

GitOps migliora i modelli CI/CD esistenti.

Un moderno server CI è uno strumento per l'orchestrazione. In particolare, è uno strumento per l'orchestrazione delle pipeline CI. Queste includono build, test, merge nel trunk, ecc. I server CI automatizzano la gestione di complesse pipeline multi-passaggio. La comune tentazione è quella di creare uno script per un set di aggiornamenti di Kubernetes e di eseguirlo come elemento della pipeline per pushare le modifiche nel cluster. Infatti, molti professionisti procedono in questo modo. Tuttavia, ciò non è ottimale, ecco perché.

CI dovrebbe essere utilizzato per apportare aggiornamenti al trunk, e il cluster Kubernetes dovrebbe modificarsi in base a questi aggiornamenti per gestire il CD "internamente". La chiamiamo modello pull per il CD, a differenza del modello push CI. Il CD è parte della orchestrazione runtime.

Perché i server CI non dovrebbero gestire il CD tramite aggiornamenti diretti in Kubernetes

Non utilizzare il server CI per orchestrare aggiornamenti diretti in Kubernetes come un insieme di attività CI. Questo è un anti-pattern di cui abbiamo già parlato nel nostro blog.

Torniamo ad Alice e Bob.

Quali problemi hanno affrontato? Il server CI di Bob applica modifiche al cluster, ma se, durante il processo, dovesse bloccarsi, Bob non saprà in quale stato si trova (o dovrebbe trovarsi) il cluster e come risolverlo. Lo stesso vale in caso di successo.

Supponiamo che il team di Bob abbia creato una nuova immagine e poi abbia aggiornato i propri deployment per eseguire l'immagine (tutto ciò attraverso il pipeline CI).

Se l'immagine viene creata correttamente, ma il pipeline si interrompe, il team dovrà scoprire:

  • L'aggiornamento è stato distribuito?
  • Stiamo eseguendo una nuova compilazione? Questo porterà a effetti collaterali indesiderati, con la possibilità di ottenere due compilazioni della stessa immagine immutabile?
  • Dobbiamo aspettare un altro aggiornamento prima di avviare la compilazione?
  • Cosa è andato storto esattamente? Quali passaggi devono essere ripetuti (e quali possono essere ripetuti in sicurezza)?

Organizzare un flusso di lavoro basato su Git non garantisce che il team di Bob non affronti questi problemi. Possono comunque fare errori con il push del commit, con il tag o con qualsiasi altro parametro; tuttavia, questo approccio è comunque molto più vicino al principio del tutto o niente.

In sintesi, ecco perché i server CI non dovrebbero occuparsi del CD:

  • Gli script di aggiornamento non sono sempre deterministici; è facile commettere errori.
  • I server CI non convergono verso un modello dichiarativo del cluster.
  • È difficile garantire l'idempotenza. Gli utenti devono comprendere la semantica profonda del sistema.
  • È più complicato eseguire un ripristino dopo un guasto parziale.

Nota su Helm: se desideri utilizzare Helm, ti consigliamo di combinarlo con un operatore GitOps, come Flux-Helm. Questo aiuterà a garantire la convergenza. Da solo, Helm non è né deterministico né atomico.

GitOps è il modo migliore per realizzare il Continuous Delivery per Kubernetes

Il team di Alice e Bob implementa GitOps e scopre che è molto più facile lavorare con i prodotti software, mantenere alte prestazioni e stabilità. Concludiamo questo articolo con illustrazioni che mostrano come appare il loro nuovo approccio. Tieni presente che stiamo parlando principalmente di applicazioni e servizi, ma GitOps può essere utilizzato per gestire l'intera piattaforma.

Il modello operativo per Kubernetes

Guarda il diagramma seguente. Rappresenta Git e il repository delle immagini dei container come risorse comuni per i due cicli di vita orchestrati:

  • Il pipeline di integrazione continua, che legge e scrive file in Git e può aggiornare il repository delle immagini dei container.
  • Il pipeline Runtime GitOps, che combina il deployment con la gestione e la visibilità. Questo legge e scrive file in Git e può caricare le immagini dei container.

Quali sono le principali conclusioni?

  1. Separazione delle preoccupazioni: Si noti che entrambe le pipeline possono scambiarsi dati solamente aggiornando Git o il repository delle immagini. In altre parole, c'è un firewall tra l'ambiente CI e quello runtime. Lo chiamiamo "firewall dell'immutabilità" (immutability firewall), poiché tutti gli aggiornamenti ai repository creano nuove versioni. Per ulteriori informazioni su questo tema, fare riferimento alle diapositive 72-87 di questa presentazione..
  2. È possibile utilizzare qualsiasi server CI e Git.: GitOps funziona con qualsiasi componente. Puoi continuare a utilizzare i tuoi server CI e Git preferiti, i repository delle immagini e i set di test. Quasi tutti gli altri strumenti per il Continuous Delivery sul mercato richiedono il proprio server CI/Git o un repository delle immagini. Questo può diventare un fattore limitante nello sviluppo del cloud native. Con GitOps puoi utilizzare strumenti familiari.
  3. Gli eventi come strumento di integrazione: Non appena i dati in Git vengono aggiornati, Weave Flux (o l'operatore Weave Cloud) ne informa il runtime. Ogni volta che Kubernetes accetta un insieme di modifiche, Git viene aggiornato. Ciò fornisce un modello semplice per l'integrazione dei flussi di lavoro per GitOps, come mostrato di seguito.

Conclusione

GitOps offre solide garanzie di aggiornamento necessarie a qualsiasi strumento CI/CD moderno:

  • automazione;
  • convergenza;
  • idempotenza;
  • determinismo.

Questo è importante perché offre un modello operativo per gli sviluppatori nel cloud native.

  • Gli strumenti tradizionali per la gestione e il monitoraggio dei sistemi sono legati ai team di operazioni che operano all'interno di un runbook (un insieme di procedure e operazioni di routine — nota del traduttore), legato a un deployment specifico.
  • Nella gestione di sistemi cloud native, gli strumenti di monitoraggio sono il miglior modo per valutare i risultati dei deployment, consentendo al team di sviluppo di reagire prontamente.

Immaginate molteplici cluster distribuiti su vari cloud e numerosi servizi con i propri team e piani di deployment. GitOps offre un modello di gestione scalabile e invariabile per gestire questa abbondanza.

P.S. dal traduttore

Leggete anche nel nostro blog:

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

Sapevate di GitOps prima di questi due articoli su Habr?

  • Sì, sapevo tutto.

  • Solo superficialmente.

  • No

Hanno votato 35 utenti. 10 utenti si sono astenuti.

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