Questa pagina fornisce un punto di partenza per aiutarti a pianificare e progettare pipeline CI/CD GitOps 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 la progettazione e l'organizzazione del codice di configurazione e dell'applicazione. Se impari 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 saperne di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei Google Cloud contenuti, consulta Ruoli e attività comuni degli utenti GKE.
Organizzare i repository
Quando configuri l'architettura GitOps, separa i repository in base ai tipi di file di configurazione archiviati in ogni repository. A livello generale, potresti prendere in considerazione almeno quattro tipi di repository:
- Un repository di pacchetti per gruppi di configurazioni correlate.
- Un repository della piattaforma per la configurazione a livello di parco risorse per cluster e spazi dei nomi.
- Un repository di configurazione dell'applicazione.
- Un repository di codice dell'applicazione.
Il seguente diagramma mostra il layout di questi repository:
Nella Figura 2:
- I team di sviluppo eseguono il push del codice per le applicazioni e le configurazioni delle applicazioni in un repository.
- Il codice per le app e le configurazioni è archiviato nello stesso posto e i team delle applicazioni hanno il controllo su questi repository.
- I team delle applicazioni eseguono il push del codice in una build.
Utilizzare un repository di pacchetti 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 repository centrale.
Ad esempio, il team della piattaforma della tua organizzazione può implementare policy in cui i team delle applicazioni possono utilizzare i pacchetti solo dal repository centrale.
Puoi limitare le autorizzazioni di scrittura al repository a un numero ridotto di ingegneri. Il resto dell'organizzazione può avere accesso in lettura. Ti consigliamo di implementare una procedura per promuovere i pacchetti nel repository centrale e trasmettere gli aggiornamenti.
Sebbene la gestione di un repository centrale possa comportare un overhead aggiuntivo, poiché qualcuno deve gestirlo e aggiunge una procedura aggiuntiva per i team delle applicazioni, questo approccio offre molti vantaggi:
- Un team centrale può scegliere di aggiungere pacchetti pubblici a 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 verificare la presenza di 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.
Creare repository WET
WET sta per "Write Everything Twice". È in contrasto con DRY, che sta per "Don't Repeat Yourself". Questi approcci rappresentano due tipi diversi di file di configurazione:
- Configurazioni DRY , in cui un singolo file di configurazione subisce un'azione di trasformazione per popolare i campi con valori diversi per ambienti diversi. Ad esempio, potresti avere una configurazione del cluster condivisa che viene compilata con una regione diversa 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 flusso di lavoro GitOps:
- È più facile per i membri del team esaminare le modifiche.
- Non è necessaria alcuna elaborazione per visualizzare lo stato previsto di un file di configurazione.
Testare prima la convalida delle configurazioni
Se aspetti che Config Sync inizi la sincronizzazione per verificare la presenza di problemi, puoi 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 kpt.
Sebbene tu debba aggiungere strumenti e logica aggiuntivi alla procedura di commit, il test prima dell'applicazione delle configurazioni presenta i seguenti vantaggi:
- La visualizzazione delle modifiche alla configurazione in una richiesta di modifica può aiutare a impedire che gli errori vengano inseriti in un repository.
- Riduce l'impatto dei problemi nelle configurazioni condivise.
Utilizzare le cartelle anziché i rami
Utilizza le cartelle per le varianti dei file di configurazione anziché i rami. Con le cartelle, puoi utilizzare il comando tree per visualizzare le varianti. Con i rami, non puoi sapere se il delta tra un ramo di produzione e uno di sviluppo è una modifica imminente nella configurazione o una differenza permanente tra l'aspetto degli ambienti prod e dev.
Il principale svantaggio 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 presenta i seguenti vantaggi:
- L'individuazione delle cartelle è più semplice rispetto ai rami.
- È possibile eseguire un diff sulle cartelle con molti strumenti CLI e GUI, mentre il diff dei rami è meno comune al di fuori dei provider Git.
- È più facile distinguere tra differenze permanenti e differenze non promosse con le cartelle.
- Puoi eseguire il deployment delle modifiche a più cluster e spazi dei nomi in una singola richiesta di modifica, mentre i rami richiedono diverse richieste di modifica a rami diversi.
Ridurre al minimo l'utilizzo di ClusterSelectors
ClusterSelectors consente di applicare determinate parti di una configurazione a un sottoinsieme di cluster. Anziché configurare un RootSync o RepoSync oggetto,
puoi modificare la risorsa che viene applicata o aggiungere etichette
ai cluster. Sebbene questo sia un modo leggero per aggiungere caratteristiche a un cluster, con l'aumentare del numero di ClusterSelectors nel tempo, può diventare complicato comprendere lo stato finale del cluster.
Poiché Config Sync 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 vuoi. In questo modo è più facile comprendere lo stato finale del cluster e puoi assemblare le configurazioni per il cluster in una cartella anziché applicare direttamente le decisioni di configurazione sul cluster.
Evitare 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 ne gestisce la gestione del ciclo di vita. Puoi quindi gestire il servizio con Config Sync, anziché i job stessi.
Sebbene Config Sync possa applicare i job, questi non sono adatti ai deployment GitOps per i seguenti motivi:
Campi immutabili: molti campi dei 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 il job viene eliminato dal cluster, Config Sync considera la deviazione dallo stato scelto e ricrea il job. Se specifichi un TTL durata (TTL) job, Config Sync elimina automaticamente il job e lo ricrea e riavvia automaticamente, finché non lo elimini dall'origine attendibile.
Problemi di riconciliazione: in genere, Config Sync attende che gli oggetti vengano riconciliati dopo l'applicazione. Tuttavia, i job vengono considerati riconciliati quando hanno iniziato 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, questo può impedire la sincronizzazione di altre risorse e causare errori finché non li correggi. In altri casi, la sincronizzazione potrebbe riuscire e solo la riconciliazione non riesce.
Per questi motivi, non consigliamo di sincronizzare i job con Config Sync.
Utilizzare 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é consente di organizzare un repository nel modo più conveniente per te.
I repository gerarchici, al contrario, 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 il pacchetto deve spostare la CRD in una directory cluster, aggiungendo un overhead maggiore alla procedura.
L'utilizzo di un repository non strutturato semplifica notevolmente la condivisione e il riutilizzo dei pacchetti di configurazione. Tuttavia, senza una procedura o linee guida definite per l'organizzazione dei repository, le strutture dei repository possono variare da un team all'altro, il che può rendere più difficile l'implementazione di strumenti a livello di parco risorse.
Per scoprire come convertire un repository gerarchico, consulta Convertire un repository gerarchico in un repository non strutturato.
Separare i repository di codice e configurazione
Quando si esegue lo scale up di un mono-repository, è necessaria una build specifica per ogni cartella. Le autorizzazioni e le preoccupazioni per le persone che lavorano sul codice e sulla configurazione del cluster sono generalmente diverse.
La separazione dei repository di codice e configurazione presenta 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 di 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 configurazione presenta i seguenti svantaggi:
- Riduce l'individuazione della configurazione dell'applicazione perché non si trova nello stesso repository del codice dell'applicazione.
- La gestione di molti repository può richiedere molto tempo.
Utilizzare 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 limiti di sicurezza tra la configurazione di sicurezza, della piattaforma e dell'applicazione. È anche una buona idea separare i repository di produzione e non di produzione.
Sebbene la gestione di molti repository possa essere un'attività di per sé impegnativa, l'isolamento di diversi tipi di configurazione in repository diversi presenta i seguenti vantaggi:
- In un'organizzazione con team di piattaforma, sicurezza e applicazioni, la cadenza delle modifiche e delle autorizzazioni è diversa.
- Le autorizzazioni rimangono a livello di repository. I file
CODEOWNERSconsentono alle organizzazioni di limitare l'autorizzazione di scrittura, consentendo comunque l'autorizzazione di lettura. - Config Sync supporta più sincronizzazioni per spazio dei nomi, il che può ottenere un effetto simile all'origine dei file da più repository.
Fissare le versioni dei pacchetti
Che tu utilizzi Helm o Git, devi fissare la versione del pacchetto di configurazione a un valore che non venga spostato accidentalmente senza un rollout esplicito.
Sebbene questo aggiunga controlli aggiuntivi ai rollout quando viene aggiornata una configurazione condivisa, riduce il rischio che gli aggiornamenti condivisi abbiano un impatto maggiore del previsto.
Utilizzare Workload Identity Federation for GKE
Puoi abilitare Workload Identity Federation for GKE sui cluster GKE, che consente ai carichi di lavoro Kubernetes di accedere ai servizi Google in modo sicuro e gestibile.
Sebbene alcuni non-Google Cloud servizi, come GitHub e GitLab, non supportino Workload Identity Federation for GKE, ti consigliamo di provare a utilizzare Workload Identity Federation for GKE ogni volta che è possibile, grazie alla maggiore sicurezza e alla riduzione della complessità della gestione di secret e password.