Azure 虚拟机规模集代理

Azure DevOps Services

Azure 虚拟机规模集代理(以下简称为“规模集代理”)是一种可根据需求自动缩放的自托管代理。 这种弹性可减少一直运行专用代理的需求。 与 Microsoft 托管的代理不同,你可以灵活地处理运行代理的计算机的大小和映像。

提示

托管 DevOps 池是一项新服务,是 Azure DevOps 虚拟机规模集代理池的演变,通过提高自定义池的可伸缩性和可靠性,进一步简化了自定义池创建。 托管 DevOps 池是一项完全托管服务,其中实时为代理提供支持的虚拟机或容器位于 Microsoft Azure 订阅中,而不位于你自己的 Azure 订阅中,就像使用 Azure DevOps 虚拟机规模集代理池时一样。 有关详细信息,请参阅托管 DevOps 池文档。

如果你喜欢 Microsoft 托管代理,但受其所提供的内容限制,则应考虑使用规模集代理。 下面是一些示例:

  • 与我们在本机 Microsoft 托管代理中所提供的内容相比,你需要更多内存、更多处理器、更多存储或更多 IO。
  • 你需要使用具有特定指令集的 NCv2 VM 进行机器学习。
  • 你需要部署到专用 VNET 中没有入站连接的专用 Azure 应用服务。
  • 你需要向特定 IP 地址打开企业防火墙,使 Microsoft 托管代理能够与你的服务器通信。
  • 你需要限制代理计算机的网络连接,并允许它们仅访问已批准的站点。
  • 你无法从 Microsoft 获取足够的代理来满足需求。
  • 你的作业超过了 Microsoft 托管的代理超时。
  • 你无法将 Microsoft 托管并行作业分区到组织中的各个项目或团队中。
  • 你想要在代理上运行多个连续作业,以利用增量源和计算机级包缓存。
  • 你想要在代理开始接受作业之前运行配置或缓存预热。

如果你喜欢自托管代理,但希望可以简化管理,则应考虑使用规模集代理。 下面是一些示例:

  • 你不希望全天候运行专用代理。 你想要取消预配未用于运行作业的代理计算机。
  • 你在管道中运行不受信任的代码,并希望在每个作业后对代理计算机重新设置映像。
  • 你想要简化针对代理的基础映像的定期更新。

注意

  • 你不能使用规模集运行 Mac 代理。 只能以这种方式运行 Windows 或 Linux 代理。

  • 仅 Azure 公有(全局服务)云支持对 Azure DevOps Services 使用虚拟机规模集。 目前,虚拟机规模集代理池不支持任何其他国家/地区云产品/服务

  • 不应将虚拟机规模集关联到多个池。

创建规模集

在准备创建规模集代理时,必须先在 Azure 门户中创建虚拟机规模集。 必须以某种方式创建虚拟机规模集,以便 Azure Pipelines 可以进行管理。 具体而言,必须禁用自动缩放,以便 Azure Pipelines 可以确定如何根据传入的管道作业数执行缩放。 建议使用以下步骤创建规模集。

在以下示例中,使用 UbuntuLTS VM 映像通过 Azure Cloud Shell 创建新的资源组和虚拟机规模集。

注意

