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

Azure VM 映像生成器服务 DevOps 任务(预览版)

适用于:✔️ Linux VM ✔️ 灵活规模集

本文中介绍如何使用 Azure DevOps 任务将生成工件注入到虚拟机 (VM) 映像中,以便能够安装并配置应用程序和操作系统。

重要

适用于 VM 映像生成器的 Azure DevOps 任务目前为预览版。 有关 beta 版本、预览版或尚未正式发布的版本的 Azure 功能所适用的法律条款,请参阅 Microsoft Azure 预览版的补充使用条款

DevOps 任务版本

此时,有两个 Azure VM 映像生成器 DevOps 任务:

先决条件

注意

VM 映像生成器任务当前不支持 Windows 重启或以管理员身份运行提升的命令。 也就是说,该任务不适用于需要这些功能的 Azure 虚拟桌面方案或 Windows 自定义项。 若要将 DevOps 与 VM 映像生成器一起使用,请将模板嵌套在 Azure 资源管理器任务中,并使用 Azure CLI 或 PowerShell 任务。

开始之前,必须:

  • 从 Visual Studio Marketplace 安装稳定的 DevOps 任务

  • 已创建一个 Azure DevOps Services(以前称为 Visual Studio Team Services 或 VSTS)帐户和一个生成管道。

  • 在管道使用的订阅中注册并启用 VM 映像生成器功能要求:

  • 在源映像资源组中创建标准 Azure 存储帐户。 可以使用其他资源组或存储帐户。 该存储帐户用于将生成工件从 DevOps 任务传输到映像。

    # Azure PowerShell
    $timeInt=$(get-date -UFormat "%s")
    $storageAccName="aibstorage"+$timeInt
    $location=westus
    # Create a storage account and blob in the resource group
    New-AzStorageAccount -ResourceGroupName $strResourceGroup -Name $storageAccName -Location $location -SkuName Standard_LRS
    
    # The Azure CLI
    location=westus
    scriptStorageAcc=aibstordot$(date +'%s')
    # Create a storage account and blob in the resource group
    az storage account create -n $scriptStorageAcc -g $strResourceGroup -l $location --sku Standard_LRS
    

向发布管道添加任务

  1. 选择“发布管道”>“编辑”。

  2. 在“用户代理”中选择加号 (+) 来添加和搜索“映像生成器”。

  3. 选择 添加

在以下部分中,设置任务属性。

Azure 订阅

在下拉列表中,选择希望 VM 映像生成器运行的订阅。 使用存储源映像的并且要在其中分发映像的订阅。 需要授权 VM 映像生成器参与者访问订阅或资源组。

资源组

请使用要将临时映像模板工件存储到的资源组。 创建模板工件时,将再创建一个临时 VM 映像生成器资源组 IT_<DestinationResourceGroup>_<TemplateName>_guid。 该临时资源组存储映像元数据,例如脚本。 任务结束时,将删除映像模板工件和临时 VM 映像生成器资源组。

位置

此位置是运行 VM 映像生成器的区域。 仅支持特定数量的区域。 源映像必须位于此位置。 例如,如果你使用 Azure Compute Gallery(以前称为“共享映像库”),则该区域中必须存在一个副本。

托管标识(必需)

VM 映像生成器需要一个托管标识,该标识用于读取源自定义映像,连接到 Azure 存储,以及创建自定义映像。 有关详细信息,请参阅了解 VM 映像生成器

虚拟网络支持

可以将创建的 VM 配置为位于特定的虚拟网络中。 在配置该任务时,请在“VNet 配置(可选)”输入字段中提供某个预先存在的子网的资源 ID。 如果不需要使用任何特定虚拟网络,则可省略资源 ID。 有关详细信息,请参阅 Azure VM 映像生成器服务网络选项

源映像必须采用支持的 VM 映像生成器操作系统。 可以在 VM 映像生成器从中运行的区域中选择现有的自定义映像:

  • 托管映像:传入资源 ID。 例如:

    /subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/images/<imageName>
    
  • Compute Gallery:传入映像版本的资源 ID。 例如:

    /subscriptions/$subscriptionID/resourceGroups/$sigResourceGroup/providers/Microsoft.Compute/galleries/$sigName/images/$imageDefName/versions/<versionNumber>
    

    如果需要获取最新的 Compute Gallery 版本,请使用 Azure PowerShell 或 Azure CLI 任务来获取它并设置 DevOps 变量。 在 VM 映像生成器 DevOps 任务中使用该变量。 有关详细信息,请参阅获取最新映像版本资源 ID 中的示例。

  • (市场)基础映像:使用热门映像的下拉列表,它始终使用支持的操作系统的最新版本。

    如果该列表中不包含基础映像,你可以使用 Publisher:Offer:Sku 指定确切的映像。

    (可选)基础映像版本 - 可以提供要使用的映像版本。 默认版本为 latest

自定义

以下部分介绍自定义任务的各种方法。

预配程序

最初支持两个自定义程序 - Shell 和 PowerShell。 仅支持内联。 如果你要下载脚本,可以传递内联命令。

