Esercizio - Distribuire una soluzione multicontenitore in un cluster Kubernetes

Completato

La pipeline di versione fornita con il progetto è progettata per compilare la soluzione come contenitore Docker e distribuirla nel servizio app di Azure. Per supportare la distribuzione di più contenitori in un cluster Kubernetes, è necessario modificare questa pipeline.

In questa unità si apprenderà come:

  • Aggiornare la pipeline affinché si attivi in base a un commit nel ramo principale.
  • Definire le variabili da condividere nella pipeline.
  • Compilare e pubblicare le immagini Docker.
  • Pubblicare i manifesti Kubernetes.
  • Aggiungere un'attività per creare un segreto di pull dell'immagine da usare tra le istanze di Kubernetes e del registro contenitori.
  • Distribuire le immagini aggiornate in un cluster Kubernetes.

Aggiornare la pipeline per supportare i trigger

  1. Accedere all'organizzazione di Azure DevOps e passare al progetto.

  2. Selezionare Pipeline e quindi selezionare la pipeline.

  3. Selezionare Modifica per modificare azure-pipelines.yml.

    Andy: questa è la fase di compilazione che abbiamo attuato per la soluzione a contenitore singolo precedente. Sapevo che non avrebbe funzionato correttamente, pertanto l'ho disabilitata. È possibile iniziare abilitando di nuovo per i commit nel ramo main.

  4. Sostituire la riga trigger esistente riportata all'inizio del file con il frammento seguente. Viene attivata un'esecuzione della pipeline ogni volta che viene eseguito un commit nel ramo principale.

    trigger:
    - 'main'
    

Definire le variabili accessibili tra le pipeline

Andy: sarà necessario aggiungere due variabili per la pipeline. Una per specificare il nome del repository del tabellone punteggi, ovvero leaderboard. L'altra per il nome del segreto pull dell'immagine usato per la condivisione tra il servizio Azure Kubernetes e le istanze del Registro Azure Container durante la distribuzione.

  1. Aggiungere il codice evidenziato seguente alla sezione variables.

    variables:
      buildConfiguration: 'Release'
      leaderboardRepository: 'leaderboard'
      webRepository: 'web'
      tag: '$(Build.BuildId)'
      imagePullSecret: 'secret'
    

Compilare e pubblicare l'immagine Docker nel Registro Azure Container

Andy: è già presente un'attività per la compilazione dell'app Web come contenitore Docker, che viene pubblicata nel registro contenitori. È sufficiente usare una seconda attività per eseguire la stessa operazione per il tabellone punteggi in uso.

  1. Aggiungere una seconda attività Docker@2 per compilare e pubblicare il contenitore del tabellone punteggi usando il frammento evidenziato di seguito. Aggiungere questa attività subito dopo l'attività del contenitore Web.

    - task: Docker@2
      displayName: 'Build and push the web image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(webRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.Web/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    

Suggerimento

Assicurarsi che l'attività aggiunta qui usi un rientro coerente con l'attività precedente, in quanto gli spazi vuoti sono importanti in un file YAML.

Pubblicare i manifesti Kubernetes

Andy: penso che si possa passare alla fase successiva. Si nota qualche mancanza?

Mara: Si è accennato al fatto che nel progetto di origine erano presenti alcuni file manifesto che definiscono la distribuzione e i servizi necessari per Kubernetes durante la distribuzione. È consigliabile pubblicare questi dati prima di completare questa fase.

Andy: è necessario? Non saranno ancora presenti sul disco locale?

Mara: sì se dovessimo aggiungere le attività di distribuzione nell'ambito della stessa fase della compilazione. Tuttavia, poiché l'attività di distribuzione avviene nella propria fase di Distribuzione, viene eseguita in un ambiente nuovo, probabilmente anche in un agente diverso. È necessario assicurarsi di pubblicare qualsiasi elemento prodotto da questa fase che sia necessario per l'altra fase.

Andy: è un'ottima osservazione. È facile da fare? È sufficiente assicurarsi che la cartella manifests venga copiata nel nuovo agente.