在此示例中,UbuntuLTS VM 映像用于规模集。 如果需要将自定义 VM 映像作为代理的基础,请按照使用自定义映像、软件或磁盘大小创建规模集中的步骤在创建规模集之前创建自定义映像。

  1. https://shell.azure.com/ 中浏览到 Azure Cloud Shell

  2. 运行以下命令以验证默认 Azure 订阅。

    az account list -o table
    

    如果所需订阅未列为默认订阅,请选择所需的订阅。

    az account set -s <your subscription ID>
    
  3. 为虚拟机规模集创建资源组。

    az group create \
    --location westus \
    --name vmssagents
    
  4. 在资源组中创建虚拟机规模集。 在此示例中,指定了 Ubuntu2204 VM 映像。

    az vmss create \
    --name vmssagentspool \
    --resource-group vmssagents \
    --image Ubuntu2204 \
    --vm-sku Standard_D2_v4 \
    --storage-sku StandardSSD_LRS \
    --authentication-type SSH \
    --generate-ssh-keys \
    --instance-count 2 \
    --disable-overprovision \
    --upgrade-policy-mode manual \
    --single-placement-group false \
    --platform-fault-domain-count 1 \
    --load-balancer "" \
    --orchestration-mode Uniform
    

    注意

    Azure Pipelines 不支持规模集超量预配自动缩放。 确保已为规模集禁用这两项功能。

    由于 Azure Pipelines 管理规模集,因此需要或建议使用以下设置:

    • --disable-overprovision - 必需
    • --upgrade-policy-mode manual - 必需
    • --load-balancer "" - Azure Pipelines 不需要负载均衡器来将作业路由到规模集代理池中的代理,但是可通过配置负载均衡器来获取规模集代理的 IP 地址,以用于防火墙规则。 另外,还可以使用 --public-ip-address 选项创建规模集,以此方式获取规模集代理的 IP 地址。 有关使用负载均衡器或公共 IP 地址配置规模集的详细信息,请参阅虚拟机规模集文档az vmss create
    • --instance-count 2 - 此设置并非必需,但该设置让你能够在创建代理池之前验证规模集是否完全正常运行。 创建这两个 VM 可能需要几分钟时间。 稍后,创建代理池时,Azure Pipelines 会删除这两个 VM 并创建新的 VM。

    重要

    如果在 Windows 上使用 Azure CLI 运行此脚本,则必须用单引号将 --load-balancer "" 中的 "" 括起来,如下所示:--load-balancer '""'

    如果 VM 大小支持临时操作系统磁盘,则用于启用临时操作系统磁盘的以下参数是可选的,但建议使用这些参数来缩短虚拟机重置映像时间。

    • --ephemeral-os-disk true
    • --os-disk-caching readonly

    重要

    并非所有 VM 大小都支持临时操作系统磁盘。 有关支持的 VM 大小列表,请参阅 Azure VM 的临时操作系统磁盘

    (从 Azure 市场或你自己的自定义映像中)选择任何 Linux 或 Windows 映像以创建规模集。 请勿在映像中预安装 Azure Pipelines 代理。 Azure Pipelines 在预配新虚拟机时自动安装代理。 在上面的示例中,我们使用了纯 UbuntuLTS 映像。 有关创建和使用自定义映像的说明,请参阅常见问题解答

    选择任何 VM SKU 和存储 SKU。

    注意

    许可注意事项限制我们分发 Microsoft 托管映像。 我们无法提供这些映像供你在规模集代理中使用。 但是,用于生成这些映像的脚本是开放源代码。 你可以自由使用这些脚本并创建自己的自定义映像。

  5. 创建规模集后,在 Azure 门户中导航到规模集并验证以下设置:

    • 升级策略 - 手动

      验证升级策略。

      还可以通过运行以下 Azure CLI 命令来验证此设置。

      az vmss show --resource-group vmssagents --name vmssagentspool --output table
      
      Name            ResourceGroup    Location    Zones    Capacity    Overprovision    UpgradePolicy
      --------------  ---------------  ----------  -------  ----------  ---------------  ---------------
      vmssagentspool  vmssagents       westus               0           False            Manual
      
    • 缩放 - 手动缩放

      验证手动缩放策略。

重要

Azure Pipelines 不支持实例保护。 请确保已禁用横向缩减和规模集操作实例保护。

业务流程模式

Azure 虚拟机规模集可以配置两种业务流程模式:统一和灵活。 Azure Pipelines 对统一业务流程模式的支持已正式发布,可供所有客户使用。

使用灵活业务流程模式,Azure Pipelines 能够并行对多个规模集操作进行排队。 Azure Pipelines 对灵活业务流程的支持会根据客户请求提供,而且还需要进行评估。 需要证明,使用此功能可给客户的使用模式带来显著益处。 此类客户需要有大型规模集,不重复使用多个作业的代理,并行运行多个短期作业,并在 VM 中专门使用临时磁盘。 若要使用此功能,请联系我们的支持团队

