你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Pipelines 生成和部署 HPC 解决方案

Azure DevOps 工具可以自动生成和测试 Azure Batch 高性能计算 (HPC) 解决方案。 Azure Pipelines 提供了新式持续集成 (CI) 和持续部署 (CD) 进程,用于生成、部署、测试和监视软件。 这些流程加快了软件交付,使你能够专注于代码,而不是基础结构和操作支持。

本文介绍如何使用 Azure Pipelines 和 Azure 资源管理器模板(ARM 模板)设置 CI/CD 进程,用于在 Azure Batch 上部署 HPC 解决方案。 在此示例中,创建了一个生成和发布管道,用于部署 Azure Batch 基础结构并发布应用程序包。 下图显示了一般部署流,假设代码在本地开发:

显示管道中的部署流的关系图。

必备条件

若要执行本文中的步骤,必须提供:

准备解决方案

本文中的示例使用多个 ARM 模板和现有的开源视频处理应用程序 FFmpeg。 可以复制或下载这些资源并将资源推送到 Azure Repos 存储库。

重要

此示例在基于 Windows 的 Batch 节点上部署 Windows 软件。 Azure Pipelines、ARM 模板和 Batch 还全面支持 Linux 软件和节点。

了解 ARM 模板

三个功能模板(类似于单元或模块)用于实施特定功能。 然后,端到端解决方案模板部署基础功能模板。 此链接模板结构允许单独测试每个功能模板并跨解决方案重复使用这些模板。

显示使用 ARM 模板的链接模板结构的关系图。

有关模板的详细信息,请参阅 Microsoft.Batch 资源类型的资源管理器模板参考指南

存储帐户模板

将以下代码保存为名为 storageAccount.json 的文件。 此模板定义用于将应用程序部署到 Batch 帐户的 Azure 存储帐户。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "accountName": {
            "type": "string",
            "metadata": {
                 "description": "Name of the Azure Storage Account"
             }
         }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[parameters('accountName')]",
            "sku": {
                "name": "Standard_LRS"
            },
            "apiVersion": "2018-02-01",
            "location": "[resourceGroup().location]",
            "properties": {}
        }
    ],
    "outputs": {
        "blobEndpoint": {
          "type": "string",
          "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('accountName'))).primaryEndpoints.blob]"
        },
        "resourceId": {
          "type": "string",
          "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('accountName'))]"
        }
    }
}

Batch 帐户模板

将以下代码保存为名为 batchAccount.json 的文件。 此模板定义 Batch 帐户。 Batch 帐户充当跨运行多个应用程序的平台。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "batchAccountName": {
           "type": "string",
           "metadata": {
                "description": "Name of the Azure Batch Account"
            }
        },
        "storageAccountId": {
           "type": "string",
           "metadata": {
                "description": "ID of the Azure Storage Account"
            }
        }
    },
    "variables": {},
    "resources": [
        {
            "name": "[parameters('batchAccountName')]",
            "type": "Microsoft.Batch/batchAccounts",
            "apiVersion": "2017-09-01",
            "location": "[resourceGroup().location]",
            "properties": {
              "poolAllocationMode": "BatchService",
              "autoStorage": {
                  "storageAccountId": "[parameters('storageAccountId')]"
              }
            }
          }
    ],
    "outputs": {}
}

Batch 池模板

将以下代码保存为名为 batchAccountPool.json 的文件。 此模板在 Batch 帐户中创建节点池和节点。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "batchAccountName": {
           "type": "string",
           "metadata": {
                "description": "Name of the Azure Batch Account"
           }
        },
        "batchAccountPoolName": {
            "type": "string",
            "metadata": {
                 "description": "Name of the Azure Batch Account Pool"
             }
         }
    },
    "variables": {},
    "resources": [
        {
            "name": "[concat(parameters('batchAccountName'),'/', parameters('batchAccountPoolName'))]",
            "type": "Microsoft.Batch/batchAccounts/pools",
            "apiVersion": "2017-09-01",
            "properties": {
                "deploymentConfiguration": {
                    "virtualMachineConfiguration": {
                        "imageReference": {
                            "publisher": "MicrosoftWindowsServer",
                            "offer": "WindowsServer",
                            "sku": "2022-datacenter",
                            "version": "latest"
                        },
                        "nodeAgentSkuId": "batch.node.windows amd64"
                    }
                },
                "vmSize": "Standard_D2s_v3"
            }
          }
    ],
    "outputs": {}
}

