教程:使用已启用 Azure Arc 的 Kubernetes 群集通过 GitOps 实现 CI/CD

重要

本教程使用 GitOps (Flux v1)。 GitOps (Flux v2) 适用于 Azure Arc-enabled Kubernetes 和 Azure Kubernetes Service (AKS) 群集;转到使用 GitOps (Flux v2) 的教程。 建议尽快迁移到 Flux v2

2025 年 5 月 24 日起,将不再支持 2024 年 1 月 1 日之前创建的基于 Flux v1 的群集配置资源。 从 2024 年 1 月 1 日开始,你将无法创建新的基于 Flux v1 的群集配置资源。

在本教程中,你会将 GitOps 与已启用 Azure Arc 的 Kubernetes 群集配合使用,来设置一个 CI/CD 解决方案。 你将使用示例 Azure 投票应用执行以下操作:

  • 创建一个已启用 Azure Arc 的 Kubernetes 群集。
  • 将应用程序和 GitOps 存储库连接到 Azure Repos。
  • 导入 CI/CD 管道。
  • 将 Azure 容器注册表 (ACR) 连接到 Azure DevOps 和 Kubernetes。
  • 创建环境变量组。
  • 部署 devstage 环境。
  • 测试应用程序环境。

如果没有 Azure 订阅,请在开始前创建一个试用版订阅

注意

在可以在由世纪互联运营的 Microsoft Azure 中使用 Azure CLI 之前,请先运行 az cloud set -n AzureChinaCloud 来更改云环境。 若要切换回 Azure 公有云,请再次运行 az cloud set -n AzureCloud

开始之前

本教程假设读者熟悉 Azure DevOps、Azure Repos 和管道以及 Azure CLI。

将应用程序存储库和 GitOps 存储库导入 Azure Repos

应用程序存储库GitOps 存储库导入 Azure Repos。 对于本教程,请使用以下示例存储库:

详细了解如何导入 Git 存储库

注意

为应用程序和 GitOps 导入并使用两个独立的存储库能够提高安全性和简易性。 可以分别优化应用程序和 GitOps 存储库的权限与可见性。 例如,群集管理员可能在应用程序代码中发现不了与群集所需状态相关的更改。 相反,应用程序开发人员无需知道每个环境的特定参数 - 一组能够涵盖各个参数的测试值可能就已足够。

连接 GitOps 存储库

若要持续部署应用,请使用 GitOps 将应用程序存储库连接到群集。 arc-cicd-demo-gitops GitOps 存储库包含可使应用在 arc-cicd-cluster 群集上启动并运行的基本资源。

初始 GitOps 存储库仅包含一个清单,该清单用于创建对应于部署环境的 devstage 命名空间。

创建的 GitOps 连接将自动执行以下操作:

  • 同步清单目录中的清单。
  • 更新群集状态。

CI/CD 工作流将在清单目录中填充额外的清单,以部署应用。

  1. 与 Azure Repos 中新导入的 arc-cicd-demo-gitops 存储库建立新的 GitOps 连接

    az k8s-configuration create \
       --name cluster-config \
       --cluster-name arc-cicd-cluster \
       --resource-group myResourceGroup \
       --operator-instance-name cluster-config \
       --operator-namespace cluster-config \
       --repository-url https://dev.azure.com/<Your organization>/<Your project>/_git/arc-cicd-demo-gitops \
       --https-user <Azure Repos username> \
       --https-key <Azure Repos PAT token> \
       --scope cluster \
       --cluster-type connectedClusters \
       --operator-params='--git-readonly --git-path=arc-cicd-cluster/manifests'
    
  2. 确保 Flux 仅使用 arc-cicd-cluster/manifests 目录作为基路径。 使用以下运算符参数定义路径:

    --git-path=arc-cicd-cluster/manifests

    注意

    如果你使用 HTTPS 连接字符串并出现连接问题,请确保在 URL 中省略用户名前缀。 例如,必须删除 https://alice@dev.azure.com/contoso/project/_git/arc-cicd-demo-gitops 中的 alice@。 在此情况下,将由 --https-user 指定用户,例如 --https-user alice

  3. 在 Azure 门户中检查部署状态。

    • 如果成功,你会发现群集中创建了 devstage 命名空间。