创建规模集代理池

  1. 导航到 Azure DevOps 项目设置,在“管道”下选择“代理池”,然后选择“添加池”以创建新的代理池。

    创建代理池。

    重要

    可以在“项目设置”或“组织设置”中创建规模集池,但在删除规模集池时,必须将其从“组织设置”(不是“项目设置”)中删除。

  2. 选择“Azure 虚拟机规模集”作为池类型。 选择包含规模集的 Azure 订阅,选择“授权”,然后从该订阅中选择所需的虚拟机规模集。 如果已有服务连接,则可以从列表(而不是订阅)中选择。

    重要

    • 若要配置规模集代理池,必须对所选订阅拥有所有者用户访问管理员权限。 如果你有其中一个权限,但在选择“授权”时收到错误,请参阅故障排除

    • 目前支持的唯一服务连接是基于服务主体密钥的 Azure 资源管理器 (ARM) 服务连接。 基于证书凭据或托管标识的 ARM 服务连接将失败。 尝试列出订阅中的现有规模集时,你将看到如下所示的错误:

      Invalid Service Endpoint with Id <guid> and Scope <guid>

  3. 从该订阅中选择所需的虚拟机规模集。

  4. 指定代理池的名称。

  5. 配置以下选项:

    • 每次使用后自动拆除虚拟机 - 新的 VM 实例将用于每个作业。 VM 在运行作业后脱机,并在选取另一个作业之前重置映像。
    • 保存运行不正常的代理以供调查 - 是否保存运行不正常的代理 VM以进行故障排除,而不是将其删除。
    • 规模集中的最大虚拟机数 - Azure Pipelines 将自动横向扩展代理数,但不会超过此限制。
    • 要保留在待机状态的代理数 - Azure Pipelines 将自动横向缩减代理数,但会确保始终有这些数量的代理可用于运行新作业。 如果将“要保留在待机状态的代理数”设置为 0(例如,为了节省少量作业的成本),Azure Pipelines 将仅在 VM 具有作业时启动 VM。
    • 删除多余空闲代理之前的延迟分钟数 - 考虑到一天中生成负载的变化,Azure Pipelines 将等待指定的持续时间,然后再删除多余的空闲代理。
    • 配置 VM 以运行交互式测试(仅限 Windows Server 操作系统)- Windows 代理可以配置为使用自动登录和交互式 UI 在不提升权限的情况下运行,也可以配置为使用提升的权限运行。 选中此框以使用交互式 UI 在提升权限的情况下运行。 在任一情况下,代理用户都是管理员组的成员。
  6. 配置设置后,选择“创建”以创建代理池。

使用规模集代理池

使用规模集代理池类似于任何其他代理池。 可以将其用于经典生成、发布或 YAML 管道中。 用户权限、管道权限、审批和其他检查的工作方式与任何其他代理池相同。 有关详细信息,请参阅代理池

重要

在直接对 Azure 门户中的规模集进行更改时,必须小心谨慎。

  • 不能更改 Azure 门户中的许多规模集配置设置。 Azure Pipelines 更新规模集的配置。 对规模集所做的任何手动更改都可能会干扰 Azure Pipelines 的操作。
  • 在没有先删除 Azure Pipelines 中的规模集池的情况下,最好不要重命名或删除规模集。

Azure Pipelines 如何管理规模集

创建规模集代理池后,Azure Pipelines 会自动缩放代理计算机。

Azure Pipelines 每隔 5 分钟对池中的代理和规模集中的虚拟机的状态进行一次采样。 决定横向缩减还是横向扩展,要取决于当时的空闲代理数。 如果代理处于联机状态且未运行管道作业,则会将其视为空闲。 如果满足以下任一条件,Azure Pipelines 将执行横向扩展操作:

  • 空闲代理数低于指定的备用代理数
  • 没有空闲代理来为队列中等待的管道作业提供服务

如果满足其中一个条件,Azure Pipelines 将增加 VM 的数量。 横向扩展的增量为最大池大小的特定百分比。 每个步骤允许 20 分钟来创建计算机。

当空闲代理数超过备用计数超过 30 分钟时,Azure Pipelines 会横向缩减代理数(可使用“删除多余空闲代理之前的延迟分钟数”进行配置)。

