Share via


Esercitazione: Usare una strategia di distribuzione canary per le distribuzioni Kubernetes

Azure DevOps Services | Azure DevOps Server 2022

Una strategia di distribuzione canary significa distribuire nuove versioni di un'applicazione accanto a versioni stabili e di produzione. È quindi possibile vedere in che modo la versione canary viene confrontata con la baseline, prima di promuovere o rifiutare la distribuzione.

Questa guida dettagliata illustra come usare la strategia canary dell'attività manifesto kubernetes. In particolare, si apprenderà come configurare le distribuzioni canary per Kubernetes e il flusso di lavoro associato per valutare il codice. Usare quindi tale codice per confrontare le distribuzioni di app canary e baseline, in modo da decidere se promuovere o rifiutare la distribuzione canary.

Se si usa servizio Azure Kubernetes, il tipo di connessione del servizio Azure Resource Manager è il modo migliore per connettersi a un cluster privato o a un cluster con account locali disabilitati.

Prerequisiti

Codice di esempio

Creare una copia tramite fork del repository seguente in GitHub.

https://github.com/MicrosoftDocs/azure-pipelines-canary-k8s

Ecco una breve panoramica dei file nel repository usati durante questa guida:

  • ./app:
    • app.py: server Web semplice basato su Flask instrumentato tramite la libreria di strumentazione Prometheus per le applicazioni Python. Un contatore personalizzato viene configurato per il numero di risposte valide e non valide fornite, in base al valore della success_rate variabile.
    • Dockerfile : usato per compilare l'immagine con ogni modifica apportata a app.py. Con ogni modifica, la pipeline di compilazione viene attivata e l'immagine viene compilata e inserita nel registro contenitori.
  • ./manifests:
    • deployment.yml : contiene la specifica del sampleapp carico di lavoro di distribuzione corrispondente all'immagine pubblicata in precedenza. Questo file manifesto viene usato non solo per la versione stabile dell'oggetto di distribuzione, ma anche per derivare le varianti di base e canary dei carichi di lavoro.
    • service.yml : crea il sampleapp servizio. Questo servizio instrada le richieste ai pod attivati dalle distribuzioni (stabile, baseline e canary) indicate in precedenza.
  • ./Varie
    • service-monitor.yml : usato per configurare un oggetto ServiceMonitor . Questo oggetto configura lo scraping delle metriche prometheus.
    • fortio-deploy.yml : usato per configurare una distribuzione fortio. Questa distribuzione viene usata successivamente come strumento di test di carico per inviare un flusso di richieste al sampleapp servizio distribuito in precedenza. Il flusso di richieste inviate a sampleapp viene indirizzato ai pod in tutte e tre le distribuzioni (stabile, baseline e canary).

Nota

In questa guida si usa Prometheus per la strumentazione e il monitoraggio del codice. Qualsiasi soluzione equivalente, ad esempio app Azure lication Insights, può essere usata come alternativa.

Installare prometheus-operator

Per installare Prometheus nel cluster, usare il comando seguente dal computer di sviluppo. È necessario avere kubectl e Helm installato ed è necessario impostare il contesto sul cluster in cui si vuole eseguire la distribuzione. Grafana, che verrà usato in un secondo momento per visualizzare le metriche di base e canary nei dashboard, viene installato come parte di questo grafico Helm.

Si aggiungerà prima di tutto il repository Dei grafici Helm di Prometheus Community kubernetes all'installazione di Helm. Si installerà quindi lo stack kube-prometheus, una raccolta di manifesti Kubernetes, dashboard di Grafana e regole prometheus.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update # update local cache
helm install --name sampleapp  prometheus-community/kube-prometheus-stack

Creare connessioni al servizio

  1. Passare a Impostazioni progetto>Connessioni del servizio Pipeline nel>menu Azure DevOps.
  2. Creare una connessione al servizio registro Docker associata al registro contenitori. Denominarlo azure-pipelines-canary-k8s.
  3. Creare una connessione al servizio Kubernetes per il cluster Kubernetes e lo spazio dei nomi in cui si vuole eseguire la distribuzione. Denominarlo azure-pipelines-canary-k8s.

Nota

Se si usa servizio Azure Kubernetes, il tipo di connessione del servizio Azure Resource Manager è il modo migliore per connettersi a un cluster privato o a un cluster con account locali disabilitati.

