Implementazioni sicure con Config Sync

Questo documento mostra agli operatori dei cluster e agli amministratori di piattaforma come implementare in modo sicuro le modifiche in più ambienti utilizzando Config Sync. Questo approccio consente di evitare errori che interessano tutti gli ambienti contemporaneamente.

Config Sync consente di gestire cluster singoli, cluster multi-tenant e configurazioni Kubernetes multi-cluster utilizzando i file archiviati in un repository Git.

Le configurazioni possono rappresentare diversi elementi, tra cui:

Config Sync è particolarmente adatto per eseguire il deployment di configurazioni, criteri e carichi di lavoro necessari per eseguire la piattaforma creata sulla base della versione Google Kubernetes Engine (GKE) Enterprise, ad esempio agenti di sicurezza, agenti di monitoraggio e gestori di certificati.

Sebbene sia possibile eseguire il deployment di applicazioni rivolte agli utenti con Config Sync, è sconsigliato collegare il ciclo di vita della release al ciclo di rilascio dei carichi di lavoro amministrativi menzionati in precedenza. Ti consigliamo invece di utilizzare uno strumento dedicato al deployment delle applicazioni, ad esempio uno strumento di deployment continuo, in modo che i team delle applicazioni possano essere responsabili della pianificazione delle release.

Config Sync è un prodotto avanzato che può gestire molti elementi, quindi hai bisogno di sistemi di protezione per evitare errori con un impatto significativo. Questo documento descrive diversi metodi per creare sistemi di protezione. La prima sezione riguarda le implementazioni graduali, mentre la seconda si concentra su test e convalide. La terza sezione mostra come monitorare i deployment.

Implementazione delle implementazioni graduali con Config Sync

In un ambiente multi-cluster, che è una situazione comune per gli utenti di GKE Enterprise, non è consigliabile applicare una modifica alla configurazione in tutti i cluster contemporaneamente. Un'implementazione graduale, cluster per cluster, è molto più sicura perché riduce il potenziale impatto di eventuali errori.

Esistono diversi modi per implementare le implementazioni graduali con Config Sync:

  • Utilizza i commit o i tag Git per applicare manualmente le modifiche che vuoi ai cluster.
  • Utilizza i rami Git per applicare automaticamente le modifiche quando vengono unite. Puoi utilizzare rami diversi per gruppi di cluster diversi.
  • Usa gli oggetti ClusterSelector e NamespaceSelector per applicare selettivamente le modifiche ai sottogruppi di cluster o spazi dei nomi.

Tutti i metodi per le implementazioni graduali presentano vantaggi e svantaggi. La tabella seguente mostra quali di questi metodi puoi utilizzare contemporaneamente:

Compatibilità Commit o tag Git Rami Git Selettori di cluster Selettori dello spazio dei nomi
Commit o tag Git Non compatibile Compatibile Compatibile
Rami Git Non compatibile Compatibile Compatibile
Selettori di cluster Compatibile Compatibile Compatibile
Selettori dello spazio dei nomi Compatibile Compatibile Compatibile

Il seguente albero decisionale può aiutarti a decidere quando utilizzare uno dei metodi di implementazione graduale.

Albero decisionale per i metodi di implementazione.

Utilizzare commit o tag Git

Rispetto agli altri metodi di implementazione graduale, i commit o i tag Git offrono il massimo controllo e la sicurezza. Puoi utilizzare la pagina Config Sync nella console Google Cloud all'interno della console per aggiornare più cluster contemporaneamente. Utilizza questo metodo per applicare le modifiche singolarmente ai cluster e controllare esattamente quando si verificano.

Con questo metodo, "fissa" ogni cluster su una versione specifica (un commit o un tag) del repository. Questo metodo è simile all'utilizzo del commit Git come tag dell'immagine container. Puoi implementare questo metodo specificando il commit, il tag o l'hash nel campo spec.git.revision della risorsa personalizzata RootSync o RepoSync.

Se gestisci le tue risorse personalizzate RootSync o RepoSync con uno strumento come Kustomize, puoi ridurre la quantità di lavoro manuale necessario per le implementazioni. Con questo strumento, dovrai solo modificare il parametro revision in una posizione e poi applicare selettivamente la nuova risorsa personalizzata RootSync o RepoSync ai tuoi cluster nell'ordine e con il ritmo che preferisci.