Mara: è a questo che serve l'attività PublishBuildArtifacts@1. È così diffusa che esiste anche una forma abbreviata, publish.

  1. Aggiungere un'attività publish che archivi la cartella manifests per una fase futura, come illustrato di seguito. Assicurarsi che il rientro di questa attività corrisponda a quello dell'attività precedente.

    - task: Docker@2
      displayName: 'Build and push the leaderboard image to container registry'
      inputs:
        command: buildAndPush
        buildContext: $(Build.Repository.LocalPath)
        repository: $(leaderboardRepository)
        dockerfile: '$(Build.SourcesDirectory)/Tailspin.SpaceGame.LeaderboardContainer/Dockerfile'
        containerRegistry: 'Container Registry Connection'
        tags: |
          $(tag)
    
    - publish: '$(Build.SourcesDirectory)/manifests'
      artifact: manifests
    

Sostituire l'attività di distribuzione

Mara: sostituirò la fase di distribuzione esistente con una che usa un processo di distribuzione. Un processo di distribuzione è un tipo speciale di processo che consente di associare la distribuzione in questione all'ambiente Azure DevOps creato in precedenza. In questo modo è più semplice tenere traccia della cronologia delle distribuzioni, che sarà particolarmente utile via via che le soluzioni diventeranno più sofisticate.

  1. Rimuovere la fase di distribuzione esistente (tutti gli elementi dopo la fase di compilazione) e sostituirla con il frammento seguente. Prendere nota della riga evidenziata che indica l'ambiente di distribuzione da usare.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'Dev'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
    

    Mara: il primo passaggio che verrà aggiunto nella fase di distribuzione consiste in scaricare gli artefatti del manifesto pubblicati in precedenza usando l'attività DownloadBuildArtifacts@0.

    Andy: immagino che esista una forma abbreviata download per l'attività.

    Mara: esatto! È possibile usare l'identificatore current per specificare che si vuole usare l'artefatto dell'esecuzione corrente della pipeline.

  2. Aggiungere le righe evidenziate come primo passaggio della fase di distribuzione.

    - stage: 'Deploy'
      displayName: 'Deploy the containers'
      dependsOn: Build
      jobs:
      - deployment: Deploy
        displayName: Deploy
        pool:
          vmImage: 'ubuntu-20.04'
        environment: 'spike.default'
        variables:
        - group: Release
        strategy:
          runOnce:
            deploy:
              steps:
              - download: current
                artifact: manifests
    

    Andy: a questo punto è necessario creare un segreto di pull dell'immagine che verrà condiviso tra le istanze del Registro Azure Container e del servizio Azure Kubernetes. Sai se è presente un'attività che è possibile usare?

    Mara: la stavo proprio cercando e siamo fortunati. L'attività KubernetesManifest@0 supporta un'azione per creare il segreto necessario.

Attività del manifesto Kubernetes

