使用 Azure Pipelines 生成并部署到 Azure Kubernetes 服务

Azure DevOps Services

使用 Azure Pipelines 自动部署到 Azure Kubernetes 服务 (AKS)。 利用 Azure Pipelines,可以使用 Azure DevOps 通过持续集成 (CI) 和持续交付 (CD) 来进行生成、测试和部署。

本文介绍如何创建一个持续生成和部署应用的管道。 每当你更改包含 Dockerfile 的存储库中的代码时,都会将映像推送到 Azure 容器注册表,然后将清单部署到 AKS 群集。

先决条件

获取代码

创建包含示例应用程序和 Dockerfile 的以下存储库的分支:

https://github.com/MicrosoftDocs/pipelines-javascript-docker

创建 Azure 资源

使用 Azure CLI 登录到 Azure 门户

创建容器注册表

# Create a resource group
az group create --name myapp-rg --location chinaeast2

# Create a container registry
az acr create --resource-group myapp-rg --name mycontainerregistry --sku Basic

# Create a Kubernetes cluster
az aks create \
    --resource-group myapp-rg \
    --name myapp \
    --node-count 1 \
    --enable-addons monitoring \
    --generate-ssh-keys

登录到 Azure Pipelines

登录到 Azure Pipelines。 登录后,浏览器会转到 https://dev.azure.com/my-organization-name 并显示 Azure DevOps 仪表板。

在所选组织中,创建项目。 如果组织中没有任何项目,则会显示“创建项目并开始使用”屏幕。 若未显示,请选择仪表板右上角的“创建项目”按钮。

创建管道

连接并选择存储库

  1. 登录到你的 Azure DevOps 组织,并转到你的项目。

  2. 转到“管道”,然后选择“新建管道”。

  3. 完成向导中的各个步骤。首先选择“GitHub”作为源代码位置。

  4. 可能会重定向到 GitHub 进行登录。 如果是这样,请输入 GitHub 凭据。

  5. 看到存储库列表时,请选择你的存储库。

  6. 你可能会被重定向到 GitHub 来安装 Azure Pipelines 应用。 如果是,请选择“批准并安装”。

  7. 选择“部署到 Azure Kubernetes 服务”。

  8. 如果出现提示,请选择在其中创建了注册表和群集的订阅。

  9. 选择 myapp 群集。

  10. 对于“命名空间”,请选择“现有”,然后选择“默认”。

  11. 选择你的容器注册表名称。

  12. 可将映像名称保留默认设置。

  13. 将服务端口设置为 8080。

  14. 对于要在后续步骤中包含在自动生成的管道 YAML 中的配置相关的评审应用,请设置“为拉取请求启用评审应用”复选框。

  15. 选择“Validate and configure”。

    在 Azure Pipelines 创建管道的过程中,将会:

    • 创建一个 Docker 注册表服务连接,使管道能够将映像推送到容器注册表中。

    • 创建一个环境,并在该环境中创建一个 Kubernetes 资源。 对于启用了 RBAC 的群集,创建的 Kubernetes 资源将在该群集中隐式创建 ServiceAccount 和 RoleBinding 对象,这样,创建的 ServiceAccount 就无法在所选命名空间之外执行操作。

    • 生成一个 azure-pipelines.yml 文件用于定义管道。

    • 生成 Kubernetes 清单文件。 这些文件是根据你所做的选择通过合成 deployment.ymlservice.yml 模板生成的。 准备就绪后,选择“保存并运行”。

  16. 选择“保存并运行”。

  17. 可将“提交消息”更改为类似于“将管道添加到我们的存储库”的内容。 准备就绪后,选择“保存并运行”以将新管道提交到存储库中,然后开始首次运行新管道!

查看应用部署

管道运行后,请依次观察生成阶段和部署阶段,管道的状态将从蓝色(正在运行)变为绿色(已完成)。 可以选择阶段和作业来观察管道的运作方式。

备注

如果你正在使用 Microsoft 托管的代理,则必须将 Microsoft 托管代理的 IP 范围添加到防火墙。 从每周三发布的每周 JSON 文件中获取 IP 范围的每周列表。 新的 IP 范围将在下周一开始生效。 有关详细信息,请参阅 Microsoft 托管的代理。 若要查找你的 Azure DevOps 组织所需的 IP 范围,请了解如何识别 Microsoft 托管代理的可能 IP 范围

管道运行完成后,浏览发生的情况,然后查看部署的应用。 在管道摘要中:

  1. 选择“环境”选项卡。

  2. 选择“查看环境”。

  3. 选择部署到的命名空间的应用实例。 如果你使用默认值,则它是默认命名空间中的 myapp 应用。

  4. 选择“服务”选项卡。

  5. 选择外部 IP 地址并将其复制到剪贴板。

  6. 打开新的浏览器标签页或窗口并输入“<IP 地址>:8080”。

