Microsoft 托管代理

Azure DevOps Services

Microsoft 托管代理仅适用于云中托管的 Azure DevOps Services。 不能将 Microsoft 托管代理或 Azure Pipelines 代理池与本地 TFS 或 Azure DevOps Server 配合使用。 对于这些本地版本,必须使用自托管代理

重要

从 Azure DevOps 内容版本选择器中选择一个版本。

选择与平台和版本相对应的本文的版本。 版本选择器位于目录上方。 查找 Azure DevOps 平台和版本

如果你的管道位于 Azure Pipelines 中,则你可以选择使用 Microsoft 托管代理来运行作业。 Microsoft 托管的代理可以为你处理维护和升级操作。 始终获取管道中指定的 VM 映像的最新版本。 每次运行管道时,都会为管道中的每个作业获取一个全新的虚拟机。 虚拟机会在一个作业后被丢弃,这意味着作业对虚拟机文件系统所做的任何更改(例如签出代码)将不适用于下一个作业。 Microsoft 托管代理可以直接在 VM 上运行作业,也可以在容器中运行作业。

Azure Pipelines 为 Microsoft 托管代理提供名为 Azure Pipelines 的预定义代理池。

对于许多团队来说,这是运行作业的最简单方法。 可先尝试此操作,了解其是否适用于你的生成或部署。 如果没有,可以使用规模集代理或自托管代理。

提示

可以免费试用 Microsoft 托管代理。

软件

Azure Pipelines 代理池提供多个虚拟机映像供你选择,每个映像包括各种工具和软件。

映像 经典编辑器代理规范 YAML VM 映像标签 包含的软件
带 Visual Studio 2022 的 Windows Server 2022 windows-2022 windows-latestwindows-2022 链接
带 Visual Studio 2019 的 Windows Server 2019 windows-2019 windows-2019 链接
Ubuntu 22.04 ubuntu-22.04 ubuntu-latestubuntu-22.04 链接
Ubuntu 20.04 ubuntu-20.04 ubuntu-20.04 链接
macOS 13 Ventura macOS-13 macOS-13 链接
macOS 12 Monterey macOS-12 macOS-latestmacOS-12 链接
macOS 11 Big Sur(已弃用) macOS-11 macOS-11 链接

经典生成管道的默认代理映像为 windows-2019,YAML 生成管道的默认代理映像为 ubuntu-latest。 有关详细信息,请参阅在管道中指定池

可以通过选择表中的包含的软件链接来查看每个托管代理的已安装软件。 使用 macOS 映像时,可以从工具版本进行手动选择。 了解详细信息

最新更新

建议客户迁移到较新版本或自托管代理

有关如何更新使用这些映像的管道的详细信息和说明,请参阅删除 Azure Pipelines 托管池中的旧映像

注意

macOS 容量目前有限。 与 Linux 和 Windows 映像的容量受 Azure 整体容量限制不同,macOS 容量受可用硬件数量的限制。 我们正努力在 2024 年春季提供更多容量,不过某些作业可能会遇到延迟执行。 在可能的情况下,例如对于不创建 Apple 生态系统应用的作业,客户应选择 Linux 或 Windows 映像。

注意

Azure Pipelines 托管池替换了以前的托管池,这些池的名称映射到相应的映像。 以前的托管池中的任何作业都会自动重定向到新的 Azure Pipelines 托管池中的正确映像。 在某些情况下,可能仍会看到旧池名称,但在后台,托管作业是使用 Azure Pipelines 池运行的。 有关此更新的详细信息,请参阅 2019 年 7 月 1 日 - Sprint 154 发行说明中的单托管池发行说明。

重要

若要请求在 Microsoft 托管代理上安装其他软件,请不要在本文档中创建反馈请求或开立支持票证。 相反,请在存储库上提出问题,在其中管理脚本以生成各种映像。

如何使用已弃用的托管映像识别管道

若要识别使用已弃用映像的管道,请浏览到组织中的以下位置:https://dev.azure.com/{organization}/{project}/_settings/agentqueues,然后筛选映像名称以进行检查。 以下示例检查 vs2017-win2016 映像。