Impostare l'integrazione continua

  1. Passare a Pipeline crea>pipeline e selezionare il repository.

  2. Nella scheda Configura scegliere Pipeline di avvio.

  3. Nella scheda Revisione sostituire il codice YAML della pipeline con questo codice.

    trigger:
    - main
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      imageName: azure-pipelines-canary-k8s
    
    steps:
    - task: Docker@2
      displayName: Build and push image
      inputs:
        containerRegistry: azure-pipelines-canary-k8s #replace with name of your Docker registry service connection
        repository: $(imageName)
        command: buildAndPush
        Dockerfile: app/Dockerfile
        tags: |
          $(Build.BuildId)
    

    Se la connessione al servizio del Registro di sistema Docker creata è associata a example.azurecr.io, l'immagine è example.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId), in base alla configurazione precedente.

Modificare il file manifesto

In manifests/deployment.yml sostituire <example> con l'URL del registro contenitori. Ad esempio, dopo la sostituzione, il campo immagine dovrebbe avere un aspetto simile contosodemo.azurecr.io/azure-pipelines-canary-k8sa .

Configurare la distribuzione continua

Le sezioni seguenti illustrano i passaggi per configurare la distribuzione continua, tra cui come distribuire la fase canary e come promuovere o rifiutare il canary tramite l'intervento manuale.

Distribuire la fase canary