如果你正在生成我们的示例应用,则浏览器中会显示“Hello world”。

管道如何生成

在你选择完选项并继续验证和配置管道后,Azure Pipelines 会使用“部署到 Azure Kubernetes 服务”模板为你创建一个管道。

生成阶段使用 Docker 任务生成映像并将其推送到 Azure 容器注册表。

- stage: Build
  displayName: Build stage
  jobs:  
  - job: Build
    displayName: Build job
    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)

    - task: PublishPipelineArtifact@1
      inputs:
        artifactName: 'manifests'
        path: 'manifests'

部署作业使用 Kubernetes 清单任务创建所需的 imagePullSecret,供 Kubernetes 群集节点从 Azure 容器注册表资源中拉取映像。 然后,Kubernetes 清单任务使用清单文件部署到 Kubernetes 群集。 清单文件 service.ymldeployment.yml 是在使用“部署到 Azure Kubernetes 服务”模板时生成的。

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  jobs:
  - deployment: Deploy
    displayName: Deploy job
    pool:
      vmImage: $(vmImageName)
    environment: 'myenv.aksnamespace' #customize with your environment
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadPipelineArtifact@2
            inputs:
              artifactName: 'manifests'
              downloadPath: '$(System.ArtifactsDirectory)/manifests'

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

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

清理资源

每当处理完所创建的资源后,都可以使用以下命令将其删除:

az group delete --name myapp-rg

出现提示时输入 y

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019

使用 Azure Pipelines 自动部署到 Azure Kubernetes 服务 (AKS)。 利用 Azure Pipelines,可以使用 Azure DevOps 通过持续集成 (CI) 和持续交付 (CD) 来进行生成、测试和部署。

本文介绍如何创建一个持续生成和部署应用的管道。 每当你更改包含 Dockerfile 的存储库中的代码时,都会将映像推送到 Azure 容器注册表,然后将清单部署到 AKS 群集。

先决条件

获取代码

创建包含示例应用程序和 Dockerfile 的以下存储库的分支:

https://github.com/MicrosoftDocs/pipelines-javascript-docker

创建 Azure 资源

使用 Azure CLI 登录到 Azure 门户

az cloud set -n AzureChinaCloud
az login

创建容器注册表

# Create a resource group
az group create --name myapp-rg --location chinaeast2

# Create a container registry
az acr create --resource-group myapp-rg --name mycontainerregistry --sku Basic

# Create a Kubernetes cluster
az aks create \
    --resource-group myapp-rg \
    --name myapp \
    --node-count 1 \
    --enable-addons monitoring \
    --generate-ssh-keys 

配置身份验证

将 Azure 容器注册表 (ACR) 与 Azure Kubernetes 服务 (AKS) 结合使用时,必须建立身份验证机制。 可通过两种方式实现此目的:

  1. 授予 AKS 对 ACR 的访问权限。 请参阅从 Azure Kubernetes 服务向 Azure 容器注册表进行身份验证

  2. 使用 Kubernetes 映像拉取机密。 可以使用 Kubernetes 部署任务创建映像拉取机密。

创建发布管道

