Che cos'è GitOps?

Nota di traduzione.: Dopo una recente pubblicazione di materiale sui metodi pull e push in GitOps, abbiamo notato un interesse per questo modello in generale; tuttavia, le pubblicazioni in lingua russa su questo argomento sono state molto scarse (sul sito di Habr non ce ne sono affatto). Pertanto, siamo lieti di offrire alla vostra attenzione la traduzione di un altro articolo — sebbene sia già di quasi un anno fa! — della società Weaveworks, il cui fondatore ha coniato il termine «GitOps». Nel testo viene spiegata la natura dell'approccio e le principali differenze rispetto a soluzioni già esistenti.

Un anno fa abbiamo pubblicato un'introduzione a GitOps. All'epoca abbiamo raccontato come il team di Weaveworks ha avviato un SaaS interamente basato su Kubernetes e ha sviluppato un insieme di best practices prescrittive per il deployment, la gestione e il monitoraggio in un ambiente cloud native.

L'articolo è stato molto popolare. Altre persone hanno iniziato a parlare di GitOps e a pubblicare nuovi strumenti per git push, lo sviluppo, di segreti, funzioni, all'integrazione continua e così via. Sul nostro sito sono comparse un gran numero di pubblicazioni e casi d'uso di GitOps. Ma alcune persone avevano ancora delle domande. In cosa si distingue il modello rispetto al tradizionale infrastructure as code e alla consegna continua (continuous delivery)? È necessario utilizzare Kubernetes?

Presto ci siamo resi conto che era necessaria una nuova descrizione che offrisse:

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

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

Vi presentiamo: GitOps

Immagina Alice. Gestisce l'azienda Family Insurance, che offre polizze per l'assicurazione sulla salute, automobili, proprietà immobiliari e assicurazione turistica a persone troppo occupate per occuparsi dei dettagli dei contratti da sole. La sua attività è iniziata come un progetto secondario, quando Alice lavorava in banca come data scientist. Un giorno ha capito che poteva utilizzare avanzati algoritmi informatici per un'analisi dei dati e una formulazione di pacchetti assicurativi più efficiente. Gli investitori hanno finanziato il progetto, e ora la sua azienda genera oltre 20 milioni di dollari all'anno e cresce rapidamente. Attualmente, 180 persone lavorano in diverse posizioni. Tra loro c'è il team tecnologico che si occupa dello sviluppo, della manutenzione del sito web, del database e dell'analisi della clientela. La squadra di 60 persone è guidata 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 la gestione dei dati e l'analisi.

Family Insurance non aveva intenzione di utilizzare i container, ma ha contratto entusiasmo per Docker. Presto gli specialisti dell'azienda hanno scoperto che GKE consente di distribuire cluster per testare nuove funzionalità in modo semplice e senza problemi. Sono stati aggiunti Jenkins per CI e Quay per organizzare il registro dei container, e sono stati scritti script per Jenkins che spingevano nuovi container e configurazioni in GKE.

È passato un po' di tempo. Alice e Bob si erano stancati delle prestazioni dell'approccio scelto e del suo impatto sul business. L'implementazione dei container non ha migliorato le prestazioni quanto sperava il team. A volte i deployment si rompevano ed era poco chiaro se le modifiche al codice fossero la causa. È stato anche difficile tenere traccia delle modifiche ai config. Spesso era necessario creare un nuovo cluster e spostare in esso le applicazioni, poiché era il modo più semplice per eliminare il disastro in cui era diventato il sistema. Alice temeva che la situazione peggiorasse con l'evoluzione dell'applicazione (inoltre, stava per sorgere un nuovo progetto basato su machine learning). Bob aveva automatizzato gran parte del lavoro e non capiva perché il pipeline fosse ancora instabile, scalasse male e richiedesse periodicamente interventi manuali.

Poi hanno scoperto GitOps. Questa soluzione si è rivelata proprio ciò di cui avevano bisogno per proseguire con sicurezza.

Alice e Bob avevano già sentito parlare per anni di flussi di lavoro basati su Git, DevOps e infrastructure as code. L'unicità di GitOps è che porta una serie di best practice—categoriche e normative—per implementare queste idee nel contesto di Kubernetes. Questo tema è stato sollevato più volte, incluso in un blog di Weaveworks.

