教程:通过 GitOps 实现 CI/CD (Flux v2)

在本教程中,你将使用 GitOps with Flux v2 和已启用 Azure Arc 的 Kubernetes 群集或 Azure Kubernetes 服务 (AKS) 群集来设置 CI/CD 解决方案。 你将使用示例 Azure 投票应用执行以下操作:

  • 创建已启用 Azure Arc 的 Kubernetes 或 AKS 群集。
  • 将应用程序和 GitOps 存储库连接到 Azure Repos 或 GitHub。
  • 通过 Azure Pipelines 或 GitHub 实现 CI/CD 流。
  • 将 Azure 容器注册表连接到 Azure DevOps 和 Kubernetes。
  • 创建环境变量组或机密。
  • 部署 devstage 环境。
  • 测试应用程序环境。

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

注意

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

先决条件

  • 完成上一篇教程,了解如何为 CI/CD 环境部署 GitOps。

  • 了解此功能的优势和体系结构

  • 验证是否具有:

  • 安装这些已启用 Azure Arc 的 Kubernetes 和 Kubernetes 配置 CLI 扩展的最新版本:

    az extension add --name connectedk8s
    az extension add --name k8s-configuration
    
    • 若要将这些扩展更新到最新版本,请运行以下命令:

      az extension update --name connectedk8s
      az extension update --name k8s-configuration
      

将 Azure 容器注册表连接到 Kubernetes

使 Kubernetes 群集能够从 Azure 容器注册表中拉取映像。 如果它是专用的,则需要完成身份验证。

将 Azure 容器注册表连接到现有 AKS 群集

使用以下命令将现有 Azure 容器注册表与现有 AKS 群集相集成:

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

创建映像拉取机密

若要将非 AKS 群集和本地群集连接到 Azure 容器注册表,请创建映像拉取机密。 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 教程

根据你喜欢的 CI/CD 业务流程协调程序,你可以继续了解 Azure DevOps 或 GitHub 的说明。

使用 Azure DevOps 实现 CI/CD

本教程假设读者熟悉 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 存储库仅包含一个清单,该清单用于创建对应于部署环境的 dev 和 stage 命名空间。

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

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

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

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

    az k8s-configuration flux create \
       --name cluster-config \
       --cluster-name arc-cicd-cluster \
       --namespace flux-system \
       --resource-group myResourceGroup \
       -u 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 \
       --branch master \
       --kustomization name=cluster-config prune=true path=arc-cicd-cluster/manifests
    

    提示

    对于 AKS 群集(而不是已启用 Arc 的群集),请使用 -cluster-type managedClusters

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

    • 如果成功,你会发现群集中创建了 devstage 命名空间。
    • 还可以确认在群集的 Azure 门户页面上,在 GitOps 选项卡上创建了配置 cluster-config

导入 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

将 Azure 容器注册表连接到 Azure DevOps

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

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

配置 PR 服务连接

CD 管道操作 GitOps 存储库中的 PR。 它需要服务连接才能执行此操作。 配置此连接:

  1. 在 Azure DevOps 中,从项目设置页打开“服务连接”页。 在 TFS 中,通过顶部菜单栏中的“设置”图标打开“服务”页。
  2. 选择“+ 新建服务连接”,然后选择 Generic 类型。
  3. 填写该服务连接的参数。 对于本教程:
    • 服务器 URL https://dev.azure.com/<Your organization>/<Your project>/_apis/git/repositories/arc-cicd-demo-gitops
    • 保留“用户名”和“密码”为空。
    • 将服务连接命名为 azdo-pr-connection。
  4. 选择“授予对所有管道的访问权限”。
    • 此选项为用于服务连接的 YAML 管道文件授权。
  5. 选择“确定”以创建连接。

安装 GitOps 连接器

  1. 将 GitOps 连接器存储库添加到 Helm 存储库:

       helm repo add gitops-connector https://azure.github.io/gitops-connector/
    
  2. 将连接器安装到群集:

       helm upgrade -i gitops-connector gitops-connector/gitops-connector \
          --namespace flux-system \
          --set gitRepositoryType=AZDO \
          --set ciCdOrchestratorType=AZDO \
          --set gitOpsOperatorType=FLUX \
          --set azdoGitOpsRepoName=arc-cicd-demo-gitops \
          --set azdoOrgUrl=https://dev.azure.com/<Your organization>/<Your project> \
          --set gitOpsAppURL=https://dev.azure.com/<Your organization>/<Your project>/_git/arc-cicd-demo-gitops \
          --set orchestratorPAT=<Azure Repos PAT token>
    

    注意

    Azure Repos PAT token 应具有 Build: Read & executeCode: Full 权限。

  3. 配置 Flux 以将通知发送到 GitOps 连接器:

    cat <<EOF | kubectl apply -f -
    apiVersion: notification.toolkit.fluxcd.io/v1beta1
    kind: Alert
    metadata:
      name: gitops-connector
      namespace: flux-system
    spec:
      eventSeverity: info
      eventSources:
      - kind: GitRepository
        name: cluster-config
      - kind: Kustomization
        name: cluster-config-cluster-config 
      providerRef:
        name: gitops-connector
    ---
    apiVersion: notification.toolkit.fluxcd.io/v1beta1
    kind: Provider
    metadata:
      name: gitops-connector
      namespace: flux-system
    spec:
      type: generic
      address: http://gitops-connector:8080/gitopsphase
    EOF
    