业务流程协调程序模板

将以下代码保存为名为 deployment.json 的文件。 最终模板充当业务流程协调程序,用于部署三个基础功能模板。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "StorageContainerUri": {
           "type": "string",
           "metadata": {
                "description": "URI of the Blob Storage Container containing the Azure Resource Manager templates"
            }
        },
        "StorageContainerSasToken": {
           "type": "string",
           "metadata": {
                "description": "The SAS token of the container containing the Azure Resource Manager templates"
            }
        },
        "applicationStorageAccountName": {
            "type": "string",
            "metadata": {
                 "description": "Name of the Azure Storage Account"
            }
         },
        "batchAccountName": {
            "type": "string",
            "metadata": {
                 "description": "Name of the Azure Batch Account"
            }
         },
         "batchAccountPoolName": {
             "type": "string",
             "metadata": {
                  "description": "Name of the Azure Batch Account Pool"
              }
          }
    },
    "variables": {},
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "storageAccountDeployment",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                  "uri": "[concat(parameters('StorageContainerUri'), 'arm-templates/storageAccount.json', parameters('StorageContainerSasToken'))]",
                  "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "accountName": {"value": "[parameters('applicationStorageAccountName')]"}
                }
            }
        },
        {
            "apiVersion": "2017-05-10",
            "name": "batchAccountDeployment",
            "type": "Microsoft.Resources/deployments",
            "dependsOn": [
                "storageAccountDeployment"
            ],
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                  "uri": "[concat(parameters('StorageContainerUri'), 'arm-templates/batchAccount.json', parameters('StorageContainerSasToken'))]",
                  "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "batchAccountName": {"value": "[parameters('batchAccountName')]"},
                    "storageAccountId": {"value": "[reference('storageAccountDeployment').outputs.resourceId.value]"}
                }
            }
        },
        {
            "apiVersion": "2017-05-10",
            "name": "poolDeployment",
            "type": "Microsoft.Resources/deployments",
            "dependsOn": [
                "batchAccountDeployment"
            ],
            "properties": {
                "mode": "Incremental",
                "templateLink": {
                  "uri": "[concat(parameters('StorageContainerUri'), 'arm-templates/batchAccountPool.json', parameters('StorageContainerSasToken'))]",
                  "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "batchAccountName": {"value": "[parameters('batchAccountName')]"},
                    "batchAccountPoolName": {"value": "[parameters('batchAccountPoolName')]"}
                }
            }
        }
    ],
    "outputs": {}
}

设置存储库

将 ARM 模板、FFmpeg 应用和 YAML 生成定义文件上传到 Azure Repos 存储库。

  1. 将四个 ARM 模板上传到存储库中的 arm-templates 文件夹。

  2. 对于应用程序包,下载并提取 Windows 64 位版本的 FFmpeg 4.3.1,然后将其上传到存储库中的 hpc-application 文件夹。

  3. 对于生成定义,请将以下定义保存为名为 hpc-app.build.yml 的文件,并将其上传到存储库中的 pipelines 文件夹。

    # To publish an application into Batch, you need to
    # first zip the file, and then publish an artifact, so
    # you can take the necessary steps in your release pipeline.
    steps:
    # First, zip up the files required in the Batch account.
    # For this instance, those are the ffmpeg files.
    - task: ArchiveFiles@2
      displayName: 'Archive applications'
      inputs:
        rootFolderOrFile: hpc-application
        includeRootFolder: false
        archiveFile: '$(Build.ArtifactStagingDirectory)/package/$(Build.BuildId).zip'
    # Publish the zip file, so you can use it as part
    # of your Release pipeline later.
    - task: PublishPipelineArtifact@0
      inputs:
        artifactName: 'hpc-application'
        targetPath: '$(Build.ArtifactStagingDirectory)/package'
    

设置完存储库后,文件夹结构应包含以下主要部分:

  • 包含 ARM 模板的 arm 模板文件夹。
  • 包含 ffmpeg 的 hpc-application 文件夹。
  • 包含生成管道的 YAML 生成定义文件的管道文件夹。

存储库结构的屏幕截图。

注意

此代码库结构示例演示了可以将应用程序、基础结构和管道代码存储在同一存储库中。

创建 Azure 管道