L'attività relativa ai manifesti Kubernetes è progettata per gestire tutte le operazioni di distribuzione mainstream necessarie per Kubernetes. Tale attività supporta più opzioni action che vanno dalla creazione di segreti alla distribuzione di immagini. In questo caso, viene usata l'azione createSecret insieme ai parametri seguenti:

  • action indica la funzionalità da eseguire. In questo caso, createSecret crea il segreto condiviso.
  • connectionType specifica il tipo di connessione al servizio da usare. Opzioni: azureResourceManager o kubernetesServiceConnection.
  • secretName specifica il nome del segreto da creare.
  • dockerRegistryEndpoint specifica il nome della connessione ai servizi Registro Azure Container.
  • azureSubscriptionConnection specifica il nome della connessione ai servizi ARM.
  • azureResourceGroup specifica il nome del gruppo di risorse.
  • kubernetesCluster specifica il nome del cluster del servizio Azure Kubernetes.
  • namespace specifica lo spazio dei nomi del servizio Kubernetes a cui si applica questa azione.
  1. Aggiungere il frammento seguente alla fine della pipeline. Assicurarsi che sia il nome del gruppo di risorse che il nome del cluster corrispondano ai nomi di quelli creati in precedenza. Assicurarsi che il rientro di questa attività corrisponda a quello dell'attività di download.

    - task: KubernetesManifest@1
      displayName: Create imagePullSecret
      inputs:
        action: createSecret
        connectionType: azureResourceManager
        secretName: $(imagePullSecret)
        dockerRegistryEndpoint: 'Container Registry Connection'
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
    

    Andy: il passaggio finale consiste nell'attivare la distribuzione delle immagini nel cluster Kubernetes. In base alla documentazione, sembra che sia possibile usare la stessa attività, ma con un'azione e parametri diversi.

    • action indica la funzionalità da eseguire. In questo caso, deploy per la distribuzione nel cluster del servizio Azure Kubernetes.
    • connectionType specifica il tipo di connessione al servizio da usare. Opzioni: azureResourceManager o kubernetesServiceConnection.
    • azureSubscriptionConnection specifica il nome della connessione ai servizi ARM.
    • azureResourceGroup specifica il nome del gruppo di risorse.
    • kubernetesCluster specifica il nome del cluster del servizio Azure Kubernetes.
    • namespace specifica lo spazio dei nomi del servizio Kubernetes a cui si applica questa azione.
    • imagePullSecrets specifica l'elenco di segreti necessari per eseguire il pull dal registro contenitori.
    • containers specifica l'elenco di immagini del contenitore da distribuire.
  2. Aggiungere il frammento seguente alla fine della pipeline. Assicurarsi che sia il nome del gruppo di risorse che il nome del cluster corrispondano ai nomi di quelli creati in precedenza. Assicurarsi che il rientro di questa attività corrisponda a quello dell'attività precedente.

    - task: KubernetesManifest@1
      displayName: Deploy to Kubernetes cluster
      inputs:
        action: deploy
        connectionType: azureResourceManager
        azureSubscriptionConnection: 'Kubernetes Cluster Connection'
        azureResourceGroup: 'tailspin-space-game-rg'
        kubernetesCluster: 'tailspinspacegame-24591'
        namespace: 'default'
        manifests: |
          $(Pipeline.Workspace)/manifests/deployment.yml
          $(Pipeline.Workspace)/manifests/service.yml
        imagePullSecrets: |
          $(imagePullSecret)
        containers: |
          $(RegistryName)/$(webRepository):$(tag)
          $(RegistryName)/$(leaderboardRepository):$(tag)
    

Eseguire la pipeline

  1. Selezionare Salva nell'angolo in alto a destra della pagina. Selezionare Salva per confermare il messaggio di commit.

  2. Selezionare Esegui, confermare il nome del ramo e quindi selezionare Esegui per attivare un'esecuzione della pipeline.

  3. Selezionare Pipeline e quindi selezionare la pipeline per visualizzare i log durante l'esecuzione della pipeline.

  4. Al termine dell'esecuzione della pipeline, selezionare Ambienti nel riquadro sinistro e quindi selezionare l'ambiente di sviluppo per visualizzare i processi di distribuzione.

  5. A questo punto, è necessario verificare l'app Web distribuita e l'endpoint API. A tale scopo, occorre recuperare gli indirizzi IP esterni sia per i servizi Web che per i servizi del tabellone punteggi.

  6. Passare al portale di Azure, selezionare il cluster del servizio Azure Kubernetes e quindi Servizi e risorse in ingresso.

    Screenshot of how to find the external IPs for your web and leaderboard services.

  7. Selezionare l'Indirizzo IP esterno per il servizio Web per visualizzare il sito nel servizio Azure Kubernetes.

    Screenshot of the Space Game web site.

  8. Tornare alla finestra del portale di Azure in cui ci si trovava in precedenza e quindi copiare l'Indirizzo IP esterno per il servizio tabellone punteggi. Questo indirizzo IP è quello in cui è ospitata pubblicamente l'API del tabellone punteggi.

  9. Sostituire il segnaposto nel collegamento seguente con l'indirizzo IP esterno copiato. È anche possibile aggiungere un parametro di query pageSize=10 per semplificare la visualizzazione della risposta JSON nel browser. Usare un URL simile a quello riportato di seguito in una nuova scheda del browser.

    http://[IP]/api/Leaderboard?pageSize=10
    
  10. Viene visualizzata la risposta JSON non elaborata dall'API tabellone punteggi ospitata nel cluster del servizio Azure Kubernetes. È ora disponibile un'API REST che è possibile chiamare da altre applicazioni.

    Screenshot of a web browser showing the JSON response from the leaderboard service.

Andy: È un ottimo risultato! L'uso di Kubernetes sarebbe un ottimo modo per adottare una strategia di microservizi più ampia.