Inoltre, puoi utilizzare la console Google Cloud per aggiornare il parametro revision contemporaneamente per più cluster appartenenti allo stesso parco risorse. Tuttavia, se disponi di un sistema automatizzato per aggiornare le configurazioni, non è consigliabile utilizzare la console Google Cloud per apportare modifiche alla configurazione.

Ad esempio, la seguente definizione di RootSync configura Config Sync per l'utilizzo del tag 1.2.3:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  sourceType: git
  sourceFormat: unstructured
  git:
    repo: git@example.com:gke/config-sync.git
    revision: 1.2.3
    auth: ssh

Se applichi questa configurazione al cluster, Config Sync utilizzerà il tag 1.2.3 del repository example.com:gke/config-sync.git.

Per aggiornare un cluster, modifica il campo spec.git.revision impostandolo sul nuovo valore per il cluster. Questo ti consente di definire quali cluster aggiornare e quando. Se devi eseguire il rollback di una modifica, reimposta il valore precedente del campo spec.git.revision.

Il seguente diagramma illustra la procedura di implementazione di questo metodo. Innanzitutto, esegui il commit delle modifiche nel repository di Config Sync, quindi aggiorna le definizioni di RootSync su tutti i cluster:

Processo di implementazione per i commit e i tag Git.

Consigliamo di eseguire queste operazioni:

  • Utilizza ID commit Git anziché tag. Per il modo in cui funziona Git, hai la garanzia che non cambieranno mai. Ad esempio, un git push --force non può modificare il commit utilizzato da Config Sync. Questo approccio è utile per scopi di controllo e per monitorare il commit in uso nei log. Inoltre, a differenza dei tag, non c'è nessun passaggio aggiuntivo per eseguire il commit degli ID.
  • Se preferisci utilizzare tag Git anziché ID commit Git, puoi proteggere i tuoi tag se utilizzi una soluzione Git che supporta la protezione.
  • Se vuoi aggiornare più cluster contemporaneamente, puoi farlo nella console Google Cloud. Per aggiornare più cluster contemporaneamente, devono far parte dello stesso parco risorse (e trovarsi nello stesso progetto).

Utilizza rami Git

Se vuoi che le modifiche vengano applicate ai cluster non appena vengono unite nel tuo repository Git, configura Config Sync in modo da utilizzare rami Git al posto di commit o tag. Con questo metodo, crei più rami di lunga durata nel tuo repository Git e configuri Config Sync in diversi cluster per leggerne la configurazione da rami diversi.

Ad esempio, un pattern semplice ha due rami:

  • Un ramo staging per i cluster non di produzione.
  • Un ramo main per i cluster di produzione.

Per i cluster non di produzione, crea l'oggetto RootSync o RepoSync con il campo spec.git.branch impostato su staging. Per i cluster di produzione, crea l'oggetto RootSync o RepoSync con il parametro spec.git.branch impostato su main.

Ad esempio, la seguente definizione di RootSync configura Config Sync in modo da utilizzare il ramo main:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  git:
    repo: git@example.com:gke/config-sync.git
    branch: main
    auth: ssh

Il seguente diagramma illustra la procedura di implementazione di questo metodo:

Processo di implementazione per i rami Git.

Puoi adattare questo pattern a esigenze specifiche, utilizzando più di due rami o utilizzando rami mappati a elementi diversi dagli ambienti. Se devi eseguire il rollback di una modifica, utilizza il comando git revert per creare un nuovo commit sullo stesso ramo che ripristina le modifiche dal commit precedente.

Consigliamo di eseguire queste operazioni:

  • Quando hai a che fare con più cluster, utilizza almeno due rami Git per distinguere i cluster di produzione da quelli non di produzione.
  • La maggior parte delle soluzioni Git consente di utilizzare la funzionalità dei rami protetti per impedire eliminazioni o modifiche non esaminate di questi rami. Per ulteriori informazioni, consulta la documentazione per GitHub, GitLab e Bitbucket.

Utilizzare gli oggetti ClusterSelector e NamespaceSelector