若要将所有这一切放在一个示例中,请考虑一个规模集代理池,该代理池配置有两个备用代理和四个最大代理。 例如,你希望在每次使用后拆除 VM。 此外,我们假设规模集中没有要开始使用的 VM。

  • 由于空闲代理数为 0,并且空闲代理数低于备用计数 2,因此 Azure Pipelines 横向扩展并将两个 VM 添加到规模集。 这些代理联机后,将有两个空闲代理。

  • 例如,一个管道作业到达并分配给其中一个代理。

  • 此时,空闲代理数为 1,小于备用计数 2。 因此,Azure Pipelines 横向扩展并添加另外 2 个 VM(此示例中使用的增量大小)。 此时,池有三个空闲代理和一个忙代理。

  • 例如,第一个代理上的作业已完成。 Azure Pipelines 使该代理脱机,以重置该计算机的映像。 几分钟后,它会返回一个全新的映像。 此时,我们将有四个空闲代理。

  • 如果 30 分钟内没有其他作业到达(可使用“删除多余空闲代理之前的延迟分钟数”进行配置),Azure Pipelines 将确定空闲代理的数量多于所需数量。 因此,会将池横向缩减为两个代理。

在整个操作中,Azure Pipelines 的目标是在待机时达到所需数量的空闲代理。 池缓慢横向扩展和缩减。 在一天时间里,当请求在早上排队时,池将横向扩展,随着负载在晚上减少,池便会横向缩减。 你会在不同时间观察到空闲代理的数量要多于所需数量,因为 Azure Pipelines 逐渐趋于你指定的约束。

注意

Azure Pipelines 可能需要一小时或更多时间在虚拟机中横向扩展或横向缩减。 Azure Pipelines 将逐步横向扩展,监视操作中的错误,并通过删除不可用的计算机并在一段时间内创建新计算机做出反应。 此纠正操作可能需要一个多小时。

为了实现最大的稳定性,规模集操作按顺序完成。 例如,如果池需要横向扩展,并且还需要删除运行不正常的计算机,Azure Pipelines 将首先横向扩展池。 横向扩展池以在待机时达到所需数量的空闲代理后,将删除运行不正常的计算机,具体取决于“保存运行不正常的代理以供调查”设置。 有关详细信息,请参阅运行不正常的代理

由于采样大小为 5 分钟,因此所有代理都可以在短时间内运行管道,并且不会进行横向扩展。

自定义管道代理配置

可以通过在规模集的操作系统自定义映像中定义环境变量来自定义 Azure Pipelines 代理的配置。 例如,对于 Windows,规模集代理工作目录默认为 C:\a,对于 Linux,默认为 /agent/_work。 如果要更改工作目录,请使用所需的工作目录替换名为 VSTS_AGENT_INPUT_WORK 的环境变量。 有关详细信息,请参阅 Pipelines 代理无人参与配置文档。 示例包括:

  • VSTS_AGENT_INPUT_WORK
  • VSTS_AGENT_INPUT_PROXYURL
  • VSTS_AGENT_INPUT_PROXYUSERNAME
  • VSTS_AGENT_INPUT_PROXYPASSWORD

重要

自定义 Pipelines 代理时,必须小心谨慎。 某些设置会与其他必需设置冲突,导致代理注册失败且 VM 被删除。 不应设置或更改这些设置:

  • VSTS_AGENT_INPUT_URL
  • VSTS_AGENT_INPUT_AUTH
  • VSTS_AGENT_INPUT_TOKEN
  • VSTS_AGENT_INPUT_USERNAME
  • VSTS_AGENT_INPUT_PASSWORD
  • VSTS_AGENT_INPUT_POOL
  • VSTS_AGENT_INPUT_AGENT
  • VSTS_AGENT_INPUT_RUNASSERVICE
  • ...以及与部署组相关的任何内容。

通过自定义脚本扩展自定义虚拟机启动

用户可能需要在其规模集代理计算机上执行启动脚本,然后这些计算机才会开始运行管道作业。 启动脚本的一些常见用例包括安装软件、预热缓存或提取存储库。 可以通过安装适用于 Windows 的自定义脚本扩展适用于 Linux 的自定义脚本扩展来执行启动脚本。

此扩展将在创建或重置映像后立即在规模集中的每个虚拟机上执行。 在执行 Azure Pipelines 代理扩展之前,将执行自定义脚本扩展。