È possibile eseguire la distribuzione con YAML o Versione classica.

  1. Passare a Ambienti>pipeline>Crea ambiente.

  2. Creare un nuovo ambiente.

    • Nome: akscanary
    • Risorsa: scegliere Kubernetes.
  3. Selezionare Avanti e configurare la risorsa Kubernetes come indicato di seguito:

    • Provider: servizio Azure Kubernetes
    • Sottoscrizione di Azure: scegliere la sottoscrizione che contiene il cluster Kubernetes.
    • Cluster: scegliere il cluster.
    • Spazio dei nomi: creare un nuovo spazio dei nomi con il nome canarydemo.
  4. Selezionare Convalida e crea.

  5. Passare a Pipeline. Selezionare la pipeline creata e selezionare Modifica.

  6. Modificare il passaggio creato in precedenza per usare ora una fase. Aggiungere altri due passaggi per copiare i manifesti e le directory misc come artefatti da usare per fasi consecutive. È anche possibile spostare un paio di valori in variabili, per semplificare l'utilizzo in un secondo momento nella pipeline. Il file YAML completo avrà ora un aspetto simile al seguente.

    trigger:
    - main
    
    pool:
      vmImage: ubuntu-latest
    
    variables:
      imageName: azure-pipelines-canary-k8s
      dockerRegistryServiceConnection: dockerRegistryServiceConnectionName #replace with name of your Docker registry service connection
      imageRepository: 'azure-pipelines-canary-k8s'
      containerRegistry: example.azurecr.io #replace with the name of your container registry, Should be in the format example.azurecr.io
      tag: '$(Build.BuildId)'
    
    stages:
    - stage: Build
      displayName: Build stage
      jobs:  
      - job: Build
        displayName: Build
        pool:
          vmImage: ubuntu-latest
        steps:
        - task: Docker@2
          displayName: Build and push image
          inputs:
            containerRegistry: $(dockerRegistryServiceConnection)
            repository: $(imageName)
            command: buildAndPush
            Dockerfile: app/Dockerfile
            tags: |
              $(tag)
    
        - publish: manifests
          artifact: manifests
    
        - publish: misc
          artifact: misc
    
  7. Aggiungere una fase alla fine del file YAML per distribuire la versione canary.

    - stage: DeployCanary
      displayName: Deploy canary
      dependsOn: Build
      condition: succeeded()
    
      jobs:
      - deployment: Deploycanary
        displayName: Deploy canary
        pool:
          vmImage: ubuntu-latest
        environment: 'akscanary.canarydemo'
        strategy:
          runOnce:
            deploy:
              steps:
              - task: KubernetesManifest@0
                displayName: Create imagePullSecret
                inputs:
                  action: createSecret
                  secretName: azure-pipelines-canary-k8s
                  dockerRegistryEndpoint: azure-pipelines-canary-k8s
    
              - task: KubernetesManifest@0
                displayName: Deploy to Kubernetes cluster
                inputs:
                  action: 'deploy'
                  strategy: 'canary'
                  percentage: '25'
                  manifests: |
                    $(Pipeline.Workspace)/manifests/deployment.yml
                    $(Pipeline.Workspace)/manifests/service.yml
                  containers: '$(containerRegistry)/$(imageRepository):$(tag)'
                  imagePullSecrets: azure-pipelines-canary-k8s
    
              - task: KubernetesManifest@0
                displayName: Deploy Forbio and ServiceMonitor
                inputs:
                  action: 'deploy'
                  manifests: |
                    $(Pipeline.Workspace)/misc/*
    
  8. Salvare la pipeline eseguendo il commit direttamente nel ramo main. Questo commit dovrebbe già eseguire correttamente la pipeline.

Intervento manuale per promuovere o rifiutare canary

È possibile intervenire manualmente con YAML o Classic.

  1. Passare a Ambienti>pipeline>Nuovo ambiente.

  2. Configurare il nuovo ambiente.

    • Nome: akspromote
    • Risorsa: scegliere Kubernetes.
  3. Selezionare Avanti e configurare la risorsa Kubernetes come indicato di seguito:

    • Provider: servizio Azure Kubernetes
    • Sottoscrizione di Azure: scegliere la sottoscrizione che contiene il cluster Kubernetes.
    • Cluster: scegliere il cluster.
    • Spazio dei nomi: scegliere lo spazio dei nomi canarydemo creato in precedenza.
  4. Selezionare Convalida e crea.

  5. Selezionare il nuovo akspromote ambiente dall'elenco degli ambienti.

  6. Selezionare Approvazioni e controlli> Approvazioni. Selezionare quindi l'icona con i puntini di sospensione (i tre puntini).

  7. Configurare l'approvazione come indicato di seguito:

    • Responsabili approvazione: aggiungere il proprio account utente.
    • Avanzate: assicurarsi che sia selezionata la casella Consenti ai responsabili approvazione di approvare le proprie esecuzioni .
  8. Seleziona Crea.

  9. Passare a Pipeline e selezionare la pipeline creata. A questo punto selezionare Edit (Modifica).

  10. Aggiungere un'altra fase, PromoteRejectCanary, alla fine del file YAML, per promuovere le modifiche.

    - stage: PromoteRejectCanary
      displayName: Promote or Reject canary
      dependsOn: DeployCanary
      condition: succeeded()
    
      jobs:
      - deployment: PromoteCanary
        displayName: Promote Canary
        pool: 
          vmImage: ubuntu-latest
        environment: 'akspromote.canarydemo'
        strategy:
          runOnce:
            deploy:
              steps:            
              - task: KubernetesManifest@0
                displayName: promote canary
                inputs:
                  action: 'promote'
                  strategy: 'canary'
                  manifests: '$(Pipeline.Workspace)/manifests/*'
                  containers: '$(containerRegistry)/$(imageRepository):$(tag)'
                  imagePullSecrets: '$(imagePullSecret)'
    
  11. Aggiungere un'altra fase, RejectCanary, alla fine del file YAML, per eseguire il rollback delle modifiche.

    - stage: RejectCanary
      displayName: Reject canary
      dependsOn: PromoteRejectCanary
      condition: failed()
    
      jobs:
      - deployment: RejectCanary
        displayName: Reject Canary
        pool: 
          vmImage: ubuntu-latest
        environment: 'akscanary.canarydemo'
        strategy:
          runOnce:
            deploy:
              steps:            
              - task: KubernetesManifest@0
                displayName: reject canary
                inputs:
                  action: 'reject'
                  strategy: 'canary'
                  manifests: '$(Pipeline.Workspace)/manifests/*'
    
  12. Salvare la pipeline YAML selezionando Salva e quindi eseguirne il commit direttamente nel ramo principale.

Distribuire una versione stabile

È possibile distribuire una versione stabile con YAML o Versione classica.

Per la prima esecuzione della pipeline la versione stabile dei carichi di lavoro e le relative versioni di base o canary non esistono nel cluster. Per distribuire la versione stabile:

  1. In app/app.py passare success_rate = 5 a success_rate = 10. Questa modifica attiva la pipeline, con conseguente compilazione e push dell'immagine nel registro contenitori. Attiverà anche la DeployCanary fase.
  2. Poiché è stata configurata un'approvazione nell'ambiente akspromote , la versione attenderà prima di eseguire tale fase.
  3. Nel riepilogo dell'esecuzione selezionare Rivedi>approvazione. In questo modo viene distribuita la versione stabile dei carichi di lavoro (la sampleapp distribuzione in manifests/deployment.yml) nello spazio dei nomi .

Avviare il flusso di lavoro canary

La versione stabile del carico di lavoro sampleapp è ora presente nel cluster. Apportare quindi la modifica seguente all'applicazione di simulazione:

In app/app.py passare success_rate = 10 a success_rate = 20.

Questa modifica attiva la pipeline di compilazione, con conseguente compilazione e push dell'immagine nel registro contenitori. Questo processo attiva a sua volta la pipeline di versione e inizia la fase Deploy canary( Distribuisci canary ).

Simulare le richieste

Nel computer di sviluppo eseguire i comandi seguenti e mantenerli in esecuzione per inviare un flusso costante di richieste al sampleapp servizio. sampleapp instrada le richieste ai pod attivati dalla distribuzione stabile sampleapp e ai pod attivati dalle sampleapp-baseline distribuzioni e sampleapp-canary . Il selettore specificato per sampleapp è applicabile a tutti questi pod.

FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
kubectl exec -it $FORTIO_POD -c fortio /usr/bin/fortio -- load -allow-initial-errors -t 0 http://sampleapp:8080/

Configurare il dashboard di Grafana

  1. Eseguire il comando di port forwarding seguente nel computer di sviluppo locale per poter accedere a Grafana.

    kubectl port-forward svc/sampleapp-grafana 3000:80
    
  2. In un browser aprire l'URL seguente.

    http://localhost:3000/login
    
  3. Quando vengono richieste le credenziali, a meno che il adminPassword valore non sia stato sottoposto a override durante l'installazione del prometheus-operator grafico Helm, è possibile usare i valori seguenti:

    • username: admin
    • password: operatore prom
  4. Scegliere Dashboard>Graph dal menu a sinistra.+>

  5. Selezionare un punto qualsiasi nel pannello appena aggiunto e digitare e per modificare il pannello.

  6. Nella scheda Metriche immettere la query seguente:

    rate(requests_total{pod=~"sampleapp-.*", custom_status="good"}[1m])
    
  7. Nella scheda Generale modificare il nome di questo pannello impostando Tutti i pod sampleapp.

  8. Nella barra di panoramica nella parte superiore della pagina modificare l'intervallo di durata in Ultimi 5 minuti o Ultimi 15 minuti.

  9. Per salvare questo pannello, selezionare l'icona Salva nella barra di panoramica.

  10. Il pannello precedente visualizza le metriche della frequenza di riuscita di tutte le varianti. Questi includono stable (dalla sampleapp distribuzione), baseline (dalla sampleapp-baseline distribuzione) e canary (dalla sampleapp-canary distribuzione). È possibile visualizzare solo le metriche di base e canary aggiungendo un altro pannello, con la configurazione seguente:

    • Nella scheda Generale, per Titolo, selezionare sampleapp baseline e canary.
    • Nella scheda Metriche usare la query seguente:
    rate(requests_total{pod=~"sampleapp-baseline-.*|sampleapp-canary-.*", custom_status="good"}[1m])
    

    Nota

    Il pannello per le metriche di base e canary includerà solo le metriche disponibili per il confronto in determinate condizioni. Queste condizioni si verificano quando la fase Deploy canary è stata completata correttamente e la fase canary Promote/reject è in attesa di intervento manuale.

    Suggerimento

    Configurare le annotazioni per i dashboard di Grafana per rappresentare visivamente gli eventi di completamento della fase per Deploy canary e Promote/reject canary. Ciò è utile in modo da sapere quando iniziare a confrontare la linea di base con il canary e quando la promozione o il rifiuto del canary è stata completata, rispettivamente.

Confrontare baseline e canary

  1. A questo punto, la fase Deploy canary è stata completata correttamente (in base alla modifica di success_rate da 10 a 20). La fase canary promote/reject è in attesa di intervento manuale. È ora possibile confrontare la percentuale di successo (come determinato da custom_status=good) delle varianti di base e canary nel dashboard di Grafana. La voce deve essere simile alla seguente:

    Screenshot that shows a comparison of baseline and canary metrics.

  2. In base all'osservazione che il tasso di successo è superiore per canary, promuovere il canary. Selezionare Riprendi nell'attività di intervento manuale.