Best practice di GitOps

Questa pagina fornisce un punto di partenza per aiutarti a pianificare e progettare pipeline GitOps CI/CD per Kubernetes. GitOps, insieme a strumenti come Config Sync, offre vantaggi come una maggiore stabilità del codice, una migliore leggibilità e l'automazione.

GitOps è un approccio in rapida crescita per la gestione della configurazione di Kubernetes su larga scala. A seconda dei requisiti della pipeline CI/CD, esistono molte opzioni per progettare e organizzare il codice dell'applicazione e della configurazione. Imparando alcune best practice di GitOps, puoi creare un'architettura stabile, ben organizzata e sicura.

Questa pagina è rivolta ad amministratori, architetti e operatori che vogliono implementare GitOps nel proprio ambiente. Per scoprire di più sui ruoli comuni e sugli esempi di attività a cui facciamo riferimento nei contenuti di Google Cloud , consulta Ruoli e attività comuni degli utenti GKE.

Organizza i tuoi repository

Quando configuri l'architettura GitOps, separa i repository in base ai tipi di file di configurazione archiviati in ciascun repository. A livello generale, puoi prendere in considerazione almeno quattro tipi di repository:

  1. Un Package Repository per gruppi di configurazioni correlate.
  2. Un repository della piattaforma per la configurazione a livello di parco risorse per cluster e spazi dei nomi.
  3. Un repository di configurazione dell'applicazione.
  4. Un repository di codice dell'applicazione.
Il seguente diagramma mostra il layout di questi repository:

Figura 1: architettura suggerita per un repository di pacchetti e piattaforme che confluisce nei repository di configurazione e codice dell'applicazione.
Figura 2: build dell'applicazione suggerita che mostra il codice dell'applicazione e le configurazioni dell'applicazione di cui viene eseguito il push in una build.

Nella Figura 2:

  1. I team di sviluppo eseguono il push del codice per le applicazioni e le configurazioni delle applicazioni in un repository.
  2. Il codice per le app e le configurazioni è archiviato nello stesso posto e i team delle applicazioni hanno il controllo su questi repository.
  3. I team delle applicazioni eseguono il push del codice in una build.

Utilizza un Package Repository privato centralizzato

Utilizza un repository centrale per i pacchetti pubblici o interni, come i grafici Helm,per aiutare i team a trovare i pacchetti. Ad esempio, se il repository è strutturato in modo logico o contiene un file readme, l'utilizzo di repository di pacchetti privati centralizzati può aiutare i team a trovare rapidamente le informazioni. Puoi utilizzare servizi come Artifact Registry o repository Git per organizzare il tuo repository centrale.

Ad esempio, il team della piattaforma della tua organizzazione può implementare policy in base alle quali i team delle applicazioni possono utilizzare i pacchetti solo dal repository centrale.

Puoi limitare le autorizzazioni in scrittura nel repository a un numero limitato di ingegneri. Il resto dell'organizzazione può avere accesso in lettura. Ti consigliamo di implementare un processo per la promozione dei pacchetti nel repository centrale e la trasmissione degli aggiornamenti.

Sebbene la gestione di un repository centrale possa comportare un overhead aggiuntivo, poiché qualcuno deve occuparsi della manutenzione del repository centrale e questo aggiunge un processo aggiuntivo per i team delle applicazioni, questo approccio offre molti vantaggi:

  • Un team centrale può scegliere di aggiungere pacchetti pubblici con una cadenza definita, il che aiuta a evitare interruzioni dovute alla connettività o al churn upstream.
  • Una combinazione di revisori automatici e umani può controllare i pacchetti per individuare eventuali problemi prima di renderli ampiamente disponibili.
  • Il repository centrale consente ai team di scoprire cosa è in uso e supportato. Ad esempio, i team possono trovare il deployment Redis standard archiviato nel repository centrale.
  • Puoi automatizzare le modifiche ai pacchetti upstream per assicurarti che soddisfino gli standard interni, come i valori predefiniti, l'aggiunta di etichette e i repository di immagini container.

Crea repository WET

WET sta per "Write Everything Twice" (scrivi tutto due volte). Si contrappone a DRY, che sta per "Don't Repeat Yourself" (Non ripeterti). Questi approcci rappresentano due diversi tipi di file di configurazione:

  • Configurazioni DRY, in cui un singolo file di configurazione viene sottoposto a un'azione di trasformazione per compilare i campi con valori diversi per ambienti diversi. Ad esempio, potresti avere una configurazione del cluster condivisa che viene compilata con una regione o impostazioni di sicurezza diverse per ambienti diversi.
  • Configurazioni WET (o, a volte, "completamente idratate"), in cui ogni file di configurazione è rappresentativo dello stato finale.