按映像名称筛选管道的屏幕截图。

还可以使用此处的脚本跨项目查询已弃用映像的作业历史记录,如以下示例所示。

./QueryJobHistoryForRetiredImages.ps1 -accountUrl https://dev.azure.com/{org} -pat {pat}

使用 Microsoft 托管代理

在 YAML 管道中,如果未指定池,管道将默认为 Azure Pipelines 代理池。 只需指定要使用的虚拟机映像。

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: echo hello from Linux
- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - script: echo hello from macOS
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: echo hello from Windows

注意

可以在 YAML 文件中的多个级别对池进行规范。 如果发现管道未在预期的映像上运行,请确保在管道、阶段和作业级别验证池规范。

避免硬编码引用

使用 Microsoft 托管代理时,请始终使用变量来引用生成环境和代理资源。 例如,不要对包含存储库的驱动器号或文件夹进行硬编码。 托管代理的精确布局可能会更改,而不会发出警告。

硬件

运行 Windows 和 Linux 映像的 Microsoft 托管代理在具有 2 核 CPU、7 GB RAM 和 14 GB SSD 磁盘空间的 Azure 常规用途虚拟机上预配。 这些虚拟机与 Azure DevOps 组织位于同一地理位置。

运行 macOS 映像的代理在具有 3 核 CPU、14 GB RAM 和 14 GB SSD 磁盘空间的 Mac Pro 上预配。 无论 Azure DevOps 组织位于何处,这些代理始终在美国运行。 如果数据主权对你很重要,并且你的组织不在美国,则不应使用 macOS 映像。 了解详细信息

所有这些计算机至少有 10 GB 的可用磁盘空间可供管道运行。 当管道签出源代码、下载包、拉取 docker 映像或生成中间文件时,将使用此可用空间。

重要

我们不能接受增加 Microsoft 托管代理上的磁盘空间或预配更强大的计算机的请求。 如果 Microsoft 托管代理的规范不满足你的需求,则应考虑自托管代理规模集代理

网络

在某些设置中,可能需要知道部署代理的 IP 地址范围。 例如,如果需要通过防火墙授予托管代理访问权限,则可能希望按 IP 地址限制该访问。 由于 Azure DevOps 使用 Azure 全球网络,因此 IP 范围会随时间而变化。 Microsoft 发布了每周 JSON 文件,其中列出了 Azure 数据中心的 IP 范围,按区域划分。 此文件每周更新一次,其中包含新的计划 IP 范围。 只有最新版本的文件可供下载。 如果需要以前的版本,则必须在它们可用时每周下载并存档。 新的 IP 范围将在下周开始生效。 建议频繁地检查(每周至少一次),以确保保持最新列表。 如果代理作业开始失败,关键的第一个故障排除步骤是确保配置与最新的 IP 地址列表匹配。 托管代理的 IP 地址范围在 AzureCloud.<region> 下的每周文件中列出,例如美国西部区域为 AzureCloud.westus

托管代理在与组织相同的 Azure 地理位置中运行。 每个地理位置都包含一个或多个区域。 虽然代理可能在与组织相同的区域中运行,但不能保证这样做。 若要获取代理的可能 IP 范围的完整列表,必须使用地理位置中包含的所有区域的 IP 范围。 例如,如果你的组织位于美国地理位置,则必须使用该地理位置中的所有区域的 IP 范围。

若要确定地理位置,请导航到 https://dev.azure.com/<your_organization>/_settings/organizationOverview,获取你的区域,然后从 Azure 地理位置表中查找关联的地理位置。 确定地理位置后,对该地理位置中的所有区域使用每周文件中的 IP 范围。

重要

不能使用 ExpressRoute 或 VPN 等专用连接将 Microsoft 托管代理连接到企业网络。 Microsoft 托管代理与服务器之间的流量将通过公用网络。