Family Insurance ha deciso di implementare GitOps. Ora l'azienda ha un modello di operazioni automatizzato compatibile con Kubernetes che combina velocità per stabilità, poiché hanno:

  • scoperto che la produttività del team è raddoppiata e nessuno di loro è andato in crisi;
  • smettere di gestire gli script. Invece, ora possono concentrarsi su nuove funzionalità e migliorare le pratiche ingegneristiche—ad esempio, implementare il canary release e migliorare i test;
  • ottimizzato il processo di deployment—ora raramente si rompe;
  • acquisito la possibilità di ripristinare i deployment dopo guasti parziali senza interventi manuali;
  • acquisito bunmaggiore fiducia nei sistemi di fornitura. Alice e Bob hanno scoperto che era possibile dividere il team in gruppi che si occupano di microservizi e lavorano in parallelo;
  • possono apportare 30-50 modifiche al progetto ogni giorno grazie agli sforzi di ciascun gruppo e provare nuove tecniche;
  • attirano facilmente nuovi sviluppatori al progetto, che hanno la possibilità di implementare aggiornamenti in produzione tramite pull request già dopo poche ore;
  • superano facilmente l'audit nel contesto del SOC2 (per l'adeguamento dei fornitori di servizi ai requisiti di gestione sicura dei dati; leggi di più, ad esempio, qui — nota del traduttore.).

Cosa è successo?

GitOps è due cose:

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

Due parole su Git

Se non sei familiare con i sistemi di controllo versione e il flusso di lavoro basato su Git, ti incoraggiamo vivamente a studiarli. Inizialmente, lavorare con rami e pull request può sembrare un'arte oscura, ma i benefici ripagano 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 per un po' 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 forma dichiarativa.
  2. Il server API di Kubernetes accetta tale dichiarazione come input e poi cerca continuamente di riportare il cluster nello stato descritto nella dichiarazione.
  3. Le dichiarazioni sono sufficienti per descrivere e gestire una grande varietà di carichi di lavoro — "applicazioni".
  4. Di conseguenza, le modifiche all'applicazione e al cluster si verificano a causa di:
    • cambiamenti nelle immagini dei container;
    • cambiamenti nella specifica dichiarativa;
    • errori nell'ambiente - come il crash dei container.

Le splendide 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 avvicina alla nuova configurazione. Questo modello funziona per qualsiasi risorsa Kubernetes e si espande tramite le Custom Resource Definitions (CRD). Pertanto, i deployment di Kubernetes possiedono le seguenti meravigliose 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 gli aggiornamenti fino al raggiungimento del successo.
  • Idempotenza: le applicazioni ripetute della convergenza portano allo stesso risultato.
  • Determinismo: con risorse 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 che si occupano di microservizi. Di cosa si occupano solitamente? Dai un'occhiata all'elenco qui sotto (se qualche punto ti sembra strano o sconosciuto, per favore, astieniti dal criticare e resta con noi). Questi sono solo esempi di flussi di lavoro basati su Jenkins. Ci sono anche molti altri processi quando si lavora 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 portano il 'operatore GitOps' ad aggiornare il cluster:

1. Flusso di lavoro: 'Build Jenkins - ramo master».
Elenco dei compiti:

  • Jenkins invia immagini taggate su Quay;
  • Jenkins invia la configurazione e i grafici Helm nel bucket di archiviazione master;
  • La funzione cloud copia la configurazione e i grafici dal bucket di archiviazione master al repository Git master;
  • L'operatore GitOps aggiorna il cluster.

2. Build Jenkins - ramo release o hotfix:

  • Jenkins invia immagini non taggate su Quay;
  • Jenkins invia la configurazione e i grafici Helm nel bucket di archiviazione staging;
  • La funzione cloud copia la configurazione e i grafici dal bucket di archiviazione staging al repository Git staging;
  • L'operatore GitOps aggiorna il cluster.

3. Build Jenkins - ramo develop o feature:

  • Jenkins invia immagini non taggate su Quay;
  • Jenkins invia la configurazione e i grafici Helm nel bucket di archiviazione develop;
  • La funzione cloud copia la configurazione e i grafici 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) chiama Gradle per il primo deployment e la configurazione dei bilanciatori di carico (NLB);
  • LCM/ops esegue il commit della nuova configurazione per preparare il deployment agli aggiornamenti;
  • L'operatore GitOps aggiorna il cluster.

Breve descrizione di GitOps

  1. Descrivi lo stato desiderato dell'intero sistema, utilizzando specifiche dichiarative per ogni ambiente (nella nostra storia, il team di Bob definisce l'intera 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 avvengono tramite commit in Git.
    • Tutti i parametri desiderati del cluster sono anche osservabili all'interno dello stesso cluster. Così possiamo determinare se coincidono (convergono, converge) o differiscono (divergono, diverge) lo stato desiderato e quello osservato.
  2. Se lo stato desiderato e quello osservato differiscono, allora:
    • Esiste un meccanismo di convergenza che, prima o poi, sincronizza automaticamente lo stato atteso e quello osservato. All'interno del cluster, questo è gestito da Kubernetes.
    • Il processo si avvia immediatamente con la notifica "change committed".
    • Dopo un certo intervallo di tempo configurabile, può essere inviata una notifica "diff", se gli stati differiscono.
  3. Così, tutti i commit in Git generano aggiornamenti verificabili e idempotenti nel cluster.
    • Un rollback è una convergenza a uno stato desiderato precedente.
  4. La convergenza è definitiva. La sua avvenuta è testimoniata da:
    • L'assenza di notifiche "diff" per un certo intervallo di tempo.
    • La notifica "converged" (ad esempio, webhook, evento Git writeback).