设置源代码存储库后,请使用 Azure Pipelines 为应用程序实施生成、测试和部署管道。 在管道的此阶段中,通常会运行测试来验证代码并生成软件的某些部分。 测试的数量和类型以及运行的任何其他任务取决于总体范围的生成和发布策略。

创建生成管道

本节内容关于创建一个 YAML 生成管道以使用 Batch 帐户中运行的 ffmpeg 软件。

  1. 在你的 Azure DevOps 项目中,选择左侧导航中的“管道”,然后选择“新管道”。

  2. 在“你的代码位于何处”屏幕上,选择“Azure Repos Git”。

    “新管道”屏幕的屏幕截图。

  3. 在“选择存储库”屏幕上,选择存储库。

    注意

    你也可以使用可视设计器创建生成管道。 在“新管道”页上,选择“使用经典编辑器”。 可在可视化设计器中使用 YAML 模板。 有关详细信息,请参阅定义经典管道

  4. 在“ 配置管道”屏幕上,选择“现有 Azure Pipelines YAML 文件”。

  5. 在“选择现有 YAML 文件”屏幕上,从存储库中选择 hpc-app.build.yml 文件,然后选择“继续”。

  6. 在“查看管道 YAML”屏幕上,查看生成配置,然后选择“运行”,或选择“运行”旁边的下拉插入符号,最后选择“保存”。 此模板支持持续集成,因此如果向存储库提交的新提交满足生成中设置的条件时,将自动触发生成。

    现有生成管道的屏幕截图。

  7. 可以查看实时生成进度更新。 若要查看生成结果,请从 Azure Pipelines 的生成定义中选择相应的运行。

    Azure Pipelines 中生成产生的实时输出屏幕截图。

注意

如果使用客户端应用程序运行 HPC 解决方案,则需要为该应用程序创建单独的生成定义。 有关操作指南,请参阅 Azure Pipelines 文档。

创建发布管道

使用 Azure Pipelines 发布管道来部署应用程序和底层基础结构。 发布管道启用 CD 并自动执行发布进程。 部署应用程序和底层基础结构需要执行几个步骤。

应可从公共 HTTP 或 HTTPS 终结点访问此解决方案的链接模板。 该终结点可以是 GitHub 存储库、Azure Blob 存储帐户或其他存储位置。 若要确保上传的模板项目安全,请将它们在专用模式下保存,但是要使用某种形式的共享访问签名 (SAS) 令牌进行访问。

以下示例演示了如何使用 Azure 存储 blob 中的模板部署基础结构。

设置管道

  1. 在 Azure DevOps 项目中,在左侧导航栏中选择“管道>发布”。

  2. 在下一个屏幕上,选择“新建>新发布管道”。

  3. 在“选择模板”屏幕上,选择“空作业”,然后关闭“阶段”屏幕。

  4. 选择页面顶部的“新发布管道”,并将管道重命名为与管道相关的内容,例如“部署 Azure Batch + 池”。

    初始发布管道的屏幕截图。

  5. 在“项目”部分,选择“添加”。

  6. 在“添加项目”屏幕上,选择“生成”,然后选择生成管道以获取 HPC 应用程序的输出。

    注意

    可以创建源别名或接受默认值。 记录下源别名值,因为它将用于在发布定义中创建任务。

    屏幕截图显示在生成管道中指向 hpc-application 程序包的项目链接。

  7. 选择 添加

  8. 在管道页上,选择“项目”旁的“添加”以创建指向另一个项目(Azure Repos 存储库)的链接。 此链接用于访问存储库中的 ARM 模板。 ARM 模板不需要编译,因此无需通过生成管道推送。

    注意

    请再次记下“源别名”值,以便稍后使用。

    屏幕截图显示指向 Azure Repos 存储库的项目链接。

  9. 选择“变量”选项卡。在管道中创建以下变量,因而无需将相同信息重新输入到多个任务中。

    名称 Value
    applicationStorageAccountName 用于保存 HPC 应用程序二进制文件的存储帐户的名称。
    batchAccountApplicationName Batch 帐户中应用程序的名称。
    batchAccountName Batch 帐户的名称。
    batchAccountPoolName 用于执行进程的虚拟机池的名称。
    batchApplicationId Batch 应用程序的唯一 ID,其格式为:
    /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>^
    /providers/Microsoft.Batch/batchAccounts/<batchAccountName>^
    /applications/<batchAccountApplicationName>.

    <subscriptionId> 占位符替换为 Azure 订阅 ID,将其他占位符替换成专为此列表中其他变量设置的值。
    batchApplicationVersion 本例中 Batch 应用程序的语义版本为 4.3.1
    location 要部署的资源的 Azure 区域。
    resourceGroupName 要在其中部署资源的资源组名称。
    storageAccountName 用于保存链接 ARM 模板的存储帐户名称。
    StorageContainerSasToken $(<referenceName>.StorageContainerSasToken). 将 <referenceName 占位符替换为在以下“Azure 文件复制”步骤的“输出变量”部分配置的“引用名称”值。
    StorageContainerUri $(<referenceName>.StorageContainerUri). 将 <referenceName> 占位符替换为在“Azure 文件复制”步骤的“输出变量”部分配置的“引用名称”值。

    屏幕截图显示为 Azure Pipelines 发布设置的变量。

  10. 选择“任务”选项卡,然后选择“代理作业”。

  11. 在“代理作业”屏幕的“代理池”下,选择“Azure Pipelines”。

  12. 在“代理规范”下,选择“windows-latest”。

    屏幕截图显示代理作业设置。