识别 Microsoft 托管代理的可能 IP 范围

  1. 组织设置中识别组织区域
  2. 确定组织所在地区的 Azure 地理位置
  3. 按照 AzureCloud.<region> 的格式(如 AzureCloud.westus),将地理区域的名称映射到每周文件中使用的格式。 可以通过查看从适用于 .NET 的 Azure 管理库传递给“区域”类的源代码中定义的区域构造函数的区域名称,将 Azure 地理位置列表中的区域名称映射到每周文件中使用的格式。

    注意

    由于适用于 .NET 的 Azure 管理库中没有 API 可以列出地理位置的区域,因此必须手动列出它们,如以下示例所示。

  4. 每周文件中检索地理位置中所有地区的 IP 地址。 如果你的区域是巴西南部欧洲西部,则必须根据回退地理位置包括其他 IP 范围,如以下说明中所述。

注意

由于容量限制,巴西南部欧洲西部区域中的某些组织偶尔可能会看到其托管代理位于其预期地理位置之外。 在这些情况下,除了包括上一部分所述的地理位置中所有区域的 IP 范围外,还必须为容量回退地理位置中的区域包括其他 IP 范围。

如果组织位于巴西南部区域,则容量回退地理位置为美国

如果组织位于欧洲西部区域,则容量回退地理位置为法国

我们的 Mac IP 范围不包括在上述 Azure IP 中,因为它们托管在 GitHub 的 macOS 云中。 可以根据此处提供的说明,使用 GitHub 元数据 API 检索 IP 范围。

示例

在以下示例中,从每周文件中检索美国西部区域中组织的托管代理 IP 地址范围。 由于美国西部区域位于美国地理位置,因此将包括美国地理位置中所有区域的 IP 地址。 在此示例中,IP 地址将写入控制台。

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace WeeklyFileIPRanges
{
    class Program
    {
        // Path to the locally saved weekly file
        const string weeklyFilePath = @"C:\MyPath\ServiceTags_Public_20230904.json";

        static void Main(string[] args)
        {
            // United States geography has the following regions:
            // Central US, East US, East US 2, East US 3, North Central US, 
            // South Central US, West Central US, West US, West US 2, West US 3
            // This list is accurate as of 9/8/2023
            List<string> USGeographyRegions = new List<string>
            {
                "centralus",
                "eastus",
                "eastus2",
                "eastus3",
                "northcentralus",
                "southcentralus",
                "westcentralus",
                "westus",
                "westus2",
                "westus3"
            };

            // Load the weekly file
            JObject weeklyFile = JObject.Parse(File.ReadAllText(weeklyFilePath));
            JArray values = (JArray)weeklyFile["values"];

            foreach (string region in USGeographyRegions)
            {
                string tag = $"AzureCloud.{region}";
                Console.WriteLine(tag);

                var ipList =
                    from v in values
                    where tag.Equals((string)v["name"], StringComparison.OrdinalIgnoreCase)
                    select v["properties"]["addressPrefixes"];

                foreach (var ip in ipList.Children())
                {
                    Console.WriteLine(ip);
                }
            }
        }
    }
}

服务标记

Microsoft 托管代理不能按服务标记列出。 如果尝试向托管代理授予对资源的访问权限,则需要遵循 IP 范围允许列表方法。

安全性

Microsoft 托管代理在安全的 Azure 平台上运行。 但是,必须注意以下安全注意事项。

  • 尽管 Microsoft 托管代理在 Azure 公用网络上运行,但未为其分配公共 IP 地址。 因此,外部实体不能以 Microsoft 托管代理为目标。
  • Microsoft 托管代理在单个 VM 中运行,每次运行后都会重新映像。 每个代理专用于单个组织,每个 VM 仅托管一个代理。
  • 从安全角度来看,在 Microsoft 托管代理上运行管道有几个好处。 如果在管道中运行不受信任的代码(例如分叉的贡献),在 Microsoft 托管代理上运行管道比在驻留在企业网络的自托管代理上运行管道更安全。
  • 当管道需要访问防火墙后面的公司资源时,必须允许 Azure 地理位置的 IP 地址范围。 这可能会增加你的曝光率,因为 IP 地址范围相当大,并且此范围内的计算机也可以属于其他客户。 防止这种情况的最佳方法是避免访问内部资源。 如需了解如何将项目部署到一组服务器,请参阅关于部署到目标服务器的信息
  • 托管映像不符合 CIS 强化基准。 若要使用 CIS 强化的映像,必须创建自托管代理或规模集代理。