Che cos'è la divergenza?

Ripetiamo ancora una volta: tutte le proprietà desiderate del cluster devono essere osservabili all'interno dello stesso cluster.

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.
  • Multiple modifiche allo stato desiderato a causa di PR in Git seguite dalla costruzione di un'immagine del contenitore e modifiche della configurazione.
  • Modifica dello stato del cluster a causa di errori, conflitti di risorse che portano a "comportamenti indesiderati", o semplicemente deviazioni casuali dallo stato originale.

Che cos'è il meccanismo di convergenza?

Alcuni esempi:

  • Per contenitori e cluster, il meccanismo di convergenza è fornito da Kubernetes.
  • Lo stesso meccanismo può essere utilizzato per gestire applicazioni e strutture basate su Kubernetes (ad esempio, Istio e Kubeflow).
  • Il meccanismo per gestire l'interazione lavorativa tra Kubernetes, i repository delle immagini e Git fornisce l'operatore GitOps Weave Flux, che è 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 è più vicino a questa definizione, ma richiede ancora un controllo umano. In questo senso, GitOps amplia le tradizioni dell'Infrastructure as Code.

GitOps combina Git con un eccellente meccanismo di convergenza di Kubernetes, offrendo un modello per l'operatività.

GitOps ci consente 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, ecc.)

GitOps non è solo Kubernetes. Vogliamo che l'intero sistema sia gestito in modo dichiarativo e utilizzi la convergenza. Con 'sistema intero' ci riferiamo all'insieme degli ambienti che lavorano con Kubernetes, ad esempio, 'dev cluster 1', 'produzione', ecc. Ogni ambiente include macchine, cluster, applicazioni e interfacce per servizi esterni che forniscono dati, monitoraggio, ecc.

Notate quanto sia importante, in questo caso, Terraform per il problema del bootstrapping. Kubernetes deve essere distribuito da qualche parte, e l'uso di Terraform significa che possiamo applicare gli stessi processi di lavoro GitOps per creare uno strato di controllo alla base di Kubernetes e delle applicazioni. Questa è una pratica migliore utile.

C'è molta attenzione sull'applicazione dei concetti GitOps agli strati sopra Kubernetes. Attualmente ci sono soluzioni di tipo GitOps per Istio, Helm, Ksonnet, OpenFaaS e Kubeflow, e anche 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 verso l'organizzazione di un ambiente orientato agli sviluppatori per gestire le applicazioni.

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

GitOps garantisce il deployment continuo (CD) sotto Kubernetes

GitOps offre un meccanismo di deployment continuo che elimina la necessità di 'sistemi di gestione dei deployment' separati. Tutto il lavoro viene svolto da Kubernetes.

  • L'aggiornamento dell'applicazione richiede un aggiornamento in Git. Questo è un aggiornamento transazionale al stato desiderato. Il "deployment" viene quindi eseguito all'interno del cluster da Kubernetes stesso sulla base della descrizione aggiornata.
  • A causa della specificità del funzionamento di Kubernetes, questi aggiornamenti sono convergenti. Ciò fornisce un meccanismo per un deployment continuo, in cui tutti gli aggiornamenti sono atomici.
  • Nota: Weave Cloud offre un operatore GitOps, che integra Git e Kubernetes e consentendo di eseguire CD mediante l'allineamento dello stato desiderato con quello attuale del cluster.

Senza kubectl e script

Dovrebbe essere evitato l'uso di Kubectl per aggiornare il cluster, e in particolare degli script per raggruppare i comandi kubectl. Invece, con una pipeline GitOps, l'utente può aggiornare il proprio cluster Kubernetes attraverso Git.