请根据你的操作系统选择“PowerShell”或“Shell”。

Windows 更新任务

(仅适用于 Windows)自定义结束时,该任务将运行 Windows 更新。 它还会处理所需的重新启动操作。

该任务会运行以下 Windows 更新配置:

    "type": "WindowsUpdate",
    "searchCriteria": "IsInstalled=0",
    "filters": [
        "exclude:$_.Title -like '*Preview*'",
        "include:$true"

该任务将安装非预览版的重要 Windows 更新和建议的 Windows 更新。

处理重新启动

DevOps 任务当前不支持重新启动 Windows 生成。 如果尝试使用 PowerShell 代码重新启动,生成将失败。 不过,可以使用代码重新启动 Linux 生成。

生成路径

该任务能够将 DevOps 生成发布工件注入到映像中。 若要正常完成此过程,需要设置一个生成管道。 在发布管道设置中,添加生成工件的存储库。

Screenshot showing how to add an artifact in the release pipeline.

选择“生成路径”按钮,以选择要放在映像中的生成文件夹。 VM 映像生成器任务将复制该文件夹中的所有文件和目录。 创建映像时,VM 映像生成器会根据操作系统将这些文件和目录部署到不同的路径。

重要

添加存储库工件时,可能会发现目录名称带有下划线字符 (_) 前缀。 下划线可能会导致内联命令出现问题。 请务必在命令中使用适当的引号。

以下示例显示了这种命名结构:

Screenshot of a directory structure showing hierarchy.

  • 对于 Windows:文件存在于 C: 盘中。 创建了名为 buildArtifacts 的目录,其中包含 webapp 目录。

  • 对于 Linux:文件存在于 /tmp 目录中。 创建了 webapp 目录,其中包含所有文件和目录。 因为这是临时目录,所以必须将文件移出该目录。 否则,它们将被删除。

内联自定义脚本

  • 对于 Windows:可以输入逗号分隔的 PowerShell 内联命令。 如果你要在生成目录中运行脚本,可以使用:

    & 'c:\buildArtifacts\webapp\webconfig.ps1'
    

    可以引用多个脚本,也可以添加更多命令。 例如:

    & 'c:\buildArtifacts\webapp\webconfig.ps1'
    & 'c:\buildArtifacts\webapp\installAgent.ps1'
    
  • 对于 Linux:生成工件放在 /tmp 目录中。 但是,在许多 Linux 操作系统上,重新启动后会删除 /tmp 目录内容。 如果你希望将工件放在映像中,则必须创建另一个目录,并将工件复制到该目录。 例如:

    sudo mkdir /lib/buildArtifacts
    sudo cp -r "/tmp/_ImageBuilding/webapp" /lib/buildArtifacts/.
    

    如果你不介意使用 /tmp 目录,则可以使用以下代码运行脚本:

    # Grant execute permissions to run scripts
    sudo chmod +x "/tmp/_ImageBuilding/webapp/coreConfig.sh"
    echo "running script"
    sudo . "/tmp/AppsAndImageBuilderLinux/_WebApp/coreConfig.sh"
    

生成映像后,生成工件会发生什么情况?

注意

VM 映像生成器不会自动删除生成工件。 强烈建议你始终使用代码来删除生成工件。

  • 对于 Windows:VM 映像生成器将文件部署到 C:\buildArtifacts 目录中。 由于该目录是永久保存的,因此必须通过运行脚本将其删除。 例如:

    # Clean up buildArtifacts directory
    Remove-Item -Path "C:\buildArtifacts\*" -Force -Recurse
    
    # Delete the buildArtifacts directory
    Remove-Item -Path "C:\buildArtifacts" -Force
    
  • 对于 Linux:生成工件放在 /tmp 目录中。 但是,在许多 Linux 操作系统中,重新启动后会删除 /tmp 目录内容。 建议使用代码删除这些内容,而不要依赖操作系统来删除它们。 例如:

    sudo rm -R "/tmp/AppsAndImageBuilderLinux"
    

映像生成的总时长

目前无法在 DevOps 管道任务中更改总时长。 映像生成使用的默认值为 240 分钟。 如果你要增大 buildTimeoutInMinutes,可以在发布管道中使用 Azure CLI 任务。 将该任务配置为复制并提交某个模板。 有关示例解决方案,请参阅将环境变量和参数与 VM 映像生成器配合使用,或使用 Azure PowerShell。

存储帐户

选择在先决条件部分创建的存储帐户。 如果列表中未显示该存储帐户,则表示 VM 映像生成器对该存储帐户没有权限。

生成开始时,VM 映像生成器会创建名为 imagebuilder-vststask 的容器,其中存储来自存储库的生成工件。

注意

每次生成后,都需要手动删除存储帐户或容器。

分发

支持以下三种分布类型。

托管映像

  • 资源 ID:

    /subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/images/<imageName>
    
  • 位置

Compute Gallery 必须已存在。

  • 资源 ID:

    /subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/galleries/<galleryName>/images/<imageDefName>
    
  • 区域:以逗号分隔的区域列表。 例如 westuseastuscentralus

虚拟硬盘

无法将任何值传递给此虚拟硬盘。 VM 映像生成器将虚拟硬盘 VHD 发送到 vhds 容器中的临时 VM 映像生成器资源组 IT_<DestinationResourceGroup>_<TemplateName>。 开始版本生成时,VM 映像生成器会发出日志。 VM 映像生成器完成后,它会发出 VHD URL。

可选设置

可以根据默认的 VM 大小 Standard_D1_v2 替代 VM 大小设置。 你可能希望这样做以减少总自定义时间。 或者,也可能希望创建依赖于特定 VM 大小的映像,例如 GPU(图形处理单元)、HPC(高性能计算)等。

任务的工作原理

创建发布时,该任务将在存储帐户中创建名为 imagebuilder-vststask 的容器。 该任务将以 zip 格式压缩并上传生成工件,并为 zip 文件创建共享访问签名令牌。

该任务使用传递给它的属性创建 VM 映像生成器模板工件。 该任务执行以下操作:

  • 下载生成工件 zip 文件以及任何其他关联的脚本。 文件保存在临时 VM 映像生成器资源组 IT_<DestinationResourceGroup>_<TemplateName> 的某个存储帐户中。

  • 创建名称前缀为 t_ 后接 10 位数单调整数的模板。 该模板将保存到所选资源组中,并且生成期间在资源组中存在。

示例输出:

start reading task parameters...
found build at:  /home/vsts/work/r1/a/_ImageBuilding/webapp
end reading parameters
getting storage account details for aibstordot1556933914
created archive /home/vsts/work/_temp/temp_web_package_21475337782320203.zip
Source for image:  { type: 'SharedImageVersion',
  imageVersionId: '/subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/galleries/<galleryName>/images/<imageDefName>/versions/<imgVersionNumber>' }
template name:  t_1556938436xxx
starting put template...

当映像生成开始时,发布日志中会报告运行状态:

starting run template...

当映像生成完成时,输出类似于以下文本:

2019-05-06T12:49:52.0558229Z starting run template...
2019-05-06T13:36:33.8863094Z run template:  Succeeded
2019-05-06T13:36:33.8867768Z getting runOutput for  SharedImage_distribute
2019-05-06T13:36:34.6652541Z ==============================================================================
2019-05-06T13:36:34.6652925Z ## task output variables ##
2019-05-06T13:36:34.6658728Z $(imageUri) =  /subscriptions/<subscriptionID>/resourceGroups/aibwinsig/providers/Microsoft.Compute/galleries/my22stSIG/images/winWAppimages/versions/0.23760.13763
2019-05-06T13:36:34.6659989Z ==============================================================================
2019-05-06T13:36:34.6663500Z deleting template t_1557146959485...
2019-05-06T13:36:34.6673713Z deleting storage blob imagebuilder-vststask\webapp/18-1/webapp_1557146958741.zip
2019-05-06T13:36:34.9786039Z blob imagebuilder-vststask\webapp/18-1/webapp_1557146958741.zip is deleted
2019-05-06T13:38:37.4884068Z delete template:  Succeeded

将删除映像模板和 IT_<DestinationResourceGroup>_<TemplateName>

可以获取 $(imageUri) Azure DevOps Services(以前称为 Visual Studio Team Services 或 VSTS)变量并在下一个任务中使用它,或者只使用该值并生成一个 VM。

输出 DevOps 变量

以下是源市场映像的发布者、产品/服务、SKU 和版本:

  • $(pirPublisher)
  • $(pirOffer)
  • $(pirSku)
  • $(pirVersion)

下面是映像 URI,它是分布式映像的资源 ID:

  • $(imageUri)

常见问题解答

是否可以使用我在 DevOps 外部创建的现有映像模板?

目前没有。

是否可以指定映像模板名称?

不知道。 系统使用唯一的模板名称,生成后将删除模板。

VM 映像生成器任务失败。 如何解决此问题?

如果生成失败,DevOps 任务不会删除暂存资源组。 你可以访问包含生成自定义日志的暂存资源组。

你会在 VM 映像生成器任务的 DevOps 日志中看到错误,消息将包含 customization.log 位置。 例如:

Screenshot of an example DevOps task error that describes the failure and provides the location of the customization.log file.

有关详细信息,请参阅排查 VM 映像生成器服务的问题

调查失败原因后,可以删除暂存资源组。 首先,删除 VM 映像生成器模板资源工件。 该工件的前缀为 t_,可以在 DevOps 任务生成日志中找到它:

...
Source for image:  { type: 'SharedImageVersion',
  imageVersionId: '/subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/galleries/<galleryName>/images/<imageDefName>/versions/<imgVersionNumber>' }
...
template name:  t_1556938436xxx
...

VM 映像生成器模板资源工件位于最初在任务中指定的资源组内。 完成故障排除后,请删除该工件。 如果要使用 Azure 门户删除工件,请在资源组中选择“显示隐藏的类型”以查看该工件。

后续步骤

有关详细信息,请参阅 VM 映像生成器概述