Sebbene i repository WET possano portare ad alcuni file di configurazione ripetuti, presentano i seguenti vantaggi per un workflow GitOps:

  • È più facile per i membri del team esaminare le modifiche.
  • Non è richiesta alcuna elaborazione per visualizzare lo stato previsto di un file di configurazione.

Esegui i test in anticipo durante la convalida delle configurazioni

Attendere che Config Sync inizi la sincronizzazione per verificare la presenza di problemi può creare commit Git non necessari e un lungo ciclo di feedback. Molti problemi possono essere rilevati prima che una configurazione venga applicata a un cluster utilizzando le funzioni di convalida di kpt.

Anche se devi aggiungere altri strumenti e logica al processo di commit, i test prima di applicare le configurazioni offrono i seguenti vantaggi:

  • La visualizzazione delle modifiche alla configurazione in una richiesta di modifica può aiutare a evitare che gli errori vengano inseriti in un repository.
  • Riduce l'impatto dei problemi nelle configurazioni condivise.

Utilizza le cartelle anziché i rami

Utilizza le cartelle per le varianti dei file di configurazione anziché i branch. Con le cartelle, puoi utilizzare il comando tree per visualizzare le varianti. Con i branch, non puoi sapere se il delta tra un branch di produzione e uno di sviluppo è una modifica imminente della configurazione o una differenza permanente tra l'aspetto che dovrebbero avere gli ambienti prod e dev.

Lo svantaggio principale di questo approccio è che l'utilizzo delle cartelle non consente di promuovere le modifiche alla configurazione utilizzando una richiesta di modifica agli stessi file. Tuttavia, l'utilizzo delle cartelle anziché dei rami offre i seguenti vantaggi:

  • La scoperta delle cartelle è più semplice di quella delle filiali.
  • Eseguire un diff sulle cartelle è possibile con molti strumenti CLI e GUI, mentre il diff dei branch è meno comune al di fuori dei provider Git.
  • Con le cartelle è più facile distinguere tra differenze permanenti e differenze non promosse.
  • Puoi eseguire il deployment delle modifiche in più cluster e spazi dei nomi in un'unica richiesta di modifica, mentre i branch richiedono diverse richieste di modifica per branch diversi.

Riduci al minimo l'utilizzo di ClusterSelectors

ClusterSelectors ti consentono di applicare determinate parti di una configurazione a un sottoinsieme di cluster. Anziché configurare un oggetto RootSync o RepoSync, puoi modificare la risorsa che viene applicata o aggiungere etichette ai cluster. Sebbene questo sia un modo semplice per aggiungere caratteristiche a un cluster, man mano che il numero di ClusterSelectors aumenta nel tempo, può diventare complicato comprendere lo stato finale del cluster.

Poiché Config Sync ti consente di sincronizzare più oggetti RootSync e RepoSync contemporaneamente, puoi aggiungere la configurazione pertinente a un repository separato e poi sincronizzarla con i cluster che preferisci. In questo modo è più facile comprendere lo stato finale del cluster e puoi raggruppare le configurazioni del cluster in una cartella anziché applicare le decisioni di configurazione direttamente sul cluster.

Evita di gestire i job con Config Sync

Nella maggior parte dei casi, i job e altre attività situazionali devono essere gestiti da un servizio che si occupa della gestione del loro ciclo di vita. Puoi quindi gestire il servizio con Config Sync, anziché i job stessi.

Sebbene Config Sync possa applicare i job per te, i job non sono adatti per i deployment GitOps per i seguenti motivi:

  • Campi immutabili: molti campi di Job sono immutabili. Per modificare un campo immutabile, l'oggetto deve essere eliminato e ricreato. Tuttavia, Config Sync non elimina l'oggetto, a meno che non lo rimuovi dall'origine.

  • Esecuzione involontaria dei job: se sincronizzi un job con Config Sync e poi questo viene eliminato dal cluster, Config Sync considera questa deviazione dallo stato scelto e ricrea il job. Se specifichi una durata (TTL) del job, Config Sync elimina automaticamente il job e lo ricrea e lo riavvia automaticamente, finché non lo elimini dalla single source of truth.

  • Problemi di riconciliazione: Config Sync normalmente attende la riconciliazione degli oggetti dopo l'applicazione. Tuttavia, i job sono considerati riconciliati quando iniziano l'esecuzione. Ciò significa che Config Sync non attende il completamento del job prima di continuare ad applicare altri oggetti. Tuttavia, se il job non riesce in un secondo momento, viene considerato un errore di riconciliazione. In alcuni casi, ciò può impedire la sincronizzazione di altre risorse e causare errori finché non viene risolto. In altri casi, la sincronizzazione potrebbe riuscire e solo la riconciliazione non va a buon fine.