添加任务

创建六个任务用于以下操作:

  • 下载压缩的 ffmpeg 文件。
  • 部署用于托管嵌套式 ARM 模板的存储帐户。
  • 将 ARM 模板复制到存储帐户。
  • 部署 Batch 帐户和所需的依赖项。
  • 在 Batch 帐户中创建应用程序。
  • 将应用程序包上传到 Batch 帐户。

对于以下步骤指定的每个新任务:

  1. 在左窗格中选择“代理作业”旁的 + 符号。

  2. 在右窗格中搜索并选择指定的任务。

  3. 添加或选择用于配置任务的属性。

  4. 选择 添加

    屏幕截图显示用于将 HPC 应用程序发布到 Azure Batch 的任务。

按如下所示创建任务:

  1. 添加“下载管道工件”任务,并设置以下属性:

    • 显示名称:输入“将 ApplicationPackage 下载到代理”。
    • 项目名称:输入“hpc-application”。
    • 目标目录:输入 $(System.DefaultWorkingDirectory)
  2. 创建用于存储 ARM 模板的 Azure 存储帐户。 可以使用现有存储帐户,但若要支持此自包含示例和内容隔离,需要生成专用存储帐户。

    选择“ARM 模板部署:资源组范围”任务,并设置以下属性:

    • 显示名称:输入部署 ARM 模板的存储帐户
    • Azure 资源管理器连接:选择合适的 Azure 订阅。
    • 订阅:选择合适的 Azure 订阅。
    • 操作 - 选择“创建或更新资源组”。
    • 资源组:输入 $(resourceGroupName)
    • 位置:输入 $(location)
    • 模板:输入 $(System.ArtifactsDirectory)/<AzureRepoArtifactSourceAlias>/arm-templates/storageAccount.json。 将 <AzureRepoArtifactSourceAlias> 占位符替换为前面记录的存储库源别名。
    • 替代模板参数:输入 -accountName $(storageAccountName)
  3. 将项目从源代码管理上传到存储帐户。 此 Azure 文件复制任务的部分任务将存储帐户容器 URI 和 SAS 令牌输出到变量,以便在后续步骤中重复使用。

    添加“Azure 文件复制”任务,并设置以下属性:

    • 显示名称:输入 AzureBlob 文件复制
    • 源:输入$(System.ArtifactsDirectory)/<AzureRepoArtifactSourceAlias>/arm-templates/。 将 <AzureRepoArtifactSourceAlias> 占位符替换为前面记录的存储库源别名。
    • Azure 订阅:选择合适的 Azure 订阅。
    • 目标类型:选择“Azure Blob”。
    • RM 存储帐户:输入 $(storageAccountName)
    • 容器名称:输入“模板”。
    • 引用名称:展开“输出变量”,然后输入“ffmpeg”。

    注意

    如果此步骤失败,请确保 Azure DevOps 组织在存储帐户中具有“存储 Blob 参与者”角色。

  4. 部署业务流程协调程序 ARM 模板以创建 Batch 帐户和池。 此模板包括存储帐户容器 URI 和 SAS 令牌的参数。 ARM 模板中所需的变量保存在发布定义的变量部分中,并通过 AzureBlob 文件复制任务进行了设置。

    选择“ARM 模板部署:资源组范围”任务,并设置以下属性:

    • 显示名称:输入“部署Azure Batch”。
    • Azure 资源管理器连接:选择合适的 Azure 订阅。
    • 订阅:选择合适的 Azure 订阅。
    • 操作 - 选择“创建或更新资源组”。
    • 资源组:输入 $(resourceGroupName)
    • 位置:输入 $(location)
    • 模板位置:选择“文件的 URL”。
    • 模板链接:输入 $(StorageContainerUri)arm-templates/deployment.json$(StorageContainerSasToken)
    • 替代模板参数:输入 -StorageContainerUri $(StorageContainerUri) -StorageContainerSasToken $(StorageContainerSasToken) -applicationStorageAccountName $(applicationStorageAccountName) -batchAccountName $(batchAccountName) -batchAccountPoolName $(batchAccountPoolName)

    常见的做法是使用 Azure Key Vault 任务。 如果与 Azure 订阅连接的服务主体设置了适当的访问策略,则它可以从 Key Vault 下载机密,并可在管道中用作变量。 使用关联值设置机密名称。 例如,可以在发布定义中使用 $(sshPassword) 来引用 sshPassword 机密。

  5. 调用 Azure CLI 在 Azure Batch 中创建应用程序。

    选择“Azure CLI”任务,并设置以下属性:

    • 显示名称:输入“在 Azure Batch 帐户中创建应用程序”。
    • Azure 资源管理器连接:选择合适的 Azure 订阅。
    • 脚本类型:选择“PowerShell Core”。
    • 脚本位置:选择“内联脚本”。
    • 内联脚本:输入 az batch application create --application-name $(batchAccountApplicationName) --name $(batchAccountName) --resource-group $(resourceGroupName)
  6. 调用 Azure CLI 将关联的包上传到应用程序,在本例中为 ffmpeg 文件。

    选择“Azure CLI”任务,并设置以下属性:

    • 显示名称:输入“将包上传到 Azure Batch 帐户”。
    • Azure 资源管理器连接:选择合适的 Azure 订阅。
    • 脚本类型:选择“PowerShell Core”。
    • 脚本位置:选择“内联脚本”。
    • 内联脚本:输入 az batch application package create --application-name $(batchAccountApplicationName) --name $(batchAccountName) --resource-group $(resourceGroupName) --version $(batchApplicationVersion) --package-file=$(System.DefaultWorkingDirectory)/$(Release.Artifacts.<AzureBuildArtifactSourceAlias>.BuildId).zip。 将 <AzureBuildArtifactSourceAlias> 占位符替换为前面记录的生成源别名。

    注意

    应用程序包的版本号设置为变量。 该变量允许覆盖早期版本的包,并允许手动控制推送到 Azure Batch 的包版本。

