練習 - 將多容器解決方案部署至 Kubernetes 叢集

已完成

專案所提供的發行管線是設計來建置解決方案作為 Docker 容器,並將其部署至 Azure App Service。 若要支援將多個容器部署到 Kubernetes 叢集,您需要修改此管線。

在本單元中,您將學習如何:

  • 更新管線以在對主要分支認可時觸發。
  • 定義要跨管線共用的變數。
  • 建置和發佈 Docker 映射。
  • 發佈 Kubernetes 設定檔。
  • 新增一項任務以建立影像擷取密鑰,在 Kubernetes 和容器註冊表實例之間使用。
  • 將更新的映像部署至 Kubernetes 叢集。

更新管線以支援觸發程序

  1. 登入您的 Azure DevOps 組織,然後流覽至您的專案。

  2. 選取 [管線],然後選取管線。

  3. 選取 [編輯 ] 以編輯 您的azure-pipelines.yml

    安 迪: 這是我們先前單一容器解決方案的建置階段。 我知道它不會正常運行, 所以我停用了它。 我們可以透過認可至 main 分支重新啟用觸發程序來開始。

  4. 以下列代碼段取代檔案頂端的現有 trigger 行。 這會在每次認可至主分支時觸發管線執行。

    trigger:
    - 'main'
    

定義可跨管線存取的變數

安 迪: 我們需要新增兩個管線變數。 其中一個用於指定排行榜存放庫的名稱,也就是 排行榜。 另一個是部署期間用於在 AKS 和 ACR 執行個體之間共用的映像提取密碼名稱。

  1. 將下列醒目提示的程式代碼新增至 variables 區段。

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

建置 Docker 映射並將其發佈至 Azure Container Registry

安 迪: 我們已經有將 Web 應用程式建置為 Docker 容器的工作,我們會發布至容器登錄。 我們可以只使用第二個工作來對我們的排行榜執行相同的工作。

  1. 新增第二 Docker@2 個工作,以使用下列醒目提示的代碼段來建置和發佈排行榜容器。 在 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)
    

小提示

請確定您在此處新增的工作會使用與上一個工作的一致縮排,因為空格符在YAML檔案中很重要。

發佈 Kubernetes 資訊清單

安 迪: 我認為我們可以繼續進入下一個階段。 你看到任何遺漏的東西嗎?

瑪拉: 您提到來源專案中有一些指令清單檔可定義部署,以及我們部署時 Kubernetes 所需的服務。 我們應該在完成這個階段之前發佈這些檔案。

安 迪: 我們需要嗎? 它們是否仍在本機磁碟上?

Mara:如果我們是在與建置的相同階段內新增部署工作,它們就會在本機磁碟上。 不過,由於我們的部署工作會在自己的 部署 階段執行,所以它會在全新的環境中執行,甚至可能在不同的代理程式上執行。 我們一定要發佈這個階段所產生、其他階段需要的任何成果。

安 迪: 這是一個很好的觀點。 很容易做到嗎? 我們只需確保 清單檔 資料夾已複製到新的代理程式。

Mara:這就是 PublishBuildArtifacts@1 任務用途。 它很常見,它甚至可以使用簡寫 publish

  1. 新增publish工作,儲存後續階段的manifests資料夾,如下列程式碼片段所示。 請確定此工作的縮排符合上一個工作的縮排。

    - 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
    

取代部署階段

Mara:我要將現有的部署階段取代為使用部署工作的階段。 部署作業是一種特殊的作業,可讓我們將部署與稍早建立的 Azure DevOps 環境產生關聯。 這可讓您更輕鬆地追蹤部署歷程記錄,這在解決方案變得更複雜時特別有用。

  1. 拿掉現有的 部署 階段(建置階段之後的所有專案),並將它取代為下列代碼段。 記下指出要使用的部署環境的醒目提示行。

    - 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:我們將在部署階段新增的第一個步驟是,使用 DownloadBuildArtifacts@0 工作來下載稍早發佈的資訊清單構件。

    安迪: 讓我猜,這項工作有download 簡便方法嗎?

    瑪拉: 完全正確! 我們可以使用 current 指定子來指出我們想要來自管線目前執行的成品。

  2. 將醒目提示的行新增為 部署 階段的第一個步驟。

    - 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
    

    安迪: 現在,我們需要建立一個映像拉取密鑰,以便在 ACR 和 AKS 實例之間共用。 您知道是否有可以使用的任務嗎?

    瑪拉: 我剛查了一下,我們運氣真好。 KubernetesManifest@0 工作可支援建立所需密碼的動作。

