Azure Pipelines agents(Azure Pipelines 代理)
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
要生成代码或使用 Azure Pipelines 部署软件,至少需要一个代理。 随着代码库和团队的壮大,你将需要更多的代理。
管道运行时,系统会开始运行一个或多个作业。 代理是计算基础结构,带有已安装的代理软件,一次运行一个作业。
Azure Pipelines 提供了多种不同类型的代理。
代理类型 | 说明 | 可用性 |
---|---|---|
Microsoft 托管代理 | 由 Microsoft 托管和管理的代理 | Azure DevOps Services |
自托管代理 | 由你配置和管理的代理,托管在你的 VM 上 | Azure DevOps Services、Azure DevOps Server |
Azure 虚拟机规模集代理 | 一种使用 Azure 虚拟机规模集的自托管代理形式,可以通过自动缩放来满足需求 | Azure DevOps Services |
托管 DevOps 池代理 | 托管 DevOps 池是一项完全托管服务,其中实时为代理提供支持的虚拟机或容器位于 Microsoft Azure 订阅中,而不在您自己的 Azure 订阅中 | Azure DevOps Services |
Microsoft 托管代理
如果你的管道位于 Azure Pipelines 中,可以选择使用 Microsoft 托管代理来运行作业。 Microsoft 托管的代理可以为你处理维护和升级操作。 始终获取管道中指定的 VM 映像的最新版本。 每次运行管道时,都会为管道中的每个作业获取一个全新的虚拟机。 虚拟机会在一个作业后被丢弃,这意味着作业对虚拟机文件系统所做的任何更改(例如签出代码)将不适用于下一个作业。 Microsoft 托管代理可以直接在 VM 上运行作业,也可以在容器中运行作业。
Azure Pipelines 为 Microsoft 托管代理提供名为 Azure Pipelines 的预定义代理池。
对于许多团队来说,这是运行作业的最简单方法。 可先尝试此操作,了解其是否适用于你的生成或部署。 如果没有,可以使用规模集代理或自托管代理。
提示
可以免费试用 Microsoft 托管代理。
自托管代理
自托管代理是一种你可以自行设置和管理以运行作业的代理。 你可以在 Azure Pipelines 或 Azure DevOps Server(以前称为 Team Foundation Server (TFS))中使用自托管代理。 自托管代理可让你进行更多控制,以安装生成和部署所需的依赖软件。 此外,计算机级缓存和配置会在运行中持续存在,这可以提高速度。
注意
尽管每台计算机可以安装多个代理,但我们强烈建议每台计算机只安装一个代理。 安装两个或更多代理可能会对性能和管道结果产生负面影响。
提示
在安装自托管代理之前,可能需要查看 Microsoft 托管代理池是否适合你。 在许多情况下,这是最简单的方法。 试一试。
可在 Linux、macOS 或 Windows 计算机上安装代理。 还可在 Docker 容器上安装代理。 有关安装自托管代理的详细信息,请参阅:
注意
在 macOS 上,需要清除下载存档上的特殊属性,防止在运行 ./config.sh
时为 tar 文件中的每个程序集显示 Gatekeeper 保护。 以下命令用于清除文件上的扩展属性:
xattr -c vsts-agent-osx-x64-V.v.v.tar.gz ## replace V.v.v with the version in the filename downloaded.
# then unpack the gzip tar file normally:
tar xvfz vsts-agent-osx-x64-V.v.v.tar.gz
在计算机上安装代理后,可继续安装作业所需的任何其他软件。
注意
代理具有广泛的向后兼容性。 只要 Azure DevOps 不要求更高版本的代理,任何版本的代理都应与任何 Azure DevOps 版本兼容。
我们仅支持最新版本的代理,因为这是唯一保证具有所有最新补丁和 bug 修补程序的版本。
Node 运行器版本
该代理附带了多个版本的 NodeJS 库,以支持使用不同 Node 处理程序的目标任务。
所有正式的 Azure DevOps 任务都使用 Node 20 作为通用处理程序,但是,客户仍可使用采用停用的 Node 6、Node 10 或 Node 16 库的自定义任务。 为了支持与当前生命周期已结束的 Node 的后向兼容性,我们提供了以下自助服务方法来手动安装指定的 Node 运行器。
手动安装 Node 6 运行器。 有关手动安装 Node 6 运行器的详细信息,请参阅 Node 6 支持以获取更多详细信息。
在需要过时的 Node 6 库的管道中使用 NodeTaskRunnerInstaller@0 任务。
安装包含 Node 6 的代理包。
Azure Pipelines 提供两个版本的代理包。
- vsts-agent-* 包支持 Node 6。
- pipelines-agent-* 包不支持 Node 6。 此版本的包将来会成为默认代理包。
如果你知道你未使用任何依赖于 Node 6 的任务,并且不希望在代理计算机上安装 Node 6,则可以从 https://github.com/microsoft/azure-pipelines-agent/releases 的“备用代理下载”部分安装代理。
Azure 虚拟机规模集代理
Azure 虚拟机规模集代理是一种可自动缩放以满足需求的自托管代理形式。 这种弹性可减少一直运行专用代理的需求。 与 Microsoft 托管的代理不同,你可以灵活地处理运行代理的计算机的大小和映像。
你需要指定虚拟机规模集、要保持备用状态的多个代理、规模集中的最大虚拟机数,Azure Pipelines 会为你管理代理的缩放。
有关详细信息,请参阅 Azure 虚拟机规模集代理。
托管 DevOps 池代理
托管 DevOps 池使开发团队能够快速轻松地启动专为团队特定需求定制的 Azure DevOps 代理池。 托管 DevOps 池会实现安全最佳做法,提供平衡成本和性能的旋钮,为最常见的方案提供路径,并显著减少创建和维护自定义池所用的时间。
托管 DevOps 池是 Azure DevOps 虚拟机规模集代理池的演变,通过提高自定义池的可伸缩性和可靠性,进一步简化了自定义池创建。 托管 DevOps 池是一项完全托管服务,其中实时为代理提供支持的虚拟机或容器位于 Microsoft Azure 订阅中,而不位于你自己的 Azure 订阅中,就像使用 Azure DevOps 虚拟机规模集代理池时一样。 有关详细信息,请参阅托管 DevOps 池文档。
并行作业
并行作业表示可以在组织中同时运行的作业数。 如果组织有单个并行作业,可以在组织中一次运行一个作业,任何其他并发作业将排入队列,直到第一个作业完成。 要同时运行两个作业,需要有两个并行作业。 在 Azure Pipelines 中,可以在 Microsoft 托管的基础结构上运行并行作业,也可以在自己的(自托管)基础结构上运行并行作业。
默认情况下,Microsoft 在每个组织中都提供免费的服务层级,其中至少包含一个并行作业。 根据需要运行的并发管道数,可能需要更多并行作业才能同时使用多个 Microsoft 托管代理或自托管代理。 有关并行作业和不同的免费服务层级的详细信息,请参阅 Azure Pipelines 中的并行作业。
可能需要更多并行作业才能同时使用多个代理:
重要
从 Azure DevOps Server 2019 开始,你无需为发布中的自托管并发作业付费。 仅受你拥有的代理数的限制。
功能
每个自托管代理都有一组功能,用于指示它可以执行的操作。 功能是由代理软件自动发现的名称/值对,称为系统功能,或者是由你定义的功能,称为用户功能。
代理软件会自动确定各种系统功能,例如计算机名称、操作系统类型和计算机上安装的某些软件的版本。 此外,计算机中定义的环境变量会自动显示在系统功能列表中。
注意
将环境变量存储为功能意味着在代理运行时,存储的功能值用于设置环境变量。 此外,在代理运行时对环境变量所做的任何更改都不会由任何任务选取和使用。 如果你有敏感的环境变量发生变化,而你不希望它们被存储为功能,可以通过设置 VSO_AGENT_IGNORE
环境变量,使用逗号分隔的变量列表来忽略它们。 例如,PATH
是一个关键变量,在安装软件时可能需要忽略。
当你创作管道时,需要指定代理的某些需求。 系统仅将作业发送给具有与管道中指定的需求相匹配的功能的代理。 因此,通过代理功能可以将作业定向到特定代理。
注意
需求和功能设计用于自托管代理,以便作业可与满足作业要求的代理匹配。 使用 Microsoft 托管代理时,为代理选择符合作业要求的映像,这样的话,虽然可以向 Microsoft 托管代理添加功能,但无需将功能与 Microsoft 托管代理一起使用。
配置需求
要向 YAML 生成管道添加需求,请将 demands:
行添加到 pool
部分。
pool:
name: Default
demands: SpecialSoftware # exists check for SpecialSoftware
可以检查某个功能是否存在,或与某个功能的值进行比较。 有关详细信息,请参阅 YAML 架构 - 需求。
配置代理功能
通过导航到“代理池”并选择所需代理的“功能”选项卡,可以查看代理的详细信息,包括其版本和系统功能,并管理其用户功能。
在 Web 浏览器中,导航到“代理池”:
(
https://dev.azure.com/{yourorganization}
) 登录到组织。选择“Azure DevOps”、“组织设置”。
选择“代理池”。
登录到项目集合 (
http://your-server/DefaultCollection
)。选择“Azure DevOps”、“集合设置”。
选择代理池。
选择 Azure DevOps、集合设置。
选择代理池。
导航到“功能”选项卡:
从代理池选项卡中,选择所需的代理池。
选择代理,然后选择所需的代理。
选择功能选项卡。
注意
Microsoft 托管的代理不显示系统功能。 有关 Microsoft 托管代理上安装的软件的列表,请参阅使用 Microsoft 托管代理。
从代理池选项卡中,选择所需的池。
选择代理,然后选择所需的代理。
选择功能选项卡。
从代理池选项卡中,选择所需的池。
选择代理,然后选择所需的代理。
选择功能选项卡。
要向代理注册新功能,请选择“添加新功能”。
提示
在自托管代理上安装新软件后,必须重启代理才能显示新功能。 有关详细信息,请参阅重启 Windows 代理、重启 Linux 代理和重启 Mac 代理。
通信
与 Azure Pipelines 的通信
与 Azure DevOps Server 通信
代理与 Azure Pipelines 或 Azure DevOps Server 通信以确定它需要运行哪个作业,并报告日志和作业状态。 这种通信总是由代理发起。 从代理到 Azure Pipelines 或 Azure DevOps Server 的所有消息都通过 HTTP 或 HTTPS 发送,具体取决于代理的配置方式。 此拉取模型允许在不同的拓扑中配置代理,正如以下示例所示。
下面是代理与 Azure Pipelines 或 Azure DevOps Server 之间的常见通信模式。
用户通过将代理添加到代理池来向 Azure Pipelines 或 Azure DevOps Server 注册代理。 你需要是代理池管理员才能在该代理池中注册代理。 代理池管理员的身份仅在注册时需要,不会在代理上持久存在。 在代理与 Azure Pipelines 或 Azure DevOps 服务器之间的任何进一步通信中都不会使用它。 注册完成后,代理将下载侦听器 OAuth 标记,并使用它来侦听作业队列。
代理使用 HTTP 长轮询侦听是否已在 Azure Pipelines/Azure DevOps Server 的作业队列中为其发布新作业请求。 当作业可用时,代理会下载作业和特定于作业的 OAuth 令牌。 Azure Pipelines/Azure DevOps Server 会为管道中指定的作用域身份生成一个短期令牌。 代理使用该令牌访问或修改该作业中 Azure Pipelines 或 Azure DevOps Server 上的资源。 例如,访问源代码或上传测试结果。
作业完成后,代理会丢弃特定于作业的 OAuth 令牌,然后使用侦听器 OAuth 令牌检查是否有新的作业请求。
代理与 Azure Pipelines/Azure DevOps Server 之间交换的消息的有效负载使用非对称加密进行保护。 每个代理都有一个公钥/私钥对,公钥在注册期间与服务器交换。 服务器在将作业的有效负载发送到代理之前,使用公钥对其加密。 代理使用其私钥解密作业内容。 在与代理交换时,这种方法可确保存储在管道或变量组中的机密安全。
注意
该代理支持 UTF-8 客户端编码输出。 但是,如果你的系统具有与 UTF-8 不同的编码,则日志输出可能会遇到一些问题。 例如,日志可能包含系统编码无法识别的字符,因此它们可能显示为乱码或缺失的符号。
部署到目标服务器的通信
使用代理将项目部署到一组服务器时,它必须与这些服务器建立“视线”连接。 Microsoft 托管的代理池默认与 Azure 中运行的 Azure 网站和服务器建立连接。
注意
如果 Azure 资源在 Azure 虚拟网络中运行,你可以获取部署 Microsoft 托管代理的代理 IP 范围,以便为 Azure VNet 配置防火墙规则以允许代理进行访问。
如果本地环境无法连接到 Microsoft 托管的代理池(通常是由于中间防火墙造成的),则需要在内部部署计算机上手动配置自托管代理。 代理必须连接到目标本地环境,并且可以访问 Internet 以连接到 Azure Pipelines 或 Team Foundation Server,如下图所示。
身份验证
要注册代理,你需要是代理池中管理员角色的成员。 代理池管理员的身份仅在注册时需要,不会在代理上持久存在。 在代理与 Azure Pipelines 或 Azure DevOps 服务器之间的任何后续通信中都不会使用它。 此外,你必须是服务器的本地管理员才能配置代理。
注册代理时,请从以下身份验证类型中选择,代理安装程序会提示输入每种身份验证类型所需的特定补充信息。 有关详细信息,请参阅自托管代理身份验证选项。
此外,Windows 代理在 Azure DevOps Server 上还有以下两个身份验证选项。
- 协商通过新技术局域网管理器 (NTLM) 或 Kerberos 等 Windows 身份验证方案,以已登录用户以外的用户身份连接到 Azure DevOps Server。 在选择“协商”后,系统会提示输入凭据。
- 集成:通过 NTLM 或 Kerberos 等 Windows 身份验证方案,使用已登录用户的凭据将 Windows 代理连接到 Azure DevOps Server。 选择此方法后,系统不会提示你输入凭据。
重要
服务器必须配置为支持身份验证方法使用备用、协商或集成身份验证。
用于注册代理的身份验证方法仅在代理注册期间使用。 要详细了解代理在注册后如何与 Azure Pipelines 通信,请参阅与 Azure Pipelines 或 Azure DevOps Server 的通信。
交互与服务
可以将自托管代理作为服务或交互进程运行。
配置代理后,建议首先在交互模式下试用它,以确保其正常工作。 然后,对于生产使用,我们建议你以以下模式之一运行代理,以便它可靠地保持在运行状态。 这些模式还可确保代理在重启计算机时自动启动。
作为服务。 可使用操作系统的服务管理器来管理代理的生命周期。 此外,将代理作为服务运行时,自动升级代理的体验会更好。
作为启用自动登录的交互式进程。 在某些情况下,可能需要以交互方式运行代理以供生产使用,例如运行 UI 测试。 当代理配置为在此模式下运行时,屏幕保护程序也会被禁用。 某些域策略可能会阻止你启用自动登录或禁用屏幕保护程序。 在这种情况下,可能需要从域策略中寻求豁免,或在域策略不适用的工作组计算机上运行代理。
注意
启用自动登录或禁用屏幕保护程序时存在安全风险,因为你允许其他用户访问计算机并使用那个自动登录的帐户。 如果将代理配置为按此方式运行,则必须确保计算机受到物理保护;例如,位于安全设施中。 如果使用远程桌面访问以自动登录方式运行代理的计算机,则直接关闭远程桌面会导致计算机锁定,并且在此代理上运行的任何 UI 测试都可能会失败。 为了避免这种情况,请使用 tscon 命令断开与远程桌面的连接。 例如:
%windir%\System32\tscon.exe 1 /dest:console
代理帐户
无论是以服务方式运行代理,还是以交互方式运行代理,都可以选择用于运行代理的计算机帐户。 代理帐户的选择仅取决于在生成和部署作业中运行的任务的需要。
例如,要使用 Windows 身份验证运行任务以访问外部服务,代理必须使用可访问该服务的帐户来运行。 但是,如果运行的是需要浏览器的 UI 测试(如 Selenium 或编码的 UI 测试),则浏览器在代理帐户的上下文中启动。
在 Windows 上,应考虑使用网络服务或本地服务等服务帐户。 这些帐户的权限受到限制,其密码也不会过期,这意味着随着时间的推移,代理需要的管理也会减少。
这些凭据不同于将代理注册到 Azure Pipelines 或 Azure DevOps Server 时使用的凭据。
代理版本和升级
我们每隔几周就会在 Azure Pipelines 中更新一次代理软件。
我们用 {major}.{minor}
格式来表示代理版本。
例如,如果代理版本为 2.1
,则主要版本为 2
,次要版本为 1
。
Microsoft 托管代理始终保持最新状态。 如果较新版本的代理仅在次要版本上有所不同,Azure Pipelines 可以自动更新自托管代理。 可以在代理池中配置此设置,选择您的代理,设置 - 默认为启用。 当平台功能或管道中使用的其中一个任务需要较新版本的代理时,将请求升级。
如果以交互方式运行自托管代理,或者有较新的代理主要版本可用,则可能需要手动升级代理。 可以从组织下的代理池选项卡轻松升级代理。 没有兼容的代理,管道无法运行
更新自托管代理
导航到“项目设置”、“代理池”。
选择代理池,然后选择“更新所有代理”。
此外,还可以从“...”菜单中选择“更新代理”来单独更新代理。
选择“更新”以确认更新。
更新请求将排队等待池中的每个代理,并在任何当前正在运行的作业完成后运行。 升级通常只需要很短的时间,只要下载最新版本的代理软件(大约 200 MB),将其解压缩,并使用新版本重启代理。 可以在“代理”选项卡上监视代理的状态。
我们会在 Azure DevOps Server 中通过每次更新来更新代理软件。
我们用 {major}.{minor}
格式来表示代理版本。
例如,如果代理版本为 2.1
,则主要版本为 2,次要版本为 1。
如果 Azure DevOps Server 服务器具有较新版本的代理,并且较新的代理只存在次要版本的差异,则通常可以自动升级。 当平台功能或管道中使用的其中一个任务需要较新版本的代理时,将请求升级。 从 Azure DevOps Server 2019 开始,无需等待新的服务器发布。 可以将新版本的代理上传到应用层,该版本会作为升级提供。
如果以交互方式运行代理,或者有较新的代理主要版本可用,则可能需要手动升级代理。 可以从项目集合下的代理池选项卡轻松升级代理。 没有兼容的代理,管道无法运行。
通过导航到“代理池”并选择所需代理的“功能”选项卡,可以查看代理的版本,如配置代理功能中所述。
要以编程方式触发代理更新,可以使用代理更新 API,如如何以编程方式触发特定代理池的代理更新部分中所述。
注意
对于无法访问 Internet 的服务器,请手动将代理 zip 文件复制到以下文件夹以用作本地文件。 创建 Agents 文件夹(如果不存在)。
- Windows:
%ProgramData%\Microsoft\Azure DevOps\Agents
- Linux:
usr/share/Microsoft/Azure DevOps/Agents
- macOS:
usr/share/Microsoft/Azure DevOps/Agents
创建 Agents 文件夹(如果不存在)。
常见问题解答
如何确保我使用的是最新的代理版本?
导航到代理池选项卡:
(
https://dev.azure.com/{yourorganization}
) 登录到组织。选择“Azure DevOps”、“组织设置”。
选择“代理池”。
登录到项目集合 (
http://your-server/DefaultCollection
)。选择“Azure DevOps”、“集合设置”。
选择代理池。
选择 Azure DevOps、集合设置。
选择代理池。
单击包含代理的池。
确保已启用代理。
导航到“功能”选项卡:
从代理池选项卡中,选择所需的代理池。
选择代理,然后选择所需的代理。
选择功能选项卡。
注意
Microsoft 托管的代理不显示系统功能。 有关 Microsoft 托管代理上安装的软件的列表,请参阅使用 Microsoft 托管代理。
从代理池选项卡中,选择所需的池。
选择代理,然后选择所需的代理。
选择功能选项卡。
从代理池选项卡中,选择所需的池。
选择代理,然后选择所需的代理。
选择功能选项卡。
查找
Agent.Version
功能。 可以针对最新发布的代理版本检查此值。 请参阅 Azure Pipelines 代理,并检查页面上列出的最高版本号。每个代理在运行需要较高版本的代理的任务时,都会自动自行更新。 如果要手动更新某些代理,请右键单击池,然后选择更新所有代理。
是否可以更新属于 Azure DevOps Server 池的代理?
是。 从 Azure DevOps Server 2019 开始,可以将服务器配置为在本地磁盘上查找代理包文件。 此配置将替代服务器在发布时附带的默认版本。 当服务器无权访问 Internet 时,此方案也适用。
在可以访问 Internet 的计算机上,从 Azure Pipelines 代理 GitHub 版本页下载代理包文件(.zip 或 .tar.gz 格式)的最新版本。
使用所选方法(如 U 盘、网络传输等)将下载的包文件传输到每个 Azure DevOps Server 应用层。 将代理文件放在
%ProgramData%\Microsoft\Azure DevOps\Agents
文件夹下。 创建 Agents 文件夹(如果不存在)。你已完成所有设置! 现在,只要更新代理,Azure DevOps Server 都将使用本地文件。 每个代理在运行需要较高版本的代理的任务时,都会自动自行更新。 但是,如果要手动更新某些代理,请右键单击池,然后选择“更新所有代理”。
自托管代理与 Microsoft 托管的代理相比是否有任何性能优势?
在许多情况下,有。 具体而言:
如果使用自托管代理,则可运行增量生成。 例如,如果定义的管道不清理存储库且不执行干净的生成,则生成通常运行速度更快。 除非使用高速缓存等功能,否则使用 Microsoft 托管代理将无法获得这些优势,因为代理会在管道完成后被销毁。
Microsoft 托管的代理可能需要更长的时间来启动你的生成。 虽然将作业分配到 Microsoft 托管代理通常只需几秒钟,但有时可能需要花费几分钟时间来分配代理,具体取决于系统上的负载。
能否在同一台计算机上安装多个自托管代理?
是。 对于运行不消耗太多共享资源的作业的代理,这种方法很适用。 例如,如果代理运行的发布主要用于协调部署,并且不会在代理本身上执行太多操作,则可尝试使用该方法。
你可能会发现,在其他情况下,在同一台计算机上运行多个代理并不会提高效率。 例如,对于运行消耗大量磁盘和 I/O 资源的生成的代理而言,这可能并不适用。
如果并行生成作业正在使用同一个单一工具部署(如 npm 包),可能还会遇到问题。 例如,一个生成可能会更新某个依赖项,而另一个生成正在使用该依赖项,这可能会导致结果不可靠并出现错误。
取消管道作业时代理有什么行为?
对于 Microsoft 托管代理,代理将被销毁并返回到 Azure Pipelines 池。
对于自托管代理:
取消管道时,代理会将一系列命令发送到执行当前步骤的进程。
- 发送第一个命令时的超时时间为 7.5 秒。
- 如果进程没有终止,就会发送第二条命令,超时 2.5 秒。
- 如果进程没有终止,代理就会命令将其终止。
- 如果进程忽略了这两个初始终止请求,就会被强制终止。
从初始请求到终止的过程大约需要 10 秒。
针对取消管道的进程发出的命令因代理操作系统而异。
- macOS 和 Linux - 发送的命令是 SIGINT,然后是 SIGTERM,然后是 SIGKILL。
- Windows - 发送到进程的命令为 Ctrl+C,然后是 Ctrl+Break,然后是 Process.Kill。
如何以编程方式触发特定代理池的代理更新?
可以使用以下 API 触发池的代理更新:
POST https://dev.azure.com/{organization}/_apis/distributedtask/pools/{poolId}/messages?agentId={agentId}&api-version=6.0
POST https://{server url}/tfs/{collection}/_apis/distributedtask/pools/{poolId}/messages?agentId={agentId}&api-version=6.0
注意
有关 API 和 Azure DevOps Server 和 Azure DevOps Server 版本映射的详细信息,请参阅 API 和 Azure DevOps Server 版本映射
URI 参数
名称 | 在 | 必需 | 类型 | 说明 |
---|---|---|---|---|
agentId |
query | False | 字符串 | 要更新的代理。 如果未指定 - 为所有代理触发更新。 |
organization |
path | 正确 | 字符串 | Azure DevOps 组织的名称。 |
poolId |
path | True | 整数 (int32) | 要使用的代理池 |
api-version |
query | False | 字符串 | 要使用的 API 版本。 该值应设置为“6.0”,以便使用此版本的 API。 |
要触发代理更新,请求正文应为空。
注意
Azure Pipelines 代理在 GitHub 上是开源的。
了解更多
有关代理的详细信息,请参阅使用 Azure DevOps 生成应用程序学习路径中的以下模块。