Share via


教學課程:針對 Kubernetes 部署使用 Canary 部署策略

Azure DevOps Services |Azure DevOps Server 2022

Canary 部署策略表示在穩定且生產版本旁邊部署新版本的應用程式。 然後,您可以查看 Canary 版本與基準的比較方式,再升級或拒絕部署。

本逐步指南涵蓋如何使用 Kubernetes 指令清單工作的 Canary 策略。 具體而言,您將瞭解如何設定 Kubernetes 的 Canary 部署,以及評估程式代碼的相關工作流程。 然後,您可以使用該程式碼來比較基準和 Canary 應用程式部署,以便決定是否要升級或拒絕 Canary 部署。

如果您使用 Azure Kubernetes Service,Azure Resource Manager 服務連線類型是連線到私人叢集或已停用本機帳戶的叢集的最佳方式。

必要條件

範例指令碼

在 GitHub 上派生下列存放庫。

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

以下是本指南期間所使用存放庫中檔案的簡短概觀:

  • ./app
    • app.py - 使用適用於 Python 應用程式的 Prometheus 檢測連結庫進行檢測的簡單 Flask 型網頁伺服器。 根據變數的值 success_rate ,會設定自定義計數器,以指定之良好和不正確的回應數目。
    • Dockerfile - 用於建置映射,並針對每個 變更 app.py。 每次變更時,都會觸發組建管線,並將映像建置並推送至容器登錄。
  • ./manifests
    • deployment.yml - 包含對應至稍早發行映像的 sampleapp 部署工作負載規格。 您不只針對穩定版本的部署物件使用此指令清單檔,也用於衍生工作負載的基準和 Canary 變體。
    • service.yml - 建立 sampleapp 服務。 此服務會將要求路由傳送至先前所述的部署(穩定、基準和 Canary)所啟動的 Pod。
  • 。/雜項
    • service-monitor.yml - 用來設定 ServiceMonitor 物件。 此物件會設定 Prometheus 計量抓取。
    • fortio-deploy.yml - 用來設定 fortio 部署。 此部署稍後會用來作為負載測試工具,以將要求串流傳送至 sampleapp 稍早部署的服務。 傳送至 sampleapp 的要求數據流會路由傳送至這三個部署下的Pod(穩定、基準和 Canary)。

注意

在本指南中,您會使用 Prometheus 進行程式代碼檢測和監視。 任何對等的解決方案,例如 Azure 應用程式 Insights,都可以做為替代方案。

安裝 prometheus-operator

若要在叢集上安裝 Prometheus,請使用您開發電腦上的下列命令。 您必須安裝 kubectl 和 Helm,而且您必須將內容設定為您想要部署的叢集。 您稍後用來可視化儀錶板上的基準和 Canary 計量的 Grafana 會安裝為此 Helm 圖表的一部分。

您必須先將 Prometheus Community Kubernetes Helm Chart 存放庫新增至 Helm 安裝。 然後,您將安裝 kube-prometheus 堆棧、Kubernetes 指令清單集合、Grafana 儀錶板和 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

建立服務連線

  1. 移至 Azure DevOps 功能表中的>[項目設定>管線服務連線]。
  2. 建立 與您的容器登錄相關聯的 Docker 登錄服務連線 。 將它命名為 azure-pipelines-canary-k8s
  3. 為您想要部署的 Kubernetes 叢集和命名空間建立 Kubernetes 服務連線 。 將它命名為 azure-pipelines-canary-k8s

注意

如果您使用 Azure Kubernetes Service,Azure Resource Manager 服務連線類型 是連線到私人叢集或已停用本機帳戶的叢集的最佳方式。

設定持續整合

  1. 移至 [管線建立管線>],然後選取您的存放庫。

  2. 在 [ 設定] 索引標籤上,選擇 [ 入門管線]。

  3. 在 [ 檢閱] 索引標籤上,以此程式代碼取代管線 YAML。

    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)
    

    如果您建立的 Docker 登入服務連線與 example.azurecr.io相關聯,則映像會根據上述組態對 example.azurecr.io/azure-pipelines-canary-k8s:$(Build.BuildId)

編輯指令清單檔案

manifests/deployment.yml 中,以容器登錄的 URL 取代 <example> 。 例如,取代之後,影像欄位看起來應該像 contosodemo.azurecr.io/azure-pipelines-canary-k8s

設定持續部署

下列各節提供設定持續部署的步驟,包括如何部署 Canary 階段,以及如何透過手動介入來升級或拒絕 Canary。

部署 Canary 階段

您可以使用 YAML 或傳統部署。

  1. 移至 [管線>環境建立環境>]。

  2. 建立 [新增環境]。

    • 名稱akscanary
    • 資源:選擇 [Kubernetes]。
  3. 選取 [下一步],然後設定 Kubernetes 資源,如下所示:

    • 提供者:Azure Kubernetes Service
    • Azure 訂用帳戶:選擇保留 Kubernetes 叢集的訂用帳戶。
    • 叢集:選擇您的叢集。
    • 命名空間:使用 canarydemo 名稱建立新的命名空間。
  4. 選取 [ 驗證並建立]。

  5. 前往 [管線]。 選取您建立的管線,然後選取 [ 編輯]。

  6. 將您先前建立的步驟變更為現在使用階段。 再新增兩個步驟,將指令清單和 misc 目錄複製為成品,以供連續階段使用。 您可能也想要將幾個值移至變數,以便稍後在管線中使用。 您的完整 YAML 現在看起來應該像這樣。

    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. 在 YAML 檔案結尾新增階段,以部署 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. 直接認可至 main 分支,以儲存您的管線。 此認可應該已經順利執行您的管線。