功能和限制

Microsoft 托管代理:

  • 拥有上述软件。 还可以在生成或发布过程中使用工具安装程序任务添加软件。
    • 可以获取管道中每个作业的全新映像代理。
  • 为源和生成输出提供 10 GB 的存储。
  • 提供免费层:
    • 公共项目:10 个每次最多可以运行 360 分钟(6 小时)的免费 Microsoft 托管并行作业,每个月没有总时间限制。 联系我们,提高免费层限制。
    • 专用项目:一个每次最多可以运行 60 分钟的免费并行作业,直到每个月使用了 1800 分钟(30 小时)。 你可以为每个并行作业的额外容量付费。 付费并行作业将移除每月时间限制,并允许你运行每个作业最多 360 分钟(6 小时)。 购买 Microsoft 托管的并行作业
    • 创建新的 Azure DevOps 组织时,默认情况下不会向你提供这些免费授权。 若要请求公共或专用项目的免费授权,请提交请求
  • 在 Microsoft Azure 常规用途虚拟机 Standard_DS2_v2 上运行。
  • 在 Windows 上以管理员身份运行,在 Linux 上以无密码 sudo 用户身份运行。
  • (仅限 Linux)在提供 6 GB 物理内存和 13 GB 总内存的 cgroup 中运行步骤。
  • 使用定期更新(每 3 周一次)的 VM 映像。

Microsoft 托管代理不提供:

  • 远程连接的功能。
  • 将项目拖放到 UNC 文件共享的功能。
  • 将计算机直接加入企业网络的功能。
  • 获取更大或更强大的生成计算机的功能。
  • 预加载自定义软件的功能。 可以在管道运行期间安装软件,例如通过工具安装程序任务或在脚本中。
  • 使用可以更快地启动和运行生成的自托管代理可能获得的潜在性能优势。 了解详细信息
  • 运行 XAML 生成的功能。
  • 回滚到以前的 VM 映像版本的功能。 始终使用最新版本。

如果 Microsoft 托管代理不满足你的需求,则可以部署自己的自托管代理或使用规模集代理

常见问题解答

如何查看映像中包含的软件?

可以通过选择软件表中的包含的软件链接来查看每个托管代理的已安装软件。

注意

默认情况下,Windows 代理使用与代理软件捆绑在一起的 Git 版本。 Microsoft 建议使用与代理捆绑在一起的 Git 版本,但有多个选项可以替代此默认行为,并使用代理计算机在路径中安装的 Git 版本。

  • 在管道中将名为 System.PreferGitFromPath 的管道变量设置为 true
  • 在自托管代理上,可以在代理根目录中创建名为 .env 的文件,并在文件中添加 System.PreferGitFromPath=true 行。 有关详细信息,请参阅如何为每个单独的代理设置不同的环境变量?

若要查看管道使用的 Git 版本,可以查看管道中 checkout 步骤的日志,如以下示例所示。

Syncing repository: PathFilter (Git)
Prepending Path environment variable with directory containing 'git.exe'.
git version
git version 2.26.2.windows.1

Microsoft 如何选择要在映像上放置的软件和版本?

有关映像中包含的软件版本的详细信息,请参阅安装内容指南

何时更新映像?

映像通常每周更新一次。 可以检查状态徽章,其格式为 20200113.x,其中第一部分指示映像的更新日期。

如果需要的软件被删除或替换为较新版本,该怎么办?

可以通过选择使用 Microsoft 托管代理表中的包含的软件链接,通过提交 GitHub 问题来告知我们。

还可以使用包含所需软件确切版本的自托管代理。 有关详细信息,请参阅自托管代理

如果需要具有更多处理能力、内存或磁盘空间的更大计算机,该怎么办?

