環境 - Kubernetes 資源

Azure DevOps Services |Azure DevOps Server 2022 |Azure DevOps Server 2020

Kubernetes 資源檢視會顯示對應至資源之命名空間中物件的狀態。 資源檢視也會重疊管線可追蹤性,以便從 Kubernetes 對象追蹤回管線,然後回到認可。

使用 Kubernetes 資源在環境中以 Kubernetes 叢集為目標進行部署。 使用管線從任何其他雲端提供者部署至 Azure Kubernetes Service (AKS) 和叢集。

您可以搭配公用或私人叢集使用 Kubernetes 資源。 若要深入瞭解資源的運作方式,請參閱 YAML 中的資源與 資源的安全性。

概觀

請參閱在環境中使用 Kubernetes 資源檢視的下列優點:

  • 管線可追蹤性 - 用於部署的 Kubernetes 指令清單工作會新增更多註釋,以顯示資源檢視中的管線可追蹤性。 管線可追蹤性有助於識別原始的 Azure DevOps 組織、專案和管線,負責對命名空間內物件進行更新。

    Pipeline traceability

  • 診斷資源健康情況 - 工作負載狀態對於快速偵錯新部署所引進的錯誤或回歸很有用。 例如,針對未設定的 imagePullSecrets 導致 ImagePullBackOff 錯誤,Pod 狀態資訊可協助您識別問題的根本原因。

    ImagePullBackOff

  • 檢閱應用程式 - 檢閱應用程式 的運作方式是將 Git 存放庫的每個提取要求部署到環境中的動態 Kubernetes 資源。 檢閱者可以在這些變更合併至目標分支並部署到生產環境之前,先查看這些變更的外觀,並與其他相依服務搭配運作。

使用 Azure Kubernetes Service

當您使用 Azure Kubernetes Service (AKS) 時,會在您選擇的叢集和命名空間中建立 ServiceAccount針對已啟用 Kubernetes RBAC 的叢集,RoleBinding 也會建立,以將已建立的服務帳戶範圍限製為所選的命名空間。 針對已停用 Kubernetes RBAC 的叢集,建立的 ServiceAccount 具有全叢集許可權(跨命名空間)。

新增 AKS Kubernetes 資源

  1. 在 [環境詳細數據] 頁面中,選取 [新增資源 ],然後選擇 [Kubernetes]。

  2. 在 [提供者] 下拉式列表中選取 [Azure Kubernetes Service ]。

  3. 選擇 Azure 訂用帳戶、叢集和命名空間 (new/existing)。

  4. 選取 [驗證並建立 ] 以建立 Kubernetes 資源。

  5. 確認您看到環境的叢集。 如果您尚未將程式代碼部署到叢集,您將會看到「從未部署」文字。

    Add a Kubernetes cluster.

使用現有的服務帳戶

Azure Kubernetes Service 會將環境內的 Kubernetes 資源對應至命名空間。

如需在環境外部設定 Kubernetes 服務連線的詳細資訊,請參閱服務連線中的 Kubernetes 服務連線一節。

提示

使用泛型提供者(現有的服務帳戶)將 Kubernetes 資源對應至非 AKS 叢集的命名空間。

新增非 AKS Kubernetes 資源

  1. 在 [環境詳細數據] 頁面中,選取 [新增資源 ],然後選擇 [Kubernetes]。

  2. 為您的提供者選取 [一般提供者][現有服務帳戶 ]。

  3. 新增叢集名稱和命名空間值。

  4. 新增伺服器 URL。 您可以使用下列指令取得 URL:

    kubectl config view --minify -o 'jsonpath={.clusters[0].cluster.server}'
    
  5. 若要取得秘密物件。

    Kubernetes 1.22+

    以您的帳號名稱取代 service-account-name

    kubectl get secret -n <namespace>  -o jsonpath='{.items[?(@.metadata.annotations.kubernetes\.io/service-account\.name==\"service-account-name\")]}'
    

    如果您未取得任何專案,請參閱 手動建立 ServiceAccount 的長期 API 令牌。

    Kubernetes 1.22 和以下版本:

    1. 尋找服務帳戶密碼名稱
    kubectl get serviceAccounts <service-account-name> -n <namespace> -o 'jsonpath={.secrets[*].name}'
    
    1. 將取代 <service-account-secret-name> 為此命令中上一個命令中的值
    kubectl get secret <service-account-secret-name> -n <namespace> -o json
    
  6. 使用上一個步驟的輸出取得秘密物件。

    kubectl get secret <service-account-secret-name> -n <namespace> -o json
    
  7. 將 JSON 表單中擷取的 Secret 物件複製並貼到 [秘密] 字段中。

  8. 選取 [驗證並建立 ] 以建立 Kubernetes 資源。