手動干預促進或拒絕 Canary

您可以使用 YAML 或傳統手動介入。

  1. 移至 [管線>環境>] [新增環境]。

  2. 設定新的環境。

    • 名稱akspromote
    • 資源:選擇 [Kubernetes]。
  3. 選取 [下一步],然後設定 Kubernetes 資源,如下所示:

    • 提供者:Azure Kubernetes Service
    • Azure 訂用帳戶:選擇保留 Kubernetes 叢集的訂用帳戶。
    • 叢集:選擇您的叢集。
    • 命名空間:選擇您稍早建立的命名空間 Canarydemo
  4. 選取 [ 驗證並建立]。

  5. 從環境清單中選取您的新 akspromote 環境。

  6. 選取 [核准 並檢查> 核准。 然後選取省略號圖示 (三個點)。

  7. 設定您的核准,如下所示:

    • 核准者:新增您自己的用戶帳戶。
    • 進階:確定已選取 [ 允許核准者核准自己的執行 ] 方塊。
  8. 選取 建立

  9. 移至 [管線],然後選取您建立的管線。 然後選取 [ 編輯]。

  10. 在 YAML 檔案結尾新增另一個階段 PromoteRejectCanary,以升級變更。

    - 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. 在 YAML 檔案結尾新增另一個階段 RejectCanary,以回復變更。

    - 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. 選取 [ 儲存],然後直接將 YAML 管線認可至主要分支,以儲存您的 YAML 管線。

部署穩定版本

您可以使用 YAML 或傳統部署穩定版本。

針對管線的第一次執行,工作負載的穩定版本,且其基準或 Canary 版本不存在於叢集中。 若要部署穩定版本:

  1. app/app.py 中,將 變更 success_rate = 5success_rate = 10。 這項變更會觸發管線,導致映像的建置和推送至容器登錄。 它也會觸發 DeployCanary 階段。
  2. 因為您已在環境上 akspromote 設定核准,發行會先等候再執行該階段。
  3. 在回合的摘要中,選取 [檢閱>核准]。 這會將穩定版本的工作負載(sampleappmanifests/deployment.yml 中的部署)部署到 命名空間。

起始 Canary 工作流程

工作負載的 sampleapp 穩定版本現在存在於叢集中。 接下來,對模擬應用程式進行下列變更:

app/app.py 中,將 變更 success_rate = 10success_rate = 20

這項變更會觸發組建管線,導致映像建置和推送至容器登錄。 此程式接著會觸發發行管線,並開始 部署 Canary 階段。

模擬要求

在您的開發計算機上,執行下列命令,並讓它繼續執行,以在服務傳送 sampleapp 一串固定的要求。 sampleapp將要求路由傳送至穩定sampleapp部署的 Pod,並將 要求路由傳送至 和 sampleapp-canary 部署所sampleapp-baseline啟動的 Pod。 針對 sampleapp 指定的選取器適用於所有 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/

設定 Grafana 儀錶板

  1. 在您的本機開發計算機上執行下列埠轉送命令,以存取 Grafana。

    kubectl port-forward svc/sampleapp-grafana 3000:80
    
  2. 在瀏覽器中,開啟下列URL。

    http://localhost:3000/login
    
  3. 當系統提示您輸入認證時,除非 adminPassword 在 Helm 圖表安裝期間 prometheus-operator 覆寫值,否則您可以使用下列值:

    • username:admin
    • password:prom-operator
  4. 從左側功能表中,選擇 +>[儀錶板>圖表]。

  5. 選取新新增面板上的任何位置,然後輸入 e 以編輯面板。

  6. 在 [ 計量] 索引標籤上 ,輸入下列查詢:

    rate(requests_total{pod=~"sampleapp-.*", custom_status="good"}[1m])
    
  7. 在 [ 一般] 索引標籤上,將此面板的名稱變更為 [所有範例] 應用程式 Pod

  8. 在頁面頂端的概觀列中,將持續時間範圍變更為 [過去 5 分鐘 ] 或 [過去 15 分鐘]。

  9. 若要儲存此面板,請選取概觀列中的儲存圖示。

  10. 上述面板會將來自所有變體的成功率計量可視化。 其中包括穩定(從部署)、基準(從sampleappsampleapp-baseline部署),以及 Canary(從sampleapp-canary部署)。 您可以藉由新增另一個面板,使用下列組態,只可視化基準和 Canary 計量:

    • 在 [一般] 索引標籤的 [標題] 中,選取 sampleapp 比較基準和 Canary
    • 在 [ 計量] 索引標籤上 ,使用下列查詢:
    rate(requests_total{pod=~"sampleapp-baseline-.*|sampleapp-canary-.*", custom_status="good"}[1m])
    

    注意

    基準和 Canary 計量的面板只會在特定條件下有可供比較的計量。 這些條件是在 部署 Canary 階段成功完成時,且 升級/拒絕 Canary 階段正在等候手動介入。

    提示

    設定 Grafana 儀錶板的註釋,以可視化方式描述部署 Canary升級/拒絕 Canary階段完成事件。 這很有説明,讓您知道何時開始比較基準與 Canary,以及 Canary 的升階或拒絕分別完成的時間。

比較基準和 Canary

  1. 此時,部署 Canary 階段已順利完成(根據 從 10 變更success_rate20)。 升階/拒絕 Canary 階段正在等候手動介入。 您現在可以比較 Grafana 儀錶板中基準和 Canary 變體的成功率(由 所 custom_status=good決定)。 看起來應類似下列範例:

    Screenshot that shows a comparison of baseline and canary metrics.

  2. 根據對 Canary 的成功率較高的觀察,升階 Canary。 在手動介入工作中選取 [ 繼續 ]。