I rami Git sono un buon modo per eseguire un'implementazione graduale delle modifiche in più cluster che alla fine avranno tutti gli stessi criteri. Tuttavia, se vuoi implementare una modifica solo per un sottoinsieme di cluster o di spazi dei nomi, utilizza gli oggetti ClusterSelector e NamespaceSelector. Questi oggetti hanno un obiettivo simile: consentono di applicare oggetti solo a cluster o spazi dei nomi con etichette specifiche.

Ad esempio:

  • Con gli oggetti ClusterSelector, puoi applicare criteri diversi ai cluster, a seconda del paese in cui si trovano, per vari regimi di conformità.
  • Utilizzando gli oggetti NamespaceSelector, puoi applicare criteri diversi agli spazi dei nomi utilizzati da un team interno e da un contraente esterno.

Gli oggetti ClusterSelector e NamespaceSelector consentono inoltre di implementare metodi di test e di rilascio avanzati, tra cui:

  • Release canary, in cui esegui il deployment di un nuovo criterio in un piccolo sottoinsieme di cluster e spazi dei nomi per un lungo periodo di tempo per studiare l'impatto del criterio.
  • Test A/B, in cui esegui il deployment di versioni diverse dello stesso criterio in cluster diversi per studiare la differenza dell'impatto delle versioni del criterio e poi scegli la migliore di cui eseguire il deployment ovunque.

Immagina ad esempio un'organizzazione con diversi cluster di produzione. Il team della piattaforma ha già creato due categorie di cluster di produzione, denominati canary-prod e prod, utilizzando oggetti Cluster e ClusterSelector (vedi Utilizzare ClusterSelector).

Il team della piattaforma vuole implementare un criterio con Policy Controller per applicare la presenza di un'etichetta del team sugli spazi dei nomi al fine di identificare il team a cui appartiene ogni spazio dei nomi. L'azienda ha già implementato una versione di questo criterio in modalità dry run e ora vuole applicarla su un numero limitato di cluster. Utilizzando gli oggetti ClusterSelector, crea due diverse risorse K8sRequiredLabels applicate a cluster diversi.

  • La risorsa K8sRequiredLabels viene applicata ai cluster di tipo prod, con un parametro enforcementAction impostato su dryrun:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: prod
    Spec:
      enforcementAction: dryrun
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    
  • La risorsa K8sRequiredLabels viene applicata ai cluster di tipo canary-prod, senza il parametro enforcementAction, il che significa che il criterio viene effettivamente applicato:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: canary-prod
    spec:
      match:
        kinds:
          - apiGroups: [""]
        kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    

L'annotazione configmanagement.gke.io/cluster-selector consente al team di applicare il criterio solo in cluster di tipo canary-prod, impedendo la diffusione di eventuali effetti collaterali involontari all'intero parco risorse di produzione. Per ulteriori informazioni sulla funzionalità dry run di Policy Controller, consulta Creazione di vincoli.

Consigliamo di eseguire queste operazioni:

  • Utilizza gli oggetti ClusterSelector e NamespaceSelector se devi applicare una modifica alla configurazione solo a un sottoinsieme di cluster o spazi dei nomi a tempo indeterminato o per un periodo di tempo prolungato.
  • Se implementi una modifica utilizzando i selettori, fai molta attenzione. Se utilizzi i commit Git, qualsiasi errore interessa un solo cluster alla volta, perché stai implementando cluster per cluster. Tuttavia, se usi i rami Git, qualsiasi errore può influire su tutti i cluster che lo usano. Se usi i selettori, l'errore può interessare tutti i cluster contemporaneamente.

Implementazione di revisioni, test e convalide

Un vantaggio di Config Sync è che gestisce tutto in modo dichiarativo: risorse Kubernetes, risorse cloud e criteri. Ciò significa che i file in un sistema di gestione del controllo del codice sorgente rappresentano le risorse (file Git, nel caso di Config Sync). Questa caratteristica consente di implementare flussi di lavoro di sviluppo che già utilizzi per il codice sorgente di un'applicazione: revisioni e test automatici.

Implementa le recensioni