我们无法增加 Microsoft 托管代理的内存、处理能力或磁盘空间,但你可以使用托管在符合所需规范的计算机上的自托管代理规模集代理

我无法选择 Microsoft 托管代理,无法将生成或部署排队。 应采取何种操作?

Microsoft 托管代理仅在 Azure Pipelines 中可用,在 TFS 或 Azure DevOps Server 中不可用。

默认情况下,组织中的所有项目参与者都有权访问 Microsoft 托管代理。 但是,组织管理员可能会限制 Microsoft 托管代理的访问,以选择用户或项目。 要求 Azure DevOps 组织的所有者授予你使用 Microsoft 托管代理的权限。 请参阅代理池安全性

我在 Microsoft 托管的代理上运行的管道需要更多时间才能完成。 如何加快速度?

如果管道最近变慢,请查看我们的状态页,了解是否有任何中断。 我们的服务可能出现了问题。 或者,查看在应用程序代码或管道中所做的任何更改。 在检查期间,你的存储库大小可能已增加,你可能正在上传较大的项目,或者可能正在运行更多的测试。

如果你只是设置管道,并将 Microsoft 托管代理的性能与本地计算机或自托管代理进行比较,请记下我们用于运行你的作业的硬件规范。 我们无法为你提供更大或功能更强大的计算机。 如果无法接受此性能,可以考虑使用自托管代理规模集代理

我需要更多代理。 我该怎么办?

所有 Azure DevOps 组织都为开源项目提供多个免费并行作业,每个月为专用项目提供一个免费并行作业和有限分钟数。 如果需要为开源项目增加几分钟或并行作业,请联系支持人员。 如果需要为专用项目增加几分钟或并行作业,则可以购买更多

我的管道可以在自托管代理上成功运行,但在 Microsoft 托管代理上运行失败。 应采取何种操作?

自托管代理可能安装了所有正确的依赖项,而 Microsoft 托管代理上未安装相同的依赖项、工具和软件。 首先,请仔细查看 Microsoft 托管代理上安装的软件列表,方法是按照上表中的包含的软件链接进行操作。 然后,将其与自托管代理上安装的软件进行比较。 在某些情况下,Microsoft 托管代理可能具有所需的工具(例如,Visual Studio),但可能尚未安装所有必要的可选组件。 如果发现差异,则有两个选项:

  • 可以在存储库上创建新问题,我们会在其中跟踪对其他软件的请求。 联系支持人员无法帮助你在 Microsoft 托管代理上设置新软件。

  • 可以使用自托管代理规模集代理。 使用这些代理,可以完全控制用于运行管道的映像。

我的生成在本地计算机上成功运行,但在 Microsoft 托管代理上运行失败。 应采取何种操作?

本地计算机可能安装了所有正确的依赖项,而 Microsoft 托管代理上未安装相同的依赖项、工具和软件。 首先,请仔细查看 Microsoft 托管代理上安装的软件列表,方法是按照上表中的包含的软件链接进行操作。 然后,将其与本地计算机上安装的软件进行比较。 在某些情况下,Microsoft 托管代理可能具有所需的工具(例如,Visual Studio),但可能尚未安装所有必要的可选组件。 如果发现差异,则有两个选项:

  • 可以在存储库上创建新问题,我们会在其中跟踪对其他软件的请求。 这是安装新软件的最佳选择。 联系支持人员不会帮助你在 Microsoft 托管代理上设置新软件。

  • 可以使用自托管代理规模集代理。 使用这些代理,可以完全控制用于运行管道的映像。

管道失败并出现错误:“设备上没有剩余空间”。

Microsoft 托管的代理仅有 10 GB 的磁盘空间可用于运行作业。 当签出源代码、下载包、下载 docker 映像或生成中间文件时,将使用此可用空间。 遗憾的是,无法增加 Microsoft 托管映像上的可用空间。 可以重构管道,使其适合此空间。 或者,可以考虑使用自托管代理规模集代理

在 Microsoft 托管代理上运行的管道需要访问公司网络上的服务器。 如何获取防火墙中允许的 IP 地址列表?