I vantaggi includono:

  1. Correttezza. Un gruppo di aggiornamenti può essere applicato, convergere e infine convalidare, avvicinandoci all'obiettivo del deployment atomico. Al contrario, l'uso di script non offre alcuna garanzia di convergenza (ne parlerò più a lungo più avanti).
  2. Sicurezza. Citare Kelsey Hightower: "Limitare l'accesso al cluster Kubernetes solo agli strumenti di automazione e agli amministratori responsabili della sua manutenzione o risoluzione dei problemi". Vedi anche la mia pubblicazione sulla sicurezza e la conformità alle specifiche, così come l'articolo sul hack di Homebrew attraverso il furto di credenziali da uno script Jenkins scritto in modo superficiale.
  3. Esperienza utente. Kubectl espone la meccanica del modello a oggetti di Kubernetes, che è piuttosto complessa. Idealmente, gli utenti dovrebbero interagire con il sistema a un livello più alto di astrazione. Qui, richiamo di nuovo Kelsey e consiglio di dare un'occhiata a questo riassunto.

La differenza tra CI e CD

GitOps migliora i modelli CI/CD esistenti.

Un moderno server CI è uno strumento per l'orchestrazione. In particolare, si tratta di uno strumento per orchestrare le pipeline CI. Queste includono build, test, merge nel trunk, ecc. I server CI automatizzano la gestione di complesse pipeline a più fasi. Un comune tentativo è quello di creare uno script per un set di aggiornamenti Kubernetes e di eseguirlo come parte della pipeline per pushare le modifiche nel cluster. In effetti, molti specialisti fanno così. Tuttavia, ciò non è ottimale, ecco perché.

CI deve essere utilizzato per apportare aggiornamenti al trunk, mentre il cluster Kubernetes deve modificarsi in base a questi aggiornamenti per gestire il CD "internamente". Lo chiamiamo modello pull per il CD, a differenza del modello push del 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 insieme di compiti CI. Questo è un anti-modello di cui abbiamo ha già raccontato parlato nel nostro blog.

Torniamo ad Alice e Bob.

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

Poniamo che il team di Bob abbia costruito una nuova immagine e poi patchato i loro deployment per distribuire l'immagine (tutto questo dal pipeline CI).

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

  • È stata implementata l'aggiornamento?
  • Stiamo eseguendo una nuova build? Porterà a effetti collaterali indesiderati — c'è la possibilità di ottenere due build della stessa immagine invariata?
  • Dobbiamo aspettare un altro aggiornamento prima di eseguire la build?
  • Cosa è andato esattamente storto? Quali passaggi devono essere ripetuti (e quali di essi possono essere ripetuti in sicurezza)?

L'organizzazione di un flusso di lavoro basato su Git non garantisce che il team di Bob non affronti questi problemi. Possono comunque sbagliare con il push del commit, con il tag o con qualche altro parametro; tuttavia, questo approccio è comunque molto più vicino a un modello esplicito di 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 profonda semantica del sistema.
  • È più complicato eseguire un ripristino dopo un guasto parziale.

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

GitOps come miglior modo di realizzare il Continuous Delivery per Kubernetes

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

Modello di operatività per Kubernetes

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

  • Pipelines di integrazione continua, che leggono e scrivono file in Git e possono aggiornare il repository delle immagini dei container.
  • Pipelines Runtime GitOps, che combina il deployment con la gestione e l'osservabilità. Legge e scrive file in Git e può caricare immagini dei container.

Quali sono le principali conclusioni?

  1. Separazione delle preoccupazioni: Nota che entrambe le pipeline possono scambiare dati solo 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 dei repository creano nuove versioni. Per ulteriori informazioni su questo argomento, fai riferimento alle diapositive 72-87. questa presentazione.
  2. Puoi utilizzare qualsiasi server CI e Git: GitOps funziona con qualsiasi componente. Puoi continuare a utilizzare i tuoi server CI e Git preferiti, repository delle immagini e set di test. Quasi tutti gli altri strumenti per il Continuous Delivery sul mercato richiedono il proprio server CI/Git o repository delle immagini. Questo può diventare un fattore limitante nello sviluppo cloud native. Nel caso di GitOps, puoi utilizzare strumenti familiari.
  3. Eventi come strumento di integrazione: Una volta che i dati in Git vengono aggiornati, Weave Flux (o l'operatore Weave Cloud) notifica l'ambiente runtime. Ogni volta che Kubernetes accetta un insieme di modifiche, Git viene aggiornato. Questo fornisce un modello di integrazione semplice per organizzare i flussi di lavoro per GitOps, come mostrato di seguito.

Conclusione

GitOps fornisce forti garanzie di aggiornamento, necessarie per qualsiasi moderno strumento CI/CD:

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

Questo è importante poiché offre un modello operativo per gli sviluppatori nel campo del cloud native.

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

Immagina un gran numero di cluster distribuiti su vari cloud e un gran numero di servizi con propri team e piani di deployment. GitOps offre un modello indipendente dalla scala per gestire tutta questa abbondanza.

P.S. dal traduttore

Leggi anche nel nostro blog:

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

Sapevi di GitOps prima di questi due articoli su Habr?

  • Sì, lo sapevo

  • 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