Poiché Config Sync si basa su Git, puoi utilizzare la tua soluzione Git preferita per l'hosting del repository Config Sync. La tua soluzione Git probabilmente include una funzionalità di revisione del codice che puoi utilizzare per esaminare le modifiche apportate al repository Config Sync.

Le best practice per rivedere le modifiche nel repository sono le stesse di una normale revisione del codice, come segue:

Data la sensibilità del codebase Config Sync, ti consigliamo inoltre, se possibile con la tua soluzione Git, di effettuare le seguenti configurazioni:

Utilizzando queste diverse funzionalità, puoi applicare le approvazioni per ogni richiesta di modifica al tuo codebase. Ad esempio, puoi assicurarti che ogni modifica venga approvata almeno da un membro del team della piattaforma (che gestisce il parco risorse di cluster) e da un membro del team di sicurezza (che è responsabile della definizione e dell'implementazione dei criteri di sicurezza).

Consigliamo di procedere nel seguente modo:

  • Applica revisioni peer sul tuo repository e proteggi i rami Git utilizzati dai tuoi cluster.

Implementa test automatici

Una best practice comune quando si lavora su un codebase è l'implementazione dell'integrazione continua. Ciò significa che configuri i test automatici da eseguire quando viene creata o aggiornata una richiesta di modifica. I test automatici possono rilevare molti errori prima che una persona esamini la richiesta di modifica. In questo modo il ciclo di feedback è più stretto per lo sviluppatore. Puoi implementare la stessa idea, utilizzando gli stessi strumenti, per il repository di Config Sync.

Ad esempio, un buon punto di partenza è eseguire automaticamente il comando nomos vet in caso di nuove modifiche. Questo comando verifica che la sintassi del repository Config Sync sia valida. Puoi implementare questo test utilizzando Cloud Build seguendo il tutorial sulla convalida delle configurazioni. Puoi integrare Cloud Build con le opzioni seguenti:

  • Bitbucket utilizzando i trigger di build.
  • GitHub, usando l'applicazione GitHub Google Cloud Build. I trigger di build sono disponibili anche per GitHub, ma l'applicazione GitHub è il metodo di integrazione preferito.

Come vedi nel tutorial sulla convalida delle configurazioni, il test viene eseguito utilizzando un'immagine container. Puoi quindi implementare il test in qualsiasi soluzione di integrazione continua che esegua i container, non solo in Cloud Build.

Per rafforzare ulteriormente il ciclo di feedback, puoi chiedere agli utenti di eseguire il comando nomos vet come hook di pre-commit di Git. Un'avvertenza è che alcuni utenti potrebbero non avere accesso ai cluster Kubernetes gestiti da Config Sync e potrebbero non essere in grado di eseguire la convalida completa dalla propria workstation. Esegui il comando nomos vet --clusters "" per limitare la convalida ai controlli semantici e sintattici.

Consigliamo di procedere nel seguente modo:

  • Implementare test in una pipeline di integrazione continua.
  • Esegui almeno il comando nomos vet su tutte le modifiche suggerite.

Monitoraggio delle implementazioni

Anche se implementi tutti i sistemi di protezione coperti da questo documento, gli errori possono comunque verificarsi. Di seguito sono riportati due tipi di errori comuni:

  • Errori che non rappresentano un problema per Config Sync, ma impediscono il corretto funzionamento dei carichi di lavoro, ad esempio un NetworkPolicy eccessivamente restrittivo che impedisce ai componenti del carico di lavoro di comunicare.
  • Errori che impediscono a Config Sync di applicare modifiche a un cluster, ad esempio un manifest Kubernetes non valido o un oggetto rifiutato da un controller di ammissione. I metodi descritti in precedenza dovrebbero rilevare la maggior parte di questi errori.

Rilevare gli errori descritti nel primo punto precedente è quasi impossibile a livello di Config Sync, perché richiede la comprensione dello stato di ciascuno dei tuoi carichi di lavoro. Per questo motivo, è preferibile rilevare questi errori tramite il sistema di monitoraggio esistente che ti avvisa quando un'applicazione funziona in modo anomalo.

Il rilevamento degli errori descritti nel secondo punto precedente, che dovrebbe essere raro se hai implementato tutti i sistemi di protezione, richiede una configurazione specifica. Per impostazione predefinita, Config Sync scrive gli errori nei relativi log (che troverai per impostazione predefinita in Cloud Logging). Gli errori vengono visualizzati anche nella pagina della console Google Cloud di Config Sync. Né i log né la console di solito sono sufficienti per rilevare gli errori, perché probabilmente non li monitori sempre. Il modo più semplice per automatizzare il rilevamento degli errori è eseguire il comando nomos status, che indica se si è verificato un errore in un cluster.

Puoi anche configurare una soluzione più avanzata con avvisi automatici per gli errori. Config Sync espone le metriche nel formato Prometheus. Per ulteriori informazioni, consulta la pagina sul monitoraggio di Config Sync.

Dopo aver inserito le metriche di Config Sync nel sistema di monitoraggio, crea un avviso per ricevere una notifica quando la metrica gkeconfig_monitor_errors è maggiore di 0. Per ulteriori informazioni, consulta la sezione sulla gestione dei criteri di avviso per Cloud Monitoring o sulle regole di avviso per Prometheus.

Riepilogo dei meccanismi per implementazioni sicure con Config Sync

La seguente tabella riassume i vari meccanismi descritti in precedenza in questo documento. Nessuno di questi meccanismi è esclusivo. Puoi scegliere di usarle alcune o tutte per scopi diversi.

Meccanismo Per cosa è utile Cosa non è utile Caso d'uso di esempio
ID e tag del commit Git Utilizza ID o tag di commit Git specifici per controllare con precisione a quali modifiche al cluster vengono applicate. Non utilizzare ID o tag di commit Git per le differenze di lunga durata tra i cluster. Utilizza i selettori di cluster. Tutti i cluster sono configurati per applicare il commit Git 12345. Apporta una modifica con un nuovo commit, abcdef, che vuoi testare. Puoi cambiare la configurazione di un singolo cluster per utilizzare questo nuovo commit per convalidare la modifica.
Rami Git Utilizza più rami Git quando vuoi implementare la stessa modifica in più ambienti, uno dopo l'altro. Non utilizzare più rami Git per le differenze di lunga durata tra i cluster. Le filiali si divergheranno in modo significativo e sarà difficile unirsi tra loro. Innanzitutto unisci la modifica nel ramo di gestione temporanea, dove verrà rilevata dai cluster di gestione temporanea.
Poi unisci la modifica nel ramo master, dove verrà rilevata dai cluster di produzione.
Selettori di cluster e selettori dello spazio dei nomi Utilizza i selettori per le differenze di lunga durata tra cluster e spazi dei nomi. Non utilizzare selettori per un'implementazione graduale in più ambienti. Se vuoi testare una modifica prima in fase di gestione temporanea e poi eseguirne il deployment in produzione, utilizza rami Git separati. Se i team delle applicazioni hanno bisogno dell'accesso completo ai cluster di sviluppo, ma dell'accesso di sola lettura ai cluster di produzione, utilizza l'oggetto ClusterSelector per applicare i criteri RBAC corretti solo ai cluster pertinenti.
Revisioni dei compagni Utilizza le revisioni dei compagni per assicurarti che i team competenti approvino le modifiche. I revisori non rilevano tutti gli errori, in particolare elementi come gli errori di sintassi. La tua organizzazione impone al team di sicurezza di esaminare le modifiche alla configurazione che interessano più sistemi. Chiedi a un membro del team di sicurezza di esaminare le modifiche.
Test automatici nella pipeline di integrazione continua Utilizza i test automatici per individuare gli errori nelle modifiche suggerite. I test automatici non possono sostituire completamente un revisore. Utilizza entrambi. L'esecuzione di un comando nomos vet su tutte le modifiche suggerite conferma che il repository è una configurazione di Config Sync valida.
Monitorare gli errori di sincronizzazione Assicurati che Config Sync applichi effettivamente le modifiche ai cluster. Gli errori di sincronizzazione si verificano solo se Config Sync tenta di applicare un repository non valido o se il server API Kubernetes rifiuta alcuni oggetti. Un utente ignora tutti i test e le revisioni ed esegue il commit di una modifica non valida nel repository di Config Sync. Questa modifica non può essere applicata ai tuoi cluster. Se monitori gli errori di sincronizzazione, riceverai un avviso se viene commesso un errore.

Esempio di strategia di implementazione

Questa sezione utilizza i concetti introdotti nel resto dell'articolo per aiutarti a creare una strategia di implementazione end-to-end in tutti i cluster della tua organizzazione. Questa strategia presuppone che tu disponga di parchi risorse separati per sviluppo, gestione temporanea e produzione (come mostrato in Esempio 1 - Approccio 1 del parco risorse).

In questo scenario, configurerai ogni cluster in modo che si sincronizzi con il tuo repository Git utilizzando un commit Git specifico. Il deployment di una modifica a un parco risorse specifico è un processo in quattro passaggi:

  1. Aggiorni un singolo cluster (il cluster "canary") nel parco risorse per utilizzare prima il nuovo commit.
  2. Verifichi che tutto funzioni come previsto eseguendo test e monitorando l'implementazione.
  3. Aggiorna il resto dei cluster nel parco risorse.
  4. Verifichi di nuovo che tutto funzioni come previsto.

Per eseguire il deployment di una modifica in tutti i tuoi cluster, ripeti questo processo per ogni parco risorse. Puoi applicare tecnicamente questo metodo con qualsiasi commit Git, da qualsiasi ramo. Tuttavia, ti consigliamo di adottare la seguente procedura per identificare i problemi all'inizio del processo di revisione:

  1. Quando qualcuno apre una richiesta di modifica nel repository Git di Config Sync, esegui il deployment della modifica in uno dei cluster di sviluppo.
  2. Se la richiesta di modifica viene accettata e unita nel ramo principale, esegui il deployment completo su tutti i parchi risorse come descritto in precedenza.

Anche se alcune modifiche potrebbero avere come target solo un parco risorse specifico, ti consigliamo di eseguire il deployment di tutte le modifiche in tutti i parchi risorse alla fine. Questa strategia elimina il problema del monitoraggio del parco risorse che deve essere sincronizzato con un determinato commit. Presta particolare attenzione alle modifiche che hanno come target solo il parco risorse di produzione, perché non sarebbe stato possibile eseguire test adeguati nei parchi risorse precedenti. Ad esempio, questo significa attendere più a lungo la comparsa dei problemi tra il deployment nei cluster canary e nel resto dei cluster.

Riassumendo, un deployment end-to-end completo è simile al seguente:

  1. Qualcuno apre una richiesta di modifica.
  2. Vengono eseguiti test e convalide automatici e viene eseguita una revisione manuale.
  3. Puoi attivare manualmente un job per eseguire il deployment della modifica nel cluster canary nel parco risorse di sviluppo. In questo cluster vengono eseguiti test end-to-end automatici.
  4. Se è tutto a posto, unisci la richiesta di modifica nel ramo principale.
  5. L'unione attiva un job automatizzato per il deployment del nuovo commit della mancia del ramo principale nel cluster canary nel parco risorse di sviluppo. In questo cluster vengono eseguiti test end-to-end automatici (per rilevare potenziali incompatibilità tra due richieste di modifica create e unite circa nello stesso momento).
  6. I seguenti job vengono eseguiti uno dopo l'altro (vengono attivati manualmente o dopo un intervallo di tempo predefinito per consentire la segnalazione di regressioni da parte degli utenti):
    1. Esegui il deployment su tutti i cluster del parco risorse di sviluppo.
    2. Esegui test e convalide nei cluster del parco risorse di sviluppo.
    3. Esegui il deployment nel cluster canary del parco risorse gestione temporanea.
    4. Esegui test e convalide nel cluster canary del parco risorse gestione temporanea.
    5. Esegui il deployment su tutti i cluster del parco risorse di gestione temporanea.
    6. Esegui test e convalide nei cluster del parco risorse gestione temporanea.
    7. Esegui il deployment nel cluster canary del parco risorse di produzione.
    8. Esegui test e convalide nel cluster canary del parco risorse di produzione.
    9. Esegui il deployment su tutti i cluster del parco risorse di produzione.
    10. Esegui test e convalide nei cluster del parco risorse di produzione.

Procedura di implementazione completa.

Passaggi successivi