请参阅代理 IP 范围部分

在 Microsoft 托管代理上运行的管道无法解析公司网络上的服务器的名称。 如何修复此问题?

如果按 DNS 名称引用服务器,请确保该服务器可通过其 DNS 名称在 Internet 上公开访问。 如果按 IP 地址引用服务器,请确保该 IP 地址可在 Internet 上公开访问。 在这两种情况下,请确保代理和企业网络之间的任何防火墙都允许代理 IP 范围

我收到来自 Azure 存储帐户的 SAS IP 授权错误

如果收到 SAS 错误代码,很可能是因为 Azure 存储规则不允许 Microsoft 托管代理的 IP 地址范围。 有一些解决方法:

  1. 管理 Azure 存储帐户的 IP 网络规则,并添加托管代理的 IP 地址范围
  2. 在管道中,在访问存储之前,使用 Azure CLI 更新 Azure 存储帐户的网络规则集,然后还原以前的规则集。
  3. 使用自托管代理规模集代理

如何在托管 macOS 代理上手动选择工具版本?

Xamarin

托管 macOS 代理将 Xamarin SDK 版本和关联的 Mono 版本作为一组符号链接存储到单个捆绑包符号链接可用的 Xamarin SDK 位置。

若要手动选择要在托管 macOS 代理上使用的 Xamarin SDK 版本,请在 Xamarin 生成任务之前执行以下 bash 命令作为生成的一部分,从而指定指向所需的 Xamarin 版本捆绑包的符号链接。

/bin/bash -c "sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh <symlink>"

可以在代理文档中找到所有可用的 Xamarin SDK 版本和符号链接的列表:

此命令不会选择 Xamarin SDK 以外的 Mono 版本。 若要手动选择 Mono 版本,请参阅下面的说明。

如果使用非默认版本的 Xcode 来生成 Xamarin.iOS 或 Xamarin.Mac 应用,则应另外执行以下命令行:

/bin/bash -c "echo '##vso[task.setvariable variable=MD_APPLE_SDK_ROOT;]'$(xcodeRoot);sudo xcode-select --switch $(xcodeRoot)/Contents/Developer"

其中 $(xcodeRoot) = /Applications/Xcode_13.2.app

可以在 macos-11 代理的此处以及 macos-12 代理的此处找到托管 macOS 代理池上的 Xcode 版本。

Xcode

如果使用随 Azure Pipelines 和 TFS 附带的 Xcode 任务,则可以在该任务的属性中选择 Xcode 的版本。 否则,若要手动设置要在托管 macOS 代理池上使用的 Xcode 版本,请在 xcodebuild 生成任务之前执行此命令行作为生成的一部分,从而根据需要替换 Xcode 版本号 13.2:

/bin/bash -c "sudo xcode-select -s /Applications/Xcode_13.2.app/Contents/Developer"

可以在 macos-11 代理的此处以及 macos-12 代理的此处找到托管 macOS 代理池上的 Xcode 版本。

此命令不适用于 Xamarin 应用。 若要手动选择 Xcode 版本来生成 Xamarin 应用,请参阅上面的说明。

Mono

若要手动选择要在托管 macOS 代理池上使用的 Mono 版本,请在 Mono 生成任务之前在生成的每个作业中执行此脚本,从而指定具有所需 Mono 版本的符号链接(可以在 Xamarin 部分找到所有可用符号链接的列表),请执行以下操作:

SYMLINK=<symlink>
MONOPREFIX=/Library/Frameworks/Mono.framework/Versions/$SYMLINK
echo "##vso[task.setvariable variable=DYLD_FALLBACK_LIBRARY_PATH;]$MONOPREFIX/lib:/lib:/usr/lib:$DYLD_LIBRARY_FALLBACK_PATH"
echo "##vso[task.setvariable variable=PKG_CONFIG_PATH;]$MONOPREFIX/lib/pkgconfig:$MONOPREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
echo "##vso[task.setvariable variable=PATH;]$MONOPREFIX/bin:$PATH"