練習 - 將多容器解決方案部署至 Kubernetes 叢集
您專案所提供的發行管線是設計成建置解決方案作為 Docker 容器,並將其部署至 Azure App Service。 若要支援將多個容器部署至 Kubernetes 叢集,您必須修改此管線。
在本課程模組中,您將了解如何:
- 更新管線以在對主要分支認可時觸發。
- 定義要在管線之間共用的變數。
- 建置和發佈 Docker 映像。
- 發佈 Kubernetes 資訊清單。
- 新增工作以建立映像提取密碼,以便在您的 Kubernetes 和容器登錄執行個體之間使用。
- 將更新的映像部署至 Kubernetes 叢集。
更新管線以支援觸發程序
登入您的 Azure DevOps 組織,然後瀏覽至您的專案。
選取 [管線],然後選取您的管線。
選取 [編輯] 以編輯您的 azure-pipelines.yml。
Andy:這是我們既有、用於先前的單一容器解決方案的建置階段。 我知道它無法正常執行,所以我已將它停用。 我們可以透過認可至
main
分支重新啟用觸發程序來開始。將檔案頂端的現有
trigger
行取代為下列程式碼片段。 這會在每次認可至主分支時觸發管線執行。trigger: - 'main'
定義可跨管線存取的變數
Andy:我們必須新增兩個管線變數。 其中一個用於指定排行榜存放庫的名稱,也就是 leaderboard。 另一個是部署期間用於在 AKS 和 ACR 執行個體之間共用的映像提取密碼名稱。
將下列醒目提示的程式碼新增至
variables
區段。variables: buildConfiguration: 'Release' leaderboardRepository: 'leaderboard' webRepository: 'web' tag: '$(Build.BuildId)' imagePullSecret: 'secret'
建置並將 Docker 映像發佈到 Azure Container Registry
Andy:我們已經有工作可將 Web 應用程式建置為 Docker 容器,然後會將該容器發佈至容器登錄。 我們可以只使用第二個工作來對我們的排行榜執行相同的工作。
使用以下醒目提示的程式碼片段,來新增建置和發佈排行榜容器的第二個
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
。
新增
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 環境產生關聯。 這可讓您更輕鬆地追蹤部署歷程,隨著我們的解決方案變得更複雜時特別有用。
移除現有的部署階段 (建置階段之後的所有項目),並將其取代為下列程式碼片段。 記下指出要使用的部署環境的反白顯示行。
- 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
指定子來指出我們想要來自管線目前執行的成品。將醒目提示的行新增為部署階段的第一個步驟。
- 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
會指定要使用的服務連線類型。 選項:azureResourceManager 或 kubernetesServiceConnection。secretName
會指定要建立的密碼的名稱。dockerRegistryEndpoint
會指定 Azure Container Registry Service 連線的名稱。azureSubscriptionConnection
會指定 ARM 服務連線的名稱。azureResourceGroup
會指定您資源群組的名稱。kubernetesCluster
會指定您 AKS 叢集的名稱。namespace
會指定此動作適用的 Kubernetes 命名空間。
將下列程式碼片段新增至您管線的結尾。 請確定資源群組名稱和叢集名稱都符合您稍早建立的名稱。 請確定此工作的縮排符合 [下載] 工作的縮排。
- 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
會指定要使用的服務連線類型。 選項:azureResourceManager 或 kubernetesServiceConnection。azureSubscriptionConnection
會指定 ARM 服務連線的名稱。azureResourceGroup
會指定您資源群組的名稱。kubernetesCluster
會指定您 AKS 叢集的名稱。namespace
會指定此動作適用的 Kubernetes 命名空間。imagePullSecrets
會指定需要從容器登錄提取的密碼清單。containers
會指定要部署的容器映像的清單。
將下列程式碼片段新增至管線的結尾。 請確定資源群組名稱和叢集名稱都符合您稍早建立的名稱。 請確定此工作的縮排符合上一個工作的縮排。
- 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)
執行您的管線
選取頁面右上角的 [儲存]。 選取 [儲存] 以確認您的認可訊息。
選取 [執行]、確認您的分支名稱,然後選取 [執行] 以觸發管線執行。
選取 [管線],然後選取您的管線,以在管線執行時檢視記錄。
管線執行完成後,請從左窗格中選取 [環境],然後選取 [開發] 環境以檢視您的部署工作。
現在讓我們看看我們部署的 Web 應用程式和 API 端點。 若要這樣做,我們必須取得 web 和 leaderboard 服務的外部 IP 位址。
瀏覽至 Azure 入口網站、選取您的 AKS 叢集,然後選取 [服務和輸入]。
選取 web 服務的 [外部 IP],以在 AKS 上檢視您的網站。
返回至您離開的 Azure 入口網站視窗,然後複製 leaderboard 服務的 [外部 IP]。 此 IP 位址是公開裝載排行榜 API 的位置。
將下列連結中的預留位置取代為您複製的外部 IP。 您也可以新增
pageSize=10
查詢參數,讓您更輕鬆地在瀏覽器中檢視 JSON 回應。 在新的瀏覽器索引標籤中使用如下的 URL。http://[IP]/api/Leaderboard?pageSize=10
您可以檢視來自 AKS 叢集中所裝載排行榜 API 的原始 JSON 回應。 您現在有可從其他應用程式呼叫的 REST API。
Andy:太棒了! 我認為使用 Kubernetes 是我們採用更廣泛微服務策略的絕佳方法。