參考管線中的 Kubernetes 資源

如果您使用 Azure Kubernetes Service 並建置 YAML 管線,設定管線最簡單的方式就是使用範本。 連線 存放庫,然後選取下列兩個 Kubernetes Service 選項之一:

範本可讓您設定檢閱應用程式,而不需要從頭開始撰寫 YAML 程式代碼,或手動建立明確的角色系結。

Kubernetes template options.

設定檢閱應用程式

在下列範例中,第一個部署作業會針對非PR分支執行,並在環境中針對一般 Kubernetes 資源執行部署。 第二個作業只會針對PR分支執行,並根據隨選產生的檢閱應用程式資源(Kubernetes 叢集中的命名空間)進行部署。 資源會在環境的資源清單檢視中標示為「檢閱」。 定義管線中使用的變數。 如果您使用 部署至 Azure Kubernetes Services 範本,這些變數會為您定義。

# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
trigger:
- main

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '12345' # Docker service connection identifier
  envName: 'myEnv' # name of your environment
  imageRepository: 'name-of-image-repository' # name of image repository
  containerRegistry: 'mycontainer.azurecr.io' # path to container registry
  dockerfilePath: '**/Dockerfile'
  tag: '$(Build.BuildId)'
  imagePullSecret: 'my-app-secret' # image pull secret

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Name of the new namespace being created to deploy the PR changes.
  k8sNamespaceForPR: 'review-app-$(System.PullRequest.PullRequestId)'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

    - upload: manifests
      artifact: manifests

- stage: Production
  displayName: Deploy stage
  dependsOn: Build

  jobs:
  - deployment: Production
    condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
    displayName: Production
    pool:
      vmImage: $(vmImageName)
    environment: 
      name: $(envName).$(resourceName)
      resourceType: Kubernetes 
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

  - deployment: DeployPullRequest
    displayName: Deploy Pull request
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
    pool:
      vmImage: $(vmImageName)

    environment: 
      name: $(envName).$(resourceName)
      resourceType: Kubernetes
    strategy:
      runOnce:
        deploy:
          steps:
          - reviewApp: default

          - task: Kubernetes@1
            displayName: 'Create a new namespace for the pull request'
            inputs:
              command: apply
              useConfigurationFile: true
              inline: '{ "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "$(k8sNamespaceForPR)" }}'

          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespaceForPR)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            displayName: Deploy to the new namespace in the Kubernetes cluster
            inputs:
              action: deploy
              namespace: $(k8sNamespaceForPR)
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

          - task: Kubernetes@1
            name: get
            displayName: 'Get services in the new namespace'
            continueOnError: true
            inputs:
              command: get
              namespace: $(k8sNamespaceForPR)
              arguments: svc
              outputFormat: jsonpath='http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'

          # Getting the IP of the deployed service and writing it to a variable for posting comment
          - script: |
              url="$(get.KubectlOutput)"
              message="Your review app has been deployed"
              if [ ! -z "$url" -a "$url" != "http://:" ]
              then
                message="${message} and is available at $url.<br><br>[Learn More](https://aka.ms/testwithreviewapps) about how to test and provide feedback for the app."
              fi
              echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"

若要在現有的管線中使用此作業,備份一般 Kubernetes 環境資源的服務聯機必須修改為「使用叢集管理員認證」。 否則,您必須為基礎服務帳戶建立角色系結至檢閱應用程式命名空間。

下一步