用于设置 CI 的生成管道已经生成了一个 Docker 映像并将其推送到了 Azure 容器注册表。 它还打包了一个 Helm 图表并将其作为项目发布。 在发布管道中,我们将容器映像作为 Helm 应用程序部署到 AKS 群集。

  1. 在“Azure Pipelines”中打开生成摘要。

  2. 在生成摘要中,选择“发布”图标以启动新的发布管道。

    如果事先已创建了一个使用这些生成工件的发布管道,则系统将提示你创建新的发布。 在这种情况下,请转到“发布”页,并在该页中选择 + 图标启动新的发布管道。

  3. 选择“空作业”模板。

  4. 打开“任务”页并选择“代理作业”。

  5. 选择 + 以添加新任务并添加一个“Helm 工具安装程序”任务。 这可以确保运行后续任务的代理上安装了 Helm 和 Kubectl。

  6. 再次选择 + 并添加一个“打包并部署 Helm 图表”任务。 如下所述配置此任务的设置:

    • 连接类型:选择“Azure 资源管理器”以使用 Azure 服务连接连接到 AKS 群集。 或者,若要使用 kubeconfig 或服务帐户连接到任何 Kubernetes 群集,可以选择“Kubernetes 服务连接”。 在这种情况下,需要改为根据以下设置创建并选择 Azure 订阅的 Kubernetes 服务连接。

    • Azure 订阅:从“可用 Azure 服务连接”下面的列表中选择一个连接,或者与 Azure 订阅创建权限受限程度更严格的连接。 如果在输入旁边看到了“授权”按钮,请使用它来授权与 Azure 订阅的连接。 如果在订阅列表中未看到所需的 Azure 订阅,请参阅创建 Azure 服务连接以手动设置连接。

    • 资源组:输入或选择包含你的 AKS 群集的资源组。

    • Kubernetes 群集:输入或选择你创建的 AKS 群集。

    • 命令:选择“init”作为 Helm 命令。 这会将 Tiller 安装到正在运行的 Kubernetes 群集中。 此外还会设置任何所需的本地配置。 勾选“使用 Canary 映像版本”以安装最新的预发行版 Tiller。 如果 Tiller 已预先安装,则还可以通过勾选“升级 Tiller”来升级它。 如果启用了这些选项,则该任务将运行 helm init --canary-image --upgrade

  7. 在“代理作业”中选择 +,然后添加另一个“打包并部署 Helm 图表”任务。 如下所述配置此任务的设置:

    • Kubernetes 群集:输入或选择你创建的 AKS 群集。

    • 命名空间:输入要在其中部署应用程序的 Kubernetes 群集命名空间。 Kubernetes 支持由同一个物理群集提供支持的多个虚拟群集。 这些虚拟群集称为命名空间。 可以使用命名空间在同一个群集中创建不同的环境,例如开发、测试和过渡。

    • 命令:选择“upgrade”作为 Helm 命令。 可以使用此任务运行任何 Helm 命令,并将命令选项作为参数传递。 选择“upgrade”时,任务将显示更多字段:

      • 图表类型:选择“文件路径”。 或者,若要指定 URL 或图表名称,可以指定“图表名称”。 例如,如果图表名称为 stable/mysql,则任务将执行 helm upgrade stable/mysql

      • 图表路径:可以是已打包图表的路径,也可以是已解包图表目录的路径。 在本示例中,你将使用 CI 生成来发布图表,因此请使用文件选取器选择文件包,或输入 $(System.DefaultWorkingDirectory)/**/*.tgz

      • 发布名称:输入发布名称;例如 azuredevops

      • 重新创建 Pod:如果在发布期间进行了配置更改,并且你希望将正在运行的 Pod 替换为新配置,请勾选此复选框。

      • 重置值:如果你希望用图表中的内置值替代任务提供的所有值,请勾选此复选框。

      • 强制:如果发生冲突,并且你希望进行升级和回滚以删除再重新建资源,然后重新安装完整发布,请勾选此复选框。 如果应用修补程序的操作可能失败(例如,由于群集 IP 地址不可变而无法在服务中执行此操作),则此选项很有用。

      • 参数:输入 Helm 命令参数及其值;对于此示例--set image.repository=$(imageRepoName) --set image.tag=$(Build.BuildId) 请参阅此部分了解我们为何使用这些参数。

      • 启用 TLS:勾选此复选框可以在 Helm 与 Tiller 之间启用基于 TLS 的强连接。

      • CA 证书:指定要上传的并用来为 Tiller 和 Helm 客户端颁发证书的 CA 证书。

      • 证书:指定 Tiller 证书或 Helm 客户端证书

      • 密钥:指定 Tiller 密钥或 Helm 客户端密钥

  8. 在管道的“变量”页中,添加一个名为 imageRepoName 的变量并将值设置为你的 Helm 映像存储库名称。 通常,此名称的格式为 example.azurecr.cn/coderepository

  9. 保存发布管道。

Helm 升级任务中使用的参数

在生成管道中,容器映像带有 $(Build.BuildId) 标记,将推送到 Azure 容器注册表。 在 Helm 图表中,可以参数化容器映像详细信息(例如名称和标记),因为可以使用同一映像部署到不同的环境。 也可以在 values.yaml 文件中指定这些值,或者通过用户提供的值文件替代这些值,而在 Helm 安装或升级期间,此文件又会由 --set 参数替代。

在本示例中,我们传递以下参数:

--set image.repository=$(imageRepoName) --set image.tag=$(Build.BuildId)

$(imageRepoName) 的值是在“变量”页(或 YAML 文件的 variables 节)中设置的。 或者,可以直接在 --set 参数值或 values.yaml 文件中将其替换为你的映像存储库名称。 例如:

  image:
    repository: VALUE_TO_BE_OVERRIDDEN
    tag: latest

另一种方法是设置任务的“设置值”选项,以将参数值指定为逗号分隔的键值对。

创建发布以部署应用

现已准备好创建发布,这意味着,使用特定生成所生成的项目来启动运行发布管道的过程。 这会导致部署生成:

  1. 选择“+ 发布”,然后选择“创建发布”。

  2. 在“创建新发布”面板中,检查你要使用的项目版本是否已选中,然后选择“创建”。

  3. 选择信息栏消息中的发布链接。 例如:“发布 Release-1 已创建”。

  4. 在管道视图中,选择管道阶段中的状态链接以查看日志和代理输出。