Per questi motivi, sconsigliamo di sincronizzare i job con Config Sync.

Utilizza repository non strutturati

Config Sync supporta due strutture per l'organizzazione di un repository: non strutturata e gerarchica.

L'approccio non strutturato è quello consigliato perché ti consente di organizzare un repository nel modo più conveniente per te. I repository gerarchici, invece, applicano una struttura specifica, come le definizioni di risorse personalizzate (CRD) in una directory cluster. Questo può causare problemi quando devi condividere le configurazioni. Ad esempio, se un team pubblica un pacchetto che contiene una CRD, un altro team che deve utilizzare quel pacchetto deve spostare la CRD in una directory cluster, aggiungendo ulteriore overhead al processo.

Utilizzando un repository non strutturato, diventa molto più facile condividere e riutilizzare i pacchetti di configurazione. Tuttavia, senza un processo o linee guida definiti per l'organizzazione dei repository, le strutture dei repository possono variare tra i team, il che può rendere più difficile l'implementazione di strumenti a livello di parco risorse.

Per scoprire come convertire un repository gerarchico, consulta Converti un repository gerarchico in un repository non strutturato.

Repository di codice e configurazione separati

Quando si esegue lo scale up di un repository singolo, è necessaria una build specifica per ogni cartella. Le autorizzazioni e le preoccupazioni di chi lavora sul codice e di chi lavora sulla configurazione del cluster sono generalmente diverse.

La separazione dei repository di codice e di configurazione offre i seguenti vantaggi:

  • Evita i commit "in loop". Ad esempio, il commit in un repository di codice potrebbe attivare una richiesta CI, che potrebbe produrre un'immagine, che a sua volta richiede un commit del codice.
  • Il numero di commit richiesti può diventare un onere per i membri del team che contribuiscono.
  • Puoi utilizzare autorizzazioni diverse per le persone che lavorano sul codice dell'applicazione e sulla configurazione del cluster.

La separazione dei repository di codice e di configurazione presenta i seguenti svantaggi:

  • Riduce il rilevamento della configurazione dell'applicazione, poiché non si trova nello stesso repository del codice dell'applicazione.
  • La gestione di molti repository può richiedere molto tempo.

Utilizza repository separati per isolare le modifiche

Quando si esegue lo scale up di un mono-repository, sono necessarie autorizzazioni diverse per cartelle diverse. Per questo motivo, la separazione dei repository consente di creare confini di sicurezza tra la configurazione della sicurezza, della piattaforma e dell'applicazione. È inoltre consigliabile separare i repository di produzione da quelli non di produzione.

Sebbene la gestione di molti repository possa essere un'attività complessa, l'isolamento di diversi tipi di configurazione in repository diversi offre i seguenti vantaggi:

  • In un'organizzazione con team di piattaforma, sicurezza e applicazioni, la frequenza delle modifiche e delle autorizzazioni è diversa.
  • Le autorizzazioni rimangono a livello di repository. I file CODEOWNERS consentono alle organizzazioni di limitare l'autorizzazione in scrittura, pur consentendo l'autorizzazione in lettura.
  • Config Sync supporta più sincronizzazioni per spazio dei nomi, il che può ottenere un effetto simile all'approvvigionamento di file da più repository.

Blocca le versioni dei pacchetti

Che tu utilizzi Helm o Git, devi bloccare la versione del pacchetto di configurazione su un valore che non venga spostato accidentalmente in avanti senza un'implementazione esplicita.

Sebbene ciò aggiunga ulteriori controlli alle implementazioni quando viene aggiornata una configurazione condivisa, riduce il rischio che gli aggiornamenti condivisi abbiano un impatto maggiore del previsto.

Utilizza Workload Identity Federation for GKE

Puoi abilitare la Workload Identity Federation for GKE sui cluster GKE, in modo che i workload Kubernetes possano accedere ai servizi Google in modo sicuro e gestibile.

Sebbene alcuni servizi nonGoogle Cloud , come GitHub e GitLab, non supportino Workload Identity Federation for GKE, dovresti provare a utilizzare Workload Identity Federation for GKE quando possibile, per via della maggiore sicurezza e della minore complessità della gestione di secret e password.

Passaggi successivi