环境 - Kubernetes 资源
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Kubernetes 资源视图显示映射到资源的命名空间中对象状态。 资源视图还覆盖管道可跟踪性,以便你可以从 Kubernetes 对象回溯到管道,然后回溯到提交。
在环境中使用 Kubernetes 资源以 Kubernetes 群集为目标进行部署。 使用管道从任何其他云提供商部署到Azure Kubernetes 服务 (AKS) 和群集。
可以将 Kubernetes 资源与公共或专用群集一起使用。 有关资源工作原理的详细信息,请参阅 YAML 中的资源以及 资源的安全性。
注意
如果使用专用 AKS 群集,请确保连接到群集的虚拟网络,因为 API 服务器终结点不会通过公共 IP 地址公开。
Azure Pipelines 建议在有权访问群集虚拟网络的 VNET 中设置自承载代理。 有关详细信息,请参阅 用于连接到专用群集 的选项。
概述
请了解在环境中使用 Kubernetes 资源视图的以下优点:
管道可跟踪性 - 用于部署的 Kubernetes 清单任务会添加更多注释,以显示资源视图中的管道可跟踪性。 管道可跟踪性有助于识别负责对命名空间中的对象进行更新的原始 Azure DevOps 组织、项目和管道。
诊断资源运行状况 - 工作负荷状态可用于快速调试新部署引入的错误或回归。 例如,对于导致 ImagePullBackOff 错误的未配置的 imagePullSecret,Pod 状态信息可以帮助你确定问题的根本原因。
审核应用 - 审核应用的工作原理是将 Git 存储库中的每个拉取请求部署到环境中的动态 Kubernetes 资源。 审阅者可以在将这些更改合并到目标分支并部署到生产环境之前,查看这些更改的外观以及如何使用其他依赖服务。
使用 Azure Kubernetes 服务
使用 Azure Kubernetes 服务 (AKS) 时,会在所选群集和命名空间中创建 ServiceAccount。 对于已启用 Kubernetes RBAC 的群集,还会创建 RoleBinding,以将创建的服务帐户的范围限制为所选命名空间。 对于禁用了 Kubernetes RBAC 的集群,创建的 ServiceAccount 具有集群范围的权限(跨命名空间)。
添加 AKS Kubernetes 资源
在环境详细信息页中,选择“添加资源”,然后选择“Kubernetes”。
在“提供程序”下拉列表中选择“Azure Kubernetes 服务”。
选择 Azure 订阅、群集和命名空间(新的/现有)。
选择“验证并创建”以创建 Kubernetes 资源。
验证你是否看到适用于你的环境的群集。 如果尚未将代码部署到群集,则会看到文本“从未部署过”。
使用现有的服务帐户
Azure Kubernetes 服务将环境里的 Kubernetes 资源映射到命名空间。
有关在环境外设置 Kubernetes 服务连接的更多信息,请参阅服务连接中的 Kubernetes 服务连接一节。
提示
使用通用提供程序(现有服务帐户)将 Kubernetes 资源映射到非 AKS 集群中的命名空间。
添加非 AKS Kubernetes 资源
在环境详细信息页中,选择“添加资源”,然后选择“Kubernetes”。
为你的提供程序选择“通用提供程序(现有服务帐户)”。
添加群集名称和命名空间值。
添加服务器 URL。 可以使用以下命令获取 URL:
kubectl config view --minify -o 'jsonpath={.clusters[0].cluster.server}'
如何获取机密对象。
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 及更低版本:
- 查找服务帐户机密名称
kubectl get serviceAccounts <service-account-name> -n <namespace> -o 'jsonpath={.secrets[*].name}'
- 在此命令中,将
<service-account-secret-name>
替换为上个命令中的值
kubectl get secret <service-account-secret-name> -n <namespace> -o json
使用上一步的输出获取机密对象。
kubectl get secret <service-account-secret-name> -n <namespace> -o json
复制以 JSON 格式提取的机密对象并粘贴到“机密”字段中。
选择“验证并创建”以创建 Kubernetes 资源。
在管道中引用 Kubernetes 资源
如果使用 Azure Kubernetes 服务并生成 YAML 管道,则配置管道的最简单方法是使用模板。 连接到存储库并选择以下两个 Kubernetes 服务选项之一:
- 部署到 Azure Kubernetes 服务模板
- 部署到 Kubernetes - 通过 Azure DevSpaces 实现审阅应用功能
模板允许你设置审核应用,而无需从头开始编写 YAML 代码,也不必手动创建显式角色绑定。
设置审阅应用
在以下示例中,第一个部署作业针对非 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:
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 环境资源的服务连接修改为“使用集群管理员凭据”。 否则,必须为“审核应用”命名空间的基础服务帐户创建角色绑定。