有关安装的详细信息,请参阅 GitOps 连接器存储库。

创建环境变量组

应用存储库变量组

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

变量
AZURE_SUBSCRIPTION (你的 Azure 服务连接,根据本教程前面所述,应是 arc-demo-acr
AZ_ACR_NAME Azure ACR 名称,例如 arc-demo-acr
ENVIRONMENT_NAME Dev
MANIFESTS_BRANCH master
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
VOTE_APP_TITLE 投票应用程序
AKS_RESOURCE_GROUP AKS 资源组。 自动测试所需的。
AKS_NAME AKS 名称。 自动测试所需的。

暂存环境变量组

  1. 克隆 az-vote-app-dev 变量组。

  2. 将名称更改为 az-vote-app-stage

  3. 确保相应变量使用以下值:

    变量
    ENVIRONMENT_NAME 阶段
    TARGET_NAMESPACE stage

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

创建环境

在 Azure DevOps 项目中,创建 DevStage 环境。 有关详细信息,请参阅创建环境并以该环境为目标

向生成服务授予更多权限

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

  1. 从 Azure DevOps 项目主页中转到 Project settings
  2. 选择 Repos/Repositories
  3. 选择 Security
  4. 对于 <Project Name> Build Service (<Organization Name>)Project Collection Build Service (<Organization Name>)(如果未显示,请在搜索字段中键入),允许 ContributeContribute to pull requestsCreate branch
  5. 转到 Pipelines/Settings
  6. 关闭 Protect access to repositories in YAML pipelines 选项

有关详细信息,请参阅:

首次部署开发环境

创建 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. 查找管道创建到 GitOps 存储库的 PR。

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

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

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

  5. 在“提交历史记录”选项卡上监视 Git 提交状态。一旦状态为 succeeded,CD 管道将开始自动测试。

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

    kubectl port-forward -n dev svc/azure-vote-front 8080:80
    
  7. 在浏览器中使用 http://localhost:8080/ 查看 Azure 投票应用。

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

设置环境审批

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

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

  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 管道来完成部署过程。 这一次,管道要求你批准每个部署环境。

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

部署现已完成。

有关本教程中使用的 CI/CD 工作流中实现的所有步骤和技术的详细概述,请参阅 Azure DevOps GitOps 流关系图

通过 GitHub 实现 CI/CD

本教程假定你熟悉 GitHub 和 GitHub Actions。

创建应用程序存储库和 GitOps 存储库分支

创建应用程序存储库GitOps 存储库分支。 对于本教程,请使用以下示例存储库:

连接 GitOps 存储库

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

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

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

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

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

  1. 与 GitHub 中新创建的 arc-cicd-demo-gitops 存储库分支建立新的 GitOps 连接

    az k8s-configuration flux create \
       --name cluster-config \
       --cluster-name arc-cicd-cluster \
       --namespace cluster-config \
       --resource-group myResourceGroup \
       -u  https://github.com/<Your organization>/arc-cicd-demo-gitops.git \
       --https-user <Azure Repos username> \
       --https-key <Azure Repos PAT token> \
       --scope cluster \
       --cluster-type connectedClusters \
       --branch master \
       --kustomization name=cluster-config prune=true path=arc-cicd-cluster/manifests
    
  2. 在 Azure 门户中检查部署状态。

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

安装 GitOps 连接器

  1. 将 GitOps 连接器存储库添加到 Helm 存储库:

       helm repo add gitops-connector https://azure.github.io/gitops-connector/
    
  2. 将连接器安装到群集:

       helm upgrade -i gitops-connector gitops-connector/gitops-connector \
          --namespace flux-system \
          --set gitRepositoryType=GITHUB \
          --set ciCdOrchestratorType=GITHUB \
          --set gitOpsOperatorType=FLUX \
          --set gitHubGitOpsRepoName=arc-cicd-demo-src \
          --set gitHubGitOpsManifestsRepoName=arc-cicd-demo-gitops \
          --set gitHubOrgUrl=https://api.github.com/repos/<Your organization> \
          --set gitOpsAppURL=https://github.com/<Your organization>/arc-cicd-demo-gitops/commit \
          --set orchestratorPAT=<GitHub PAT token>
    
  3. 配置 Flux 以将通知发送到 GitOps 连接器:

    cat <<EOF | kubectl apply -f -
    apiVersion: notification.toolkit.fluxcd.io/v1beta1
    kind: Alert
    metadata:
      name: gitops-connector
      namespace: flux-system
    spec:
      eventSeverity: info
      eventSources:
      - kind: GitRepository
        name: cluster-config
      - kind: Kustomization
        name: cluster-config-cluster-config
      providerRef:
        name: gitops-connector
    ---
    apiVersion: notification.toolkit.fluxcd.io/v1beta1
    kind: Provider
    metadata:
      name: gitops-connector
      namespace: flux-system
    spec:
      type: generic
      address: http://gitops-connector:8080/gitopsphase
    EOF
    

有关安装的详细信息,请参阅 GitOps 连接器存储库。

创建 GitHub 机密

创建 GitHub 存储库机密

Secret Value
AZURE_CREDENTIALS Azure 的凭据,格式为 {"clientId":"GUID","clientSecret":"GUID","subscriptionId":"GUID","tenantId":"GUID"}
AZ_ACR_NAME Azure ACR 名称,例如 arc-demo-acr
MANIFESTS_BRANCH master
MANIFESTS_FOLDER arc-cicd-cluster
MANIFESTS_REPO https://github.com/your-organization/arc-cicd-demo-gitops
VOTE_APP_TITLE 投票应用程序
AKS_RESOURCE_GROUP AKS 资源组。 自动测试所需的。
AKS_NAME AKS 名称。 自动测试所需的。
PAT 具有到 GitOps 存储库的 PR 权限的 GitHub PAT 令牌

创建 GitHub 环境机密

  1. 创建具有以下机密的 az-vote-app-dev 环境:
Secret
ENVIRONMENT_NAME Dev
TARGET_NAMESPACE dev
  1. 创建具有以下机密的 az-vote-app-stage 环境:
Secret
ENVIRONMENT_NAME 阶段
TARGET_NAMESPACE stage

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

CI/CD 开发工作流

要启动 CI/CD 开发工作流,请更改源代码。 在应用程序存储库中,更新 .azure-vote/src/azure-vote-front/config_file.cfg 文件中的值,并将更改推送到存储库。

CI/CD 开发工作流:

  • 确保应用程序更改通过了所有自动化的部署质量检查。
  • 执行无法在 PR 管道中完成的任何额外验证。
  • 验证是否已更改 Docker 映像并已推送新映像。
  • 发布将由以下 CD 阶段使用的项目(Docker 映像标签、清单模板、实用程序)。
  • 将应用程序部署到开发环境。
    • 将清单生成到 GitOps 存储库。
    • 创建对 GitOps 存储库的 PR 以供审批。
  1. 查找管道创建到 GitOps 存储库的 PR。

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

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

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

  5. 在“提交历史记录”选项卡上监视 Git 提交状态。一旦状态为 succeededCD Stage 工作流将启动。

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

    kubectl port-forward -n dev svc/azure-vote-front 8080:80
    
  7. 在浏览器中使用 http://localhost:8080/ 查看 Azure 投票应用。

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

CD 阶段工作流

在 Flux 成功地将应用程序部署到开发环境并通过 GitOps 连接器通知 GitHub 操作时,CD 阶段工作流将自动启动。

CD 阶段工作流:

  • 针对开发环境运行应用程序冒烟测试
  • 将应用程序部署到暂存环境。
    • 将清单生成到 GitOps 存储库
    • 创建到 GitOps 存储库的 PR 以供审批

一旦合并了对暂存环境的清单 PR 并且 Flux 成功应用了所有更改,Git 提交状态就会在 GitOps 存储库中更新。 部署现已完成。

有关本教程中使用的 CI/CD 工作流中实现的所有步骤和技术的详细概述,请参阅 GitHub GitOps 流关系图

清理资源

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

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

    az k8s-configuration flux delete \
          --name cluster-config \
          --cluster-name arc-cicd-cluster \
          --resource-group myResourceGroup \
          -t connectedClusters --yes
    
  2. 删除 GitOps 连接器:

    helm uninstall gitops-connector -n flux-system
    kubectl delete alerts.notification.toolkit.fluxcd.io gitops-connector -n flux-system
    kubectl delete providers.notification.toolkit.fluxcd.io  gitops-connector -n flux-system
    

后续步骤

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

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