下面是创建适用于 Linux 的自定义脚本扩展的示例。

az vmss extension set \
--vmss-name <scaleset name> \
--resource-group <resource group> \
--name CustomScript \
--version 2.0 \
--publisher Microsoft.Azure.Extensions \
--settings '{ \"fileUris\":[\"https://<myGitHubRepoUrl>/myScript.sh\"], \"commandToExecute\": \"bash ./myScript.sh /myArgs \" }'

下面是创建适用于 Windows 的自定义脚本扩展的示例。

az vmss extension set \
--vmss-name <scaleset name> \
--resource-group <resource group> \
--name CustomScriptExtension \
--version 1.9 \
--publisher Microsoft.Compute \
--settings '{ \"FileUris\":[\"https://<myGitHubRepoUrl>/myscript.ps1\"], \"commandToExecute\": \"Powershell.exe -ExecutionPolicy Unrestricted -File myscript.ps1 -myargs 0 \" }'

重要

自定义脚本扩展中执行的脚本必须返回退出代码 0,以便 VM 完成 VM 创建过程。 如果自定义脚本扩展引发异常或返回非零退出代码,则不会执行 Azure Pipeline 扩展,VM 也不会在 Azure DevOps 代理池中注册。

扩展可能会在预配所有 VM 资源之前运行,在这种情况下,你会看到类似于“基本先决条件安装失败”的错误。可以通过在脚本的开头添加 sleep 命令来解决此问题,例如,sleep 30

规模集代理的生命周期

下面是 Azure Pipelines 虚拟机规模集代理的操作流

  1. Azure DevOps 规模集代理池大小调整作业确定池的空闲代理太少,需要横向扩展。Azure Pipelines 调用 Azure 规模集以增加规模集容量。

  2. Azure 规模集开始创建新的虚拟机。 虚拟机运行后,Azure 规模集会按顺序执行任何已安装的 VM 扩展。

  3. 如果已安装自定义脚本扩展,则将在 Azure Pipelines 代理扩展之前执行。 如果自定义脚本扩展返回非零退出代码,则 VM 创建过程将中止并被删除。

  4. 执行 Azure Pipelines 代理扩展。 此扩展下载最新版本的 Azure Pipelines 代理以及最新版本的配置脚本。 可以在具有以下格式的 URL 中找到配置脚本:

    • Linux:https://vstsagenttools.blob.core.windows.net/tools/ElasticPools/Linux/<script_version>/enableagent.sh,例如,版本 15
    • Windows:https://vstsagenttools.blob.core.windows.net/tools/ElasticPools/Windows/<script_version>/enableagent.ps1,例如,版本 17
  5. 如果操作系统是 Windows Server 或 Linux,则配置脚本将创建名为 AzDevOps 的本地用户。 对于 Windows 10 客户端操作系统,代理以 LocalSystem 身份运行。 然后,该脚本将解压缩、安装和配置 Azure Pipelines 代理。 配置过程中,代理会在 Azure DevOps 代理池中注册,并以脱机状态显示在代理池列表中。

  6. 在大多数情况下,配置脚本会立即启动代理,以本地用户 AzDevOps 身份运行。 代理进入联机状态,且已准备好运行管道作业。

    如果为池配置了交互式 UI,则虚拟机将在配置代理后重新启动。 重新启动后,本地用户会自动登录并启动管道代理。 代理进入联机状态,且已准备好运行管道作业。

使用自定义映像、软件或磁盘大小创建规模集