导入 CI/CD 管道

同步 GitOps 连接后,需要导入用于创建清单的 CI/CD 管道。

应用程序存储库包含一个 .pipeline 文件夹,该文件夹中包含用于 PR、CI 和 CD 的管道。 导入示例存储库中提供的三个管道并将其重命名:

管道文件名 说明
.pipelines/az-vote-pr-pipeline.yaml 应用程序 PR 管道,名为 arc-cicd-demo-src PR
.pipelines/az-vote-ci-pipeline.yaml 应用程序 CI 管道,名为 arc-cicd-demo-src CI
.pipelines/az-vote-cd-pipeline.yaml 应用程序 CD 管道,名为 arc-cicd-demo-src CD

连接 ACR

管道和群集都将利用 ACR 来存储和检索 Docker 映像。

将 ACR 连接到 Azure DevOps

在 CI 过程中,你要将应用程序容器部署到注册表。 首先创建 Azure 服务连接:

  1. 在 Azure DevOps 中,从项目设置页打开“服务连接”页。 在 TFS 中,通过顶部菜单栏中的“设置”图标打开“服务”页。
  2. 选择“+ 新建服务连接”,然后选择所需的服务连接类型。
  3. 填写该服务连接的参数。 对于本教程:
    • 将服务连接命名为 arc-demo-acr
    • 选择“myResourceGroup”作为资源组。
  4. 选择“授予对所有管道的访问权限”。
    • 此选项为用于服务连接的 YAML 管道文件授权。
  5. 选择“确定”以创建连接。

将 ACR 连接到 Kubernetes

使 Kubernetes 群集能够从 ACR 中拉取映像。 如果该 ACR 是专用的,则需要完成身份验证。

将 ACR 连接到现有 AKS 群集

使用以下命令将现有 ACR 与现有 AKS 群集相集成:

az aks update -n arc-cicd-cluster -g myResourceGroup --attach-acr arc-demo-acr

创建映像拉取机密

若要将非 AKS 群集和本地群集连接到 ACR,请创建映像拉取机密。 Kubernetes 使用映像拉取机密来存储对注册表进行身份验证所需的信息。

使用以下 kubectl 命令创建映像拉取机密。 对 devstage 命名空间重复此操作。

kubectl create secret docker-registry <secret-name> \
    --namespace <namespace> \
    --docker-server=<container-registry-name>.azurecr.cn \
    --docker-username=<service-principal-ID> \
    --docker-password=<service-principal-password>

为了避免对每个 Pod 都设置一个 imagePullSecret,请考虑将 imagePullSecret 添加到 devstage 命名空间中的服务帐户。 有关详细信息,请参阅 Kubernetes 教程

创建环境变量组

应用存储库变量组

创建名为 az-vote-app-dev 的变量组。 设置以下值:

变量
AZ_ACR_NAME (ACR 实例,例如 .azurearctest.azurecr.cn)
AZURE_SUBSCRIPTION (你的 Azure 服务连接,根据本教程前面所述,应是 arc-demo-acr
AZURE_VOTE_IMAGE_REPO Azure 投票应用存储库的完整路径,例如 azurearctest.azurecr.cn/azvote
ENVIRONMENT_NAME Dev
MANIFESTS_BRANCH master
MANIFESTS_FOLDER azure-vote-manifests
MANIFESTS_REPO arc-cicd-demo-gitops
ORGANIZATION_NAME Azure DevOps 组织的名称
PROJECT_NAME Azure DevOps 中 GitOps 项目的名称
REPO_URL GitOps 存储库的完整 URL
SRC_FOLDER azure-vote
TARGET_CLUSTER arc-cicd-cluster
TARGET_NAMESPACE dev

暂存环境变量组

  1. 克隆 az-vote-app-dev 变量组。
  2. 将名称更改为 az-vote-app-stage
  3. 确保相应变量使用以下值:
变量
ENVIRONMENT_NAME 阶段
TARGET_NAMESPACE stage

现已准备好部署到 devstage 环境。

向生成服务授予更多权限

CD 管道使用正在运行的生成的安全令牌对 GitOps 存储库进行身份验证。 管道需要更多的权限来创建新分支、推送更改和创建拉取请求。

  1. 从 Azure DevOps 项目主页中转到 Project settings
  2. 选择 Repositories
  3. 选择 <GitOps Repo Name>
  4. 选择 Security
  5. 对于 <Project Name> Build Service (<Organization Name>),允许 ContributeContribute to pull requestsCreate branch

有关详细信息,请参阅:

首次部署开发环境

创建 CI 和 CD 管道后,运行 CI 管道以首次部署应用。

CI 管道

在初始 CI 管道运行期间,读取服务连接名称时可能会出现资源授权错误。

  1. 请验证所访问的变量是否为 AZURE_SUBSCRIPTION。
  2. 授权使用。
  3. 请重新运行管道。

CI 管道:

  • 确保应用程序更改通过了所有自动化的部署质量检查。
  • 执行无法在 PR 管道中完成的任何额外验证。
    • 该管道特定于 GitOps,它还会发布将由 CD 管道部署的提交项目。
  • 验证是否已更改 Docker 映像并已推送新映像。

CD 管道

在初始 CD 管道运行过程中,系统会要求你为管道提供对 GitOps 存储库的访问权限。 当提示管道需要访问资源的权限时,请选择“查看”。 然后,选择“允许”,向当前和将来的管道运行授予使用 GitOps 存储库的权限。

成功的 CI 管道运行会触发 CD 管道来完成部署过程。 你将以增量方式部署到每个环境。

提示

如果 CD 管道未自动触发:

  1. 验证名称是否与 .pipelines/az-vote-cd-pipeline.yaml 中的分支触发器相匹配
    • 它应为 arc-cicd-demo-src CI
  2. 重新运行 CI 管道。

生成对 GitOps 存储库所做的模板和清单更改后,CD 管道将创建一个提交项,推送该提交项,然后创建 PR 供审批。

  1. 打开 Create PR 任务输出中提供的 PR 链接。

  2. 验证对 GitOps 存储库所做的更改。 应会看到:

    • 高级 Helm 模板更改。
    • 低级 Kubernetes 清单,显示对所需状态做出的基础更改。 Flux 部署这些清单。
  3. 如果一切正常,请批准并完成 PR。

  4. 几分钟后,Flux 将拾取更改并开始部署。

  5. 使用 kubectl 在本地转发端口,并使用以下命令来确保应用正常工作:

    kubectl port-forward -n dev svc/azure-vote-front 8080:80

  6. 在浏览器中使用 http://localhost:8080/ 查看 Azure 投票应用。

  7. 为收藏项投票,并准备好对应用做出一些更改。

设置环境审批

部署应用后,你不仅可能会对代码或模板做出更改,而且还可能在无意中使群集处于错误状态。

如果开发环境在部署后出现损坏情况,请使用环境审批来避免这种情况漫延到后面的环境。

  1. 在 Azure DevOps 项目中,转到需要保护的环境。
  2. 导航到资源对应的“审批和检查”。
  3. 选择“创建”
  4. 提供审批者和可选消息。
  5. 再次选择“创建”以完成添加手动审批检查。

有关更多详细信息,请参阅定义审批和检查教程。

下一次 CD 管道运行时,该管道将在创建 GitOps PR 后暂停。 验证更改是否已正确同步并通过了基本的功能检查。 批准管道中的检查,使更改流向下一环境。

做出应用程序更改

你将根据模板以及用于表示群集中状态的清单的这一套基线,对应用进行少量的更改。

  1. arc-cicd-demo-src 存储库中编辑 azure-vote/src/azure-vote-front/config_file.cfg 文件。

  2. 由于“Cats vs Dogs”未获得足够多的投票,请将其更改为“Tabs vs Spaces”以提高投票数。

  3. 在新分支中提交更改,推送更改,然后创建拉取请求。

    • 这是启动 CI/CD 生命周期的典型开发人员流。

PR 验证管道

PR 管道是避免出现错误更改的第一道防线。 一般的应用程序代码质量检查包括 Lint 分析和静态分析。 从 GitOps 的角度看,还需确保所要部署的最终基础结构的质量相同。

应用程序的 Dockerfile 和 Helm 图表可以像应用程序一样使用 Lint 分析。

Lint 分析期间出现的错误包括:

  • 指出 YAML 文件格式不正确;
  • 提供最佳做法建议,例如,为应用程序设置 CPU 和内存限制。

注意

若要在真实应用程序中通过 Helm Lint 分析获得最全面的问题覆盖范围,需要替代真实环境中使用的相当类似的值。

在管道执行期间发现的错误将显示在运行的“测试结果”部分。 你可以在此处:

  • 跟踪有关错误类型的有用统计信息。
  • 找到在其中检测到了这些错误的第一个提交项。
  • 找到导致错误的代码部分的堆栈跟踪式链接。

管道运行完成后,即可保证应用程序代码以及要部署该代码的模板的质量。 现在可以批准并完成 PR。 CI 将再次运行,重新生成模板和清单,然后触发 CD 管道。

提示

在真实环境中,请记得设置分支策略,以确保 PR 通过质量检查。 有关详细信息,请参阅设置分支策略一文。

CD 过程审批

成功的 CI 管道运行会触发 CD 管道来完成部署过程。 与首次运行 CD 管道类似,你将以增量方式部署到每个环境。 这一次,管道要求你批准每个部署环境。

  1. 批准部署到 dev 环境。
  2. 生成对 GitOps 存储库所做的模板和清单更改后,CD 管道将创建一个提交项,推送该提交项,然后创建 PR 供审批。
  3. 打开任务中提供的 PR 链接。
  4. 验证对 GitOps 存储库所做的更改。 应会看到:
    • 高级 Helm 模板更改。
    • 低级 Kubernetes 清单,显示对所需状态做出的基础更改。
  5. 如果一切正常,请批准并完成 PR。
  6. 等待部署完成。
  7. 作为基本的冒烟测试,请导航到应用程序页,并验证投票应用现在是否显示“Tabs vs Spaces”。
    • 使用 kubectl 在本地转发端口,并使用以下命令来确保应用正常工作:kubectl port-forward -n dev svc/azure-vote-front 8080:80
    • 在浏览器中使用 http://localhost:8080/ 查看 Azure 投票应用,验证投票选项是否已更改为“Tabs vs Spaces”。
  8. stage 环境重复步骤 1-7。

部署现已完成。 CI/CD 工作流到此结束。

清理资源

如果你不打算继续使用此应用程序,请按以下步骤删除所有资源:

  1. 删除 Azure Arc GitOps 配置连接:

    az k8s-configuration delete \
    --name cluster-config \
    --cluster-name arc-cicd-cluster \
    --resource-group myResourceGroup \
    --cluster-type connectedClusters
    
  2. 删除 dev 命名空间:

    • kubectl delete namespace dev
  3. 删除 stage 命名空间:

    • kubectl delete namespace stage

后续步骤

在本教程中,你已设置一个完整的 CI/CD 工作流,该工作流可实现从应用程序开发到部署的整个 DevOps。 对应用程序所做的更改会自动触发验证和部署,这些操作通过手动审批进行限制。

请转到我们的概念文章,详细了解使用已启用 Azure Arc 的 Kubernetes 进行的 GitOps 和配置。