环境 - Kubernetes 资源

Azure DevOps Services

Kubernetes 资源视图可瞥见映射到资源的命名空间中的对象的状态。 此视图还覆盖管道可追溯性,以便你可以从 Kubernetes 对象追溯到管道,然后返回到提交。

使用 Kubernetes 资源在 环境中 以 Kubernetes 群集为目标进行部署。 使用管道从任何其他云提供商部署到 Azure Kubernetes 服务 (AKS) 和群集。

可以将 Kubernetes 资源与公共群集或专用群集配合使用。 若要详细了解资源的工作原理,请参阅 YAML 中的资源 以及 资源的安全性

概述

请参阅以下在环境中使用 Kubernetes 资源视图的优点:

  • 管道可追溯性 - 用于部署的 Kubernetes 清单任务增加了更多注释,用于在资源视图中显示管道可追溯性。 管道可跟踪性有助于识别负责对命名空间中对象进行的更新的源 Azure DevOps 组织、项目和管道。

    Pipeline traceability

  • 诊断资源运行状况 - 工作负荷状态可用于快速调试新部署可能引入的错误或回归。 例如,对于导致 ImagePullBackOff 错误的未配置 imagePullSecret ,Pod 状态信息可以帮助你识别问题的根本原因。

    ImagePullBackOff

  • 查看应用 - 查看 应用的工作原理是将 Git 存储库中的每个拉取请求部署到环境中的动态 Kubernetes 资源。 审阅者可以在将这些更改合并到目标分支并部署到生产环境之前查看这些更改的外观和与其他依赖服务的工作方式。

使用 Azure Kubernetes 服务

使用 Azure Kubernetes 服务 (AKS) 时,会在所选群集和命名空间中创建 ServiceAccount 。 对于启用了 Kubernetes RBAC 的群集, 还将创建 RoleBinding ,以将创建的服务帐户的范围限制为所选命名空间。 对于禁用 Kubernetes RBAC 的群集,创建的 ServiceAccount 具有跨命名空间) 的群集范围特权 (。

添加 AKS Kubernetes 资源

  1. 在“环境详细信息”页中,选择“ 添加资源 ”,然后选择 “Kubernetes”。

  2. 在提供程序下拉列表中选择 Azure Kubernetes 服务

  3. 选择 Azure 订阅、群集和命名空间, (新的/现有) 。

  4. 选择 “验证并创建 ”以创建 Kubernetes 资源。

  5. 验证是否看到环境的群集。 如果尚未将代码部署到群集,你将看到文本“从未部署”。

    Add a Kubernetes cluster.

使用现有的服务帐户

Azure Kubernetes 服务创建新的 ServiceAccount,但通用提供程序选项允许使用现有的 ServiceAccount。 现有 ServiceAccount 可以映射到环境中的 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. 若要获取机密对象,请查找服务帐户机密名称。

    kubectl get serviceAccounts <service-account-name> -n <namespace> -o 'jsonpath={.secrets[*].name}'
    
  6. 使用上一步的输出获取机密对象。

    kubectl get secret <service-account-secret-name> -n <namespace> -o json
    
  7. 将 JSON 格式提取的 Secret 对象复制并粘贴到“机密”字段中。

  8. 选择 “验证并创建 ”以创建 Kubernetes 资源。

在管道中引用 Kubernetes 资源

如果使用 Azure Kubernetes 服务并生成 YAML 管道,则配置管道的最简单方法是使用模板。 连接到存储库并选择以下两个 Kubernetes 服务选项之一:

模板允许你设置“审阅应用”,而无需从头开始编写 YAML 代码或手动创建显式角色绑定。

Kubernetes template options.

设置审阅应用

在以下示例中,第一个部署作业针对非 PR 分支运行,并在环境中针对常规 Kubernetes 资源执行部署。 第二个作业仅针对 PR 分支运行,针对 Kubernetes 群集内 (命名空间) 按需生成的“查看应用资源”部署。 资源在环境的资源列表视图中用“审阅”标记。 定义要在管道中使用的变量。 如果使用 “部署到 Azure Kubernetes 服务”模板,这些变量将为你定义。

# 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: $(envName).$(resourceName)
    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: $(envName).$(resourceName)
    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 posing 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 环境资源的服务连接修改为“使用群集管理员凭据”。 否则,必须为基础服务帐户创建角色绑定以连接到 Review App 命名空间。

后续步骤