如果只想使用公开可用的 Azure 映像创建具有默认 128 GB 操作系统磁盘的规模集,请直接跳到步骤 10,并使用公用映像名称(UbuntuLTS、Win2019DataCenter 等)创建规模集。 否则,请按照以下步骤自定义 VM 映像。

  1. 使用所需的操作系统映像创建 VM,并选择性地将操作系统磁盘大小从 128 GB 扩展到 <myDiskSizeGb>

    • 如果从可用的 Azure 映像开始,例如 <myBaseImage> = (Win2019DataCenter, UbuntuLTS):

      az vm create --resource-group <myResourceGroup> --name <MyVM> --image <myBaseImage> --os-disk-size-gb <myDiskSize>  --admin-username myUserName --admin-password myPassword
      
    • 如果从通用 VHD 开始:

      1. 首先使用具有所需大小的非托管磁盘创建 VM,然后转换为托管磁盘:

        az vm create --resource-group <myResourceGroup> --name <MyVM> --image <myVhdUrl> --os-type windows --os-disk-size-gb <myDiskSizeGb> --use-unmanaged-disk --admin-username <myUserName> --admin-password <myPassword> --storage-account <myVhdStorageAccount>
        
      2. 关闭 VM

        az vm stop --resource-group <myResourceGroup> --name <MyVM>
        
      3. 解除分配 VM

        az vm deallocate --resource-group <myResourceGroup> --name <MyVM>
        
      4. 转换为托管磁盘

        az vm convert --resource-group <myResourceGroup> --name <MyVM>
        
      5. 重启 VM

        az vm start --resource-group <myResourceGroup> --name <MyVM>
        
  2. 通过远程桌面(或 SSH)连接到 VM 的公共 IP 地址来自定义映像。 可能需要打开防火墙中的端口,以取消阻止 RDP (3389) 或 SSH (22) 端口。

    1. Windows - 如果 <MyDiskSizeGb> 大于 128 GB,请扩展操作系统磁盘大小以填充 <MyDiskSizeGb> 指定的磁盘大小。

      以管理员身份打开 DiskPart 工具并运行以下 DiskPart 命令:

      1. list volume(用于查看卷)
      2. select volume 2(取决于哪个卷是操作系统驱动器)
      3. extend size 72000(用于将驱动器扩展 72 GB,从 128 GB 扩展到 200 GB)
  3. 在 VM 上安装任何所需的额外软件。

  4. 若要自定义管道代理用户的权限,可以创建名为 AzDevOps 的用户,并授予该用户所需的权限。 如果此用户尚不存在,请通过规模集启动脚本创建此用户。

  5. 完成自定义后重新启动 VM

  6. 通用化 VM。

    • Windows - 从管理员控制台窗口:
      C:\Windows\System32\sysprep\sysprep.exe /generalize /oobe /shutdown
      
    • Linux
      sudo waagent -deprovision+user -force
      

    重要

    等待 VM 完成通用设置并关闭。 在 VM 停止之前不要继续操作。 允许 60 分钟。

  7. 解除分配 VM

    az vm deallocate --resource-group <myResourceGroup> --name <MyVM>
    
  8. 将 VM 标记为已完成通用设置。

    az vm generalize --resource-group <myResourceGroup> --name <MyVM>
    
  9. 根据通用映像创建 VM。 执行这些步骤以更新现有规模集映像时,请记下输出中的映像 ID URL。

    az image create  --resource-group <myResourceGroup> --name <MyImage> --source <MyVM>
    
  10. 基于自定义 VM 映像创建规模集

    az vmss create --resource-group <myResourceGroup> --name <myScaleSet> --image <MyImage> --admin-username <myUsername> --admin-password <myPassword> --instance-count 2 --disable-overprovision --upgrade-policy-mode manual --load-balancer '""'
    
  11. 验证在规模集中创建的两个 VM 是否联机,是否具有不同的名称,以及是否进入“成功”状态

现在可以使用此规模集创建代理池了。

使用新的自定义映像更新现有规模集

若要更新现有规模集上的映像,请按照上述使用自定义映像、软件或磁盘大小创建规模集部分中的步骤到 az image create 步骤生成自定义操作系统映像。 记下 az image create 命令输出的 ID 属性 URL。 然后,使用新映像更新规模集,如以下示例所示。 更新规模集映像后,将使用新映像创建规模集中的所有未来 VM。

az vmss update --resource-group <myResourceGroup> --name <myScaleSet> --set virtualMachineProfile.storageProfile.imageReference.id=<id url>

支持的操作系统

规模集代理当前支持 Ubuntu Linux、Windows Server/DataCenter 2016/2019 和 Windows 10 客户端。

已知问题

  • 不支持 Debian 或 RedHat Linux 发行版。 仅支持 Ubuntu。
  • Windows 10 客户端不支持以本地用户身份运行管道代理,因此,代理无法与 UI 进行交互, 而是作为本地服务运行。