创建并运行该发布

  1. 创建完所有步骤后,选择管道页顶部的“保存”,然后选择“确定”。

  2. 在页面顶部选择“创建”。

  3. 若要查看实时发布状态,请选择页面顶部显示已创建发布的链接。

  4. 若要查看代理的日志输出,请将鼠标悬停在阶段上,然后选择“日志”按钮。

    屏幕截图显示发布的状态。

测试环境

设置环境后,确认以下测试是否成功运行。 将占位符替换为资源组和 Batch 帐户值。

连接到 Batch 帐户

通过命令提示符使用 Azure CLI 连接到新的 Batch 帐户。

  1. 通过 az login 登录到 Azure 帐户,并按照说明进行身份验证。
  2. 使用 az batch account login -g <resourceGroup> -n <batchAccount> 对 Batch 帐户进行身份验证。

列出可用的应用程序

az batch application list -g <resourceGroup> -n <batchAccount>

检查该池是否有效

az batch pool list

在命令输出中,记下要在下一个测试中调整的 currentDedicatedNodes 值。

调整池大小

运行以下命令以调整池的大小,以便有可用于作业和任务测试的计算节点。 将 <poolName> 占位符替换为池名称值,将 <targetNumber> 占位符替换为大于上一条命令输出中 currentDedicatedNodes 的数值。 运行 az batch pool list 命令检查状态,直到完成大小调整并显示目标节点数。

az batch pool resize --pool-id <poolname> --target-dedicated-nodes <target number>

后续步骤

请参阅以下教程了解如何通过简单应用程序与 Batch 帐户交互。