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

已完成

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

在本課程模組中,您將了解如何:

  • 更新管線以在對主要分支認可時觸發。
  • 定義要在管線之間共用的變數。
  • 建置和發佈 Docker 映像。
  • 發佈 Kubernetes 資訊清單。
  • 新增工作以建立映像提取密碼,以便在您的 Kubernetes 和容器登錄執行個體之間使用。
  • 將更新的映像部署至 Kubernetes 叢集。

更新管線以支援觸發程序

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

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

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

    Andy:這是我們既有、用於先前的單一容器解決方案的建置階段。 我知道它無法正常執行,所以我已將它停用。 我們可以透過認可至 main 分支重新啟用觸發程序來開始。

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

    trigger:
    - 'main'
    

定義可跨管線存取的變數

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

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

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

建置並將 Docker 映像發佈到 Azure Container Registry

Andy:我們已經有工作可將 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 資訊清單

Andy:我想我們可以繼續進行下一個階段。 你有發現少了任何項目嗎?

Mara:您剛提到來源專案中有一些資訊清單檔案,會定義部署時 Kubernetes 將需要的部署和服務。 我們應該在完成這個階段之前發佈這些檔案。

Andy:我們需要嗎? 它們不是仍會在本機磁碟上?

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

Andy:這點很棒。 要這麼做簡單嗎? 我們只需要確保將 manifests 資料夾複製到新代理程式。

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 工作來下載稍早發佈的資訊清單構件。

    Andy:讓我猜猜,該工作是否有 download 簡寫?

    Mara:完全正確! 我們可以使用 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
    

    Andy:現在,我們需要建立將在 ACR 和 AKS 執行個體之間共用的映像提取密碼。 你知道有沒有我們可以使用的工作嗎?

    Mara:我剛剛查了一下,我們很幸運。 KubernetesManifest@0 工作可支援建立所需密碼的動作。

Kubernetes 資訊清單工作

Kubernetes 資訊清單工作的設計目的是要管理 Kubernetes 所需的所有主流部署作業。 它支援多個 action 選項,範圍從建立密碼到部署映像。 在此情況下,會使用 createSecret 動作以及下列參數:

  • action 指出要執行的功能。 在此情況下,createSecret 會建立共用密碼。
  • connectionType 會指定要使用的服務連線類型。 選項:azureResourceManagerkubernetesServiceConnection
  • secretName 會指定要建立的密碼的名稱。
  • dockerRegistryEndpoint 會指定 Azure Container Registry Service 連線的名稱。
  • 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'
    

    Andy:最後一個步驟是觸發將我們的映像部署至 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 端點。 若要這樣做,我們必須取得 webleaderboard 服務的外部 IP 位址。

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

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

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

    Screenshot of the Space Game web site.

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

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

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

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

Andy:太棒了! 我認為使用 Kubernetes 是我們採用更廣泛微服務策略的絕佳方法。