对问题进行故障排除

导航到 Azure DevOps 项目设置,在“管道”下选择“代理池”,然后选择你的代理池。 选择标记为“诊断”的选项卡。

“诊断”选项卡显示 Azure DevOps 为在 Azure 规模集中创建、删除 VM 或重置其映像而执行的所有操作。 诊断还会记录尝试执行这些操作时遇到的任何错误。 查看这些错误,以确保规模集有足够的资源进行横向扩展。如果 Azure 订阅已达到 VM 数、CPU 核心数、磁盘数或 IP 地址数中的资源限制,这些错误将在此处显示。

运行不正常的代理

当代理或虚拟机无法启动、无法连接到 Azure DevOps 或意外脱机时,Azure DevOps 会将故障记录到代理池的“诊断”选项卡中,并尝试删除关联的虚拟机。 网络配置、映像自定义和挂起的重新启动可能会导致这些问题。 连接到 VM 以调试和收集日志会有助于调查。

如果希望 Azure DevOps 保存运行不正常的代理 VM 以供调查,并且在检测到不正常状态时不自动将其删除,请导航到 Azure DevOps 项目设置,在“管道”下选择“代理池”,然后选择你的代理池。 选择“设置”,选择“保存运行不正常的代理以供调查”选项,然后选择“保存”。

保存运行不正常的代理设置。

现在,在规模集中检测到运行不正常的代理时,Azure DevOps 会保存该代理和关联的虚拟机。 可以在代理池 UI 的“诊断”选项卡上看到保存的代理。 导航到 Azure DevOps 项目设置,在“管道”下选择“代理池”,选择你的代理池,选择“诊断”,然后记下代理名称。

保存的代理卡。

通过 Azure 门户的“实例”列表,在 Azure 虚拟机规模集中查找关联的虚拟机。

Azure 门户虚拟机规模集实例。

选择实例,选择“连接”,然后执行调查。

连接到虚拟机实例。

若要在完成调查后删除保存的代理,请导航到 Azure DevOps 项目设置,在“管道”下选择“代理池”,然后选择你的代理池。 选择标记为“诊断”的选项卡。 在“保存以供调查的代理”卡中查找代理,然后选择“删除”。 这会从池中删除代理并删除关联的虚拟机。

保存的代理卡“删除”按钮。

常见问题

有哪些常见问题以及相应的解决方案?

你会在不同时间观察到空闲代理的数量要多于所需数量

若要更好地了解发生这种情况的原因,请参阅 Azure Pipelines 如何管理规模集。 在整个缩放操作中,Azure Pipelines 的目标是在待机时达到所需数量的空闲代理。 池缓慢横向扩展和缩减。 在一天的时间里,当请求在早上排队时,池将横向扩展,随着负载在晚上的消退,池会横向缩减。 这是预期行为,因为 Azure Pipelines 会逐渐收敛到你指定的约束。

虚拟机规模集纵向扩展未在预期的 5 分钟间隔内进行

缩放作业每五分钟运行一次,但如果只处理一个操作,你可能会发现在五分钟内没有进行纵向扩展;这是目前的设计使然。

Azure DevOps Linux VM 规模集经常无法启动管道

遇到规模集代理问题时,首先要查看的是代理池中的“诊断”选项卡。

此外,请考虑保存运行不正常的 VM 以用于调试目的。 有关详细信息,请参阅运行不正常的代理

保存的代理仍然存在,除非你将其删除。 如果代理在 10 分钟内未联机,则会将其标记为运行不正常并保存(如有可能)。 只有一台 VM 保持保存状态。 如果代理意外脱机(由 VM 重启或映像出现问题所致),将不会保存代理以供调查。

仅保存代理无法启动的 VM。 如果 VM 在创建期间处于失败状态,将不会保存该 VM。 在这种情况下,“诊断”选项卡中的消息将为“删除运行不正常的计算机”,而不是“无法启动”。

为代理池选中了“每次使用后自动拆除虚拟机”选项,但你看到 VM 并未按照预期重置映像,只是在新作业排队时选取了这些作业