Kubernetes 資訊清單工作

Kubernetes 配置檔案任務的設計目的是管理 Kubernetes 所需的所有主流部署作業。 它支援多種 action 選項,範圍從建立秘密到部署映像。 在此情況下,會使用 createSecret 動作及下列參數:

  • action 表示要執行的功能。 在此情況下, createSecret 會建立共享密碼。
  • connectionType 指定要使用的服務連線類型。 選項: azureResourceManagerkubernetesServiceConnection
  • secretName 指定要建立的秘密名稱。
  • dockerRegistryEndpoint 指定 Azure Container Registry Services 連線的名稱。
  • azureSubscriptionConnection 指定 ARM 服務連線的名稱。
  • azureResourceGroup 指定資源群組的名稱。
  • kubernetesCluster 會指定 AKS 叢集的名稱。
  • namespace 指定套用此動作的 Kubernetes 命名空間。
  1. 將下列程式碼片段新增至您管線的結尾。 請確定資源組名和叢集名稱都符合您稍早建立的名稱。 請確保此工作的縮排與下載工作的縮排一致。

    - 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'
    

    安 迪: 最後一個步驟是觸發映射部署至 Kubernetes 叢集。 根據文件,看來我們可以使用相同的任務,但採用不同的動作和參數。

    • action 表示要執行的功能。 在此情況下,deploy 用於部署至 AKS 叢集。
    • connectionType 指定要使用的服務連線類型。 選項: azureResourceManagerkubernetesServiceConnection
    • azureSubscriptionConnection 指定 ARM 服務連線的名稱。
    • azureResourceGroup 指定資源群組的名稱。
    • kubernetesCluster 會指定 AKS 叢集的名稱。
    • namespace 指定套用此動作的 Kubernetes 命名空間。
    • imagePullSecrets 指定從容器登錄提取所需的秘密清單。
    • containers 指定要部署的容器映像清單。
  2. 將下列程式碼片段添加到管線結尾。 請確定資源組名和叢集名稱都符合您稍早建立的名稱。 請確定此工作的縮排符合上一個工作的縮排。

    - 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)
    

執行您的管線

  1. 從頁面右上角選取 [ 儲存 ]。 選取 [儲存] 以確認您的認可訊息。

  2. 選取 [執行]、確認您的分支名稱,然後選取 [執行] 以觸發管線執行。

  3. 選取 [管線],然後選取您的管線,以在管線執行時檢視記錄。

  4. 管線執行完成之後,請從左窗格中選取 [ 環境 ],然後選取 [開發 環境] 以檢視您的部署作業。

  5. 現在讓我們看看我們部署的 Web 應用程式和 API 端點。 若要這樣做,我們需要取得 Web排行榜 服務的外部 IP 位址。

  6. 流覽至 Azure 入口網站,選取您的 AKS 叢集,然後選取 [服務和輸入]。

    如何為您的 Web 和排行榜服務尋找外部 IP 的螢幕快照。

  7. 選取 Web 服務的外部 IP,以在 AKS 上檢視您的網站。

    Space Game 網站的螢幕快照。

  8. 返回至您離開的 Azure 入口網站視窗,然後複製 leaderboard 服務的 [外部 IP]。 此IP位址是排行榜 API 公開裝載的位置。

  9. 將下列連結中的預留位置取代為您複製的外部 IP。 您也可以新增 pageSize=10 查詢參數,讓您更輕鬆地在瀏覽器中檢視 JSON 回應。 在新的瀏覽器索引標籤中使用如下的 URL。

    http://[IP]/api/Leaderboard?pageSize=10
    
  10. 您可以從 AKS 叢集中裝載的排行榜 API 檢視原始 JSON 回應。 您現在有可從其他應用程式呼叫的 REST API。

    網頁瀏覽器的螢幕快照,其中顯示排行榜服務的 JSON 回應。

安 迪: 結果很棒! 我認為使用 Kubernetes 是採用更廣泛微服務策略的絕佳方式。