Il deploy delle nostre applicazioni è sempre una fase delicata e che richiede grande attenzione poichè si vuole spesso raggiungere, ad esempio, il cliente senza interruzzione di servizio. Questo obiettivo del zero downtime è piuttosto complicato da raggiugnere e, spesso, dipende dall'infrastruttura e dalle applicazioni. Ad esempio, aggiornare una API in cloud è molto più semplice che non aggiornare un database di SQL in cui dobbiamo migrare schema e dati. Questo è vero sia in termini di tempo, che la pipeline impiegherà, che di costo di implementazione.
Tuttavia, negli ultimi mesi o anni, con l'avvento di Kubernetes e di pipeline YAML in Azure DevOps, Microsoft ha introdotto nuove strategie di deployment che ad oggi si sono notevolmente affermate, come la classica runOnce che, come dice il nome permette la singola esecuzione di un processo, piuttosto che la canary e rolling che permettono di fare un rilascio incrementale. Queste strategie consentono un grande controllo nella fase di rilascio poichè spesso vengono collegate a sistemi di telemetria che permettono di evidenziare eventuali problemi di routing (per esempio) e consentono di automatizzare anche eventuali passaggi di rollback qualora qualcosa non dovesse funzionare.
Vediamo un esempio specifico di deployment canary:
jobs: - deployment: environment: prod pool: vmImage: 'ubuntu-latest' strategy: canary: increments: [10,20] preDeploy: steps: - script: echo 'initialize, cleanup...' deploy: steps: - script: echo 'deploy updates...' routeTraffic: steps: - script: echo 'routing traffic...' postRouteTraffic: pool: server steps: - script: echo 'monitor application health...' on: failure: steps: - script: echo 'perform rollback actions...' success: steps: - script: echo 'checks passed, notify...'
Come si può vedere dall'esempio, in questo caso non abbiamo usato un job "classico", ma un job di tipo deployment. Oltre ad abilitarci il download automatico (se non specificato altrimenti) di eventuali artifact già presenti nella pipeline, questo tipo di job ci permette di utilizzare scenari di release management differenti. In prima istanza, troviamo che il deploy è in realtà suddiviso in tre step: preDeploy ci consente di fare tutte le operazioni propedeutiche al rilascio in sè, come eventuali inizializzazioni, setup di configurazioni network, switch DNS etc., deploy si occuperà del vero e proprio rilascio, mentre routeTraffic ci consente di incrementare la percentuale di utenti, specificata da increments e di monitorarne lo stato tramite postRouteTraffic.
Quando siamo sicuri che tutto funziona, allora verrà quindi eseguito lo step di success, che possiamo usare per mandare una conferma di avvenuto rilascio, mentre se qualcosa dovesse andare storto, in una qualsiasi delle fasi di rilascio, verrebbe invocato automaticamente lo step di failure che potrebbe occuparsi di fare le operazioni di rollback necessarie. Chiaro che, a questo punto, si tratterebbe solo di implementare la giusta logica per ripristinare lo stato corretto.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Evitare la script injection nelle GitHub Actions
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Eseguire query manipolando le liste contenute in un oggetto mappato verso una colonna JSON
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Utilizzare i primary constructor in C#
Sostituire la GitHub Action di login su private registry
Configurare dependabot per aggiornare le dipendenze di terze parti con GitHub Actions
Usare lo spread operator con i collection initializer in C#
Trasformare qualsiasi backend in un servizio GraphQL con Azure API Management
Determinare lo stato di un pod in Kubernetes
Reactive form tipizzati con FormBuilder in Angular
I più letti di oggi
- Utilizzare WebAssembly con .NET, ovunque
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
- Utilizzare il trigger SQL con le Azure Function
- Disabilitare automaticamente un workflow di GitHub (parte 2)
- Paginare i risultati con QuickGrid in Blazor
- Ottimizzazione dei block template in Angular 17