每次生成后拆除 VM 的选项仅适用于 Windows Server 和支持的 Linux 映像。 Windows 客户端映像不支持此选项。

如果 VM 重启,虚拟机规模集将代理显示为脱机

在 VM 重启时将代理显示为脱机是预期行为。 代理服务仅在 systemd 上下文中运行。 但是,如果计算机由于某种原因重新启动,则它会被视为运行不正常的 VM 并被删除。 有关详细信息,请参阅运行不正常的代理

当代理或虚拟机无法启动、无法连接到 Azure DevOps 或意外脱机时,Azure DevOps 会将故障记录到代理池的“诊断”选项卡中,并尝试删除关联的虚拟机。 网络配置、映像自定义和挂起的重新启动可能会导致这些问题。 若要避免出现问题,请在映像上禁用软件更新。 还可以连接到 VM 以调试和收集日志,从而帮助调查问题。

可以在成本管理中看到虚拟机规模集的多个标记(如 _AzureDevOpsElasticPoolTimeStamp)

创建池时,会向规模集添加一个标记,以将规模集标记为“正在使用”(以避免两个池使用同一规模集),并且会为每次运行配置作业(每两小时一次)更新的时间戳添加另一个标记。

无法创建新的规模集代理池,并收到一条错误消息,指出已存在具有相同名称的池

你可能会收到类似于 This virtual machine scale set is already in use by pool <pool name> 的错误消息,因为即使删除标记,该标记仍会存在于规模集中。 删除代理池时,会尝试从规模集中删除标记,但这是一次尽力尝试,并且会在三次重试后放弃。 此外,最多可以有两个小时的间隔,在此期间,任何代理池未使用的虚拟机规模集无法分配给新的代理池。 此问题的解决方法是等待该时间间隔经过,或从 Azure 门户手动删除规模集的标记。 在 Azure 门户中查看规模集时,选择左侧的“标记”链接,然后删除标记为“_AzureDevOpsElasticPool”的标记 。

虚拟机规模集维护作业未在代理上运行或获取日志

维护作业每 24 小时运行一次。 VM 可能在此时间之前被填满。 请考虑增加 VM 上的磁盘大小,并在管道中添加脚本以删除内容。

如果你在虚拟机规模集的脚本中将 AzDevOps 指定为主管理员,则规模集实例的代理配置可能会出现问题

如果你在虚拟机规模集的脚本中将 AzDevOps 指定为主管理员,则规模集实例的代理配置可能会出现问题(在用户有密码的情况下,用户的密码会被更改)。

出现此问题是因为代理扩展脚本尝试创建用户 AzDevOps 并更改其密码。

注意

可以创建用户并向其授予额外权限,但此用户不应是主管理员,并且任何内容都不应依赖于密码,因为密码将被更改。 若要避免出现问题,请在创建规模集时选择其他用户作为主管理员,而不是 AzDevOps

由于网络安全和防火墙配置,规模集实例上的代理扩展安装失败

该扩展需要能够从 https://vstsagentpackage.azureedge.net/agent 下载生成代理文件,并且生成代理需要能够注册到 Azure DevOps Services。 确保此 URL 和 Azure DevOps Services 相关的 IP 和 URL 在实例上处于打开状态。 对于需要在防火墙上取消阻止的 IP 和 URL,请参阅允许的 IP 地址和域 URL

为什么规模集代理配置脚本调用 Add-MpPreference 并在代理上配置 Windows Defender?

为了改善性能并提高可靠性,配置脚本使用包含 C:\D:\ExclusionPath 调用 Add-MpPreference,这将禁用 Windows Defender 对代理上这些文件夹中的文件的计划和实时扫描。 若要更改默认行为,请将名为 ELASTIC_POOLS_SKIP_DEFENDER_EXCLUSION 的环境变量设置为 true

我想要增加池大小。 我应考虑哪些因素?

在增加池大小之前,请确保为虚拟机规模集池配置的 Azure 虚拟网络具有足够大的地址空间范围来容纳所有新代理。 否则,可能会收到类似于“无法增加容量”的错误。地址前缀为 12.123.45.224/28 的子网 azure-devops-agent-pool-fabrikam-fiber 没有足够的容量来容纳 5 个 IP 地址。