GitHub Actions Runner Images 完全指南:托管 Runner 虚拟机镜像的构成、发布策略与自定义构建
2026/9/15 22:24:00 网站建设 项目流程

GitHub Actions Runner Images 完全指南:托管 Runner 虚拟机镜像的构成、发布策略与自定义构建

【免费下载链接】runner-imagesGitHub Actions runner images项目地址: https://gitcode.com/GitHub_Trending/ru/runner-images

本文以 GitHub 开源仓库 runner-images 的 README.md 为主体,结合仓库内 构建文档、Packer 模板与辅助脚本源码,系统讲解 GitHub Actions / Azure DevOps 托管运行器(Runner)虚拟机镜像的完整生态:当前提供哪些镜像、标签如何演进、软件预装与版本支持策略如何制定、镜像如何发布与弃用,以及开发者如何基于本仓库在 Azure 上构建属于自己的 Runner 镜像。读完本文,你将掌握镜像标签选型、版本锁定规避迁移风险的方法,并能独立完成从构建 Agent 准备到镜像生成、部署的完整流程。

仓库定位:托管 Runner 镜像的“源代码”

runner-images 仓库保存了用于创建 GitHub Actions 与 Azure DevOps 托管运行器虚拟机镜像的全部源代码。根据 README.md 的 About 章节,本仓库生成的镜像同时服务于两类平台:GitHub Actions 的 [GitHub-hosted runners] 和 Azure Pipelines 的 Microsoft-hosted agents。这意味着镜像的可用性对两个平台一致,但两者在弃用策略上可能有所不同(详见 FAQ)。

值得注意:这是一个“生成镜像的仓库”,而不是镜像本身。要基于本仓库源码真正构建出一台可用的虚拟机,需要按照 docs/create-image-and-azure-resources.md 中的步骤在 Azure 上执行 Packer 构建流程,下文最后一节会展开说明。

可用镜像一览:三大操作系统家族的矩阵

README 用一张表格列出了当前仓库定义的全部镜像。截至当前仓库状态,可用镜像如下(架构、YAML 标签与软件清单的对应关系):

镜像架构YAML 标签详细软件清单
Ubuntu 26.04(preview)x64ubuntu-26.04Ubuntu2604-Readme.md
Ubuntu 26.04 Arm64(preview)arm64ubuntu-26.04-armUbuntu2604-Arm64-Readme.md
Ubuntu 24.04x64ubuntu-latestubuntu-24.04Ubuntu2404-Readme.md
Ubuntu 24.04 Arm64arm64ubuntu-24.04-armUbuntu2404-Arm64-Readme.md
Ubuntu 22.04x64ubuntu-22.04Ubuntu2204-Readme.md
Ubuntu 22.04 Arm64arm64ubuntu-22.04-armUbuntu2204-Arm64-Readme.md
Ubuntu Slimx64ubuntu-slimubuntu-slim-Readme.md
Xcode 27(preview)arm64xcode-27xcode-27-xlargexcode-27-arm64-Readme.md
macOS 26x64macos-latest-largemacos-26-intelmacos-26-largemacos-26-Readme.md
macOS 26 Arm64arm64macos-latestmacos-26macos-26-xlargemacos-26-arm64-Readme.md
macOS 15x64macos-15-largemacos-15-intelmacos-15-Readme.md
macOS 15 Arm64arm64macos-15macos-15-xlargemacos-15-arm64-Readme.md
macOS 14(deprecated)x64macos-14-largemacos-14-Readme.md
macOS 14 Arm64(deprecated)arm64macos-14macos-14-xlargemacos-14-arm64-Readme.md
Windows Server 2025x64windows-latestwindows-2025windows-2025-vs2026Windows2025-VS2026-Readme.md
Windows Server 2022x64windows-2022Windows2022-Readme.md
Windows 11 Arm64arm64windows-11-armWindows11-Arm64-Readme.md
Windows 11 Arm64(带 Visual Studio 2026)arm64windows-11-vs2026-armWindows11-VS2026-Arm64-Readme.md

仓库中每种镜像都配套了一份独立的 Readme(位于images/ubuntu/images/macos/images/windows/目录),详细列出该镜像中预装的每一项软件及其版本——这既是使用者查询环境的权威依据,也是撰写本文时唯一可以确认“包含哪些软件”的事实来源。

标签命名方案(Label scheme)

理解镜像标签是使用托管 Runner 的第一步,README 明确了三条规则:

  • -latest标签:一般指向当前已 GA 的最新操作系统镜像版本。
  • 切换预告:在把-latest标签迁移到新操作系统版本之前,官方会提前发布公告,给用户留出足够的时间更新 workflow。
  • -xlarge/-large后缀:这两个后缀仅存在于 macOS 镜像,且只对 GitHub Actions 可用(对应 GitHub 的 larger runners 能力),Azure DevOps 中无法使用。

从表格可以看出,ubuntu-latest目前指向 Ubuntu 24.04,windows-latest指向 Windows Server 2025,而macos-latest指向 macOS 26 Arm64。

镜像生命周期:Beta → GA → 弃用

README 将镜像的生命周期划分为三个阶段,理解这一流程有助于判断某个镜像能否在正式流水线中使用。

Beta(预览)阶段

Beta 阶段的目的在于 GA 之前收集反馈、发现并修复潜在问题。关键事实:

  • Beta 镜像每周更新一次(与 GA 相同的节奏);
  • 在 Beta 镜像上运行的 workflow不适用Actions 的客户 SLA;
  • 使用 Beta 镜像的用户被鼓励在本仓库创建 issue 提交反馈;
  • Beta 镜像的可用性形式可能不同(公开或私有)。

GA(正式可用)阶段

一个镜像要进入 GA,必须满足三条硬性标准(README 原文明确列出):

  1. 已完整经历一段 Beta 期(公开或私有);
  2. 镜像上安装的大部分主要软件,在底层操作系统上都有兼容版本
  3. Beta 期间报告的所有主要 bug 均已解决

GA 镜像受 Actions 的客户 SLA 保护,并且会依据弃用指南逐步退役——仓库只支持最新 2 个版本的操作系统。例如当前同时维护 Ubuntu 22.04 与 24.04 两张 GA 镜像,而 26.04 尚处于 preview。

-latest迁移流程(Latest Migration Process)

-latest标签(如ubuntu-latestwindows-latestmacos-latest)指向最新的稳定 OS 版本。其迁移是渐进式的,整个迁移过程持续 1~2 个月,以便用户逐步调整 workflow:

  • 迁移期间,使用-latest标签的 workflow 或 pipeline 可能会观测到操作系统版本发生变化
  • 若要避免意外的迁移,应在 YAML 中显式指定具体版本(如macos-14windows-2022ubuntu-22.04)。

这也是本文最实用的建议之一:生产流水线应尽量锁定具体版本标签,将-latest留给对最新环境不敏感的作业。

镜像发布节奏:如何跟踪变更

README 提供了四条追踪镜像变更的路径:

  1. 在仓库的 Releases 页面查找最新发布;
  2. 订阅本仓库的 release 通知;
  3. 镜像部署开始时,会创建一个pre-release;部署一结束,pre-release 即被转换为正式 release——订阅 release 通知即可同时收到 pre-release 与正式版通知;也可通过awaiting-deployment标签跟踪即将部署的变更;
  4. 对高影响变更(breaking changes、镜像 GA 或弃用),官方会提前发布到 GitHub Changelog 博客。

节奏:通常每周部署一次镜像软件的更新。也就是说,托管 Runner 上的软件版本每周都可能刷新,这解释了为什么依赖固定版本号的构建需要setup-*系列 Action 来显式安装所需版本。

软件与镜像支持策略

支持策略(Support Policy)

README 明确的支持底线如下:

  • 工具及其版本通常在弃用或 EOL 后 6 个月被移除;
  • 同一时间最多支持2 张 GA 镜像 + 1 张 Beta 镜像;一旦最新 OS 镜像标签 GA,就开始对最旧的镜像标签启动弃用流程;
  • 镜像一般包含部署时刻的最新软件包,唯一例外是 Ubuntu LTS——那里主要依赖Canonical 官方仓库提供的包。

多版本并存的安装策略

对于流行工具,镜像允许几个版本并存安装,README 给出了权威的策略表:

工具安装策略
Docker 镜像不超过 3 个最新的 LTS OS/工具版本;新镜像或新版本按标准工具请求流程添加
Java所有 LTS 版本
Node.js3 个最新的 LTS 版本
Go3 个最新的 minor 版本
Python / Ruby5 个最流行的major.minor版本
PyPy3 个最流行的major.minor版本
.NET Core2 个最新 LTS 版本 + 1 个最新版本;每个 feature 版本只装最新 patch(Ubuntu 镜像的细节见 docs/dotnet-ubuntu.md)
GCC / GNU Fortran / Clang / GNU C++3 个最新 major 版本
Android NDK1 个最新非 LTS + 2 个最新 LTS 版本
Xcode每个 macOS 版本只支持一个 major 版本;该 major 版本的所有 minor 版本均可用;beta/RC 版本仅以“as-is”形式提供在最新可用 macOS 镜像中;新 patch 发布时替换旧 patch
Xcode Platforms对已安装的 Xcode,仅保留 3 个major.minor版本的平台工具与模拟器运行时(含 beta/RC)

案例深化:Ubuntu 上的 .NET 安装方式变更。README 策略表引用了 docs/dotnet-ubuntu.md,该文档解释了从 Ubuntu 24.04 开始 .NET 安装路径发生了重大变化:Ubuntu 22.04 使用 Microsoft 包仓库安装 .NET 团队构建的 deb 包;而从 24.04 起,Canonical 与 .NET 团队合作,由 Ubuntu 自己提供 .NET 包(微软不再向 24.04 的 packages.microsoft.com feed 发布 .NET 包)。这带来两个实际影响:其一,镜像中只保留.1xxfeature band(Ubuntu 只构建发布这一“兼容性 band”,更高 band 可能有破坏性变更),需要更高 band 时官方建议使用setup-dotnetAction 安装指定版本;其二,.NET MAUI 不在 Ubuntu 的 .NET 包内(官方正在推进修复),同样应通过setup-dotnet解决。

包管理器使用(Package managers usage)

镜像生成过程中,项目使用第三方包管理器安装软件。README 给出了权威对照表:

操作系统包管理器第三方仓库与包
UbuntuAPTdocker、Eclipse-Temurin(Adoptium)、Erlang、Firefox、git-lfs、git(git-core PPA)、Google Cloud CLI、Heroku、HHvm、MongoDB、Mono、MS Edge、PostgreSQL、R
pipxansible-core、yamllint
WindowsChocolatey未安装第三方仓库
macOSHomebrewaws-cli v2(aws/homebrew-tap)、azure/bicep(Azure/homebrew-bicep)、mongodb/brew
pipxyamllint

README 同时用 NOTE 注明:第三方仓库每年都会被重新评估,以确认它们仍然有用且安全——这保证了镜像供应链的持续可信度。

镜像弃用策略(Image Deprecation Policy)

弃用是一个分阶段的公告式流程:

  1. 新 GA OS 版本发布后,最旧的镜像标签开始进入弃用流程;
  2. 弃用流程始于一次设定弃用日期的公告
  3. 临近日期时,GitHub 开始对该镜像进行定期 brownout(有计划地短暂不可用);
  4. 期间仓库会置顶 Announcement 提醒用户;
  5. 最终镜像被正式弃用,不再可用。

预安装策略(Preinstallation Policy)

决定“预装什么”的六条指导原则:

  • 流行度(Popularity):广泛使用的工具与生态优先;
  • 最新技术(Latest Technology):较新版本的工具优先;
  • 弃用(Deprecation):已 EOL 的工具与版本不加入;
  • 许可(Licensing):仅接受 MIT、Apache 或 GNU 许可;
  • 时间与空间(Time & Space):评估预装工具节省的时间与占用的镜像空间;
  • 支持(Support):若某工具需要同时维护多个版本,会评估其维护成本。

FAQ 中进一步说明:部分工具部署时始终安装最新版,另一部分则固定到特定版本——两者结合,正是“最新”与“可复现”之间的平衡。

默认版本更新策略(Default Version Update Policy)

  • 一般而言,新版本装入镜像后,默认版本更新会在部署前 2 周发布公告;
  • 潜在危险的更新,公告与部署之间的时间线可延长至1 个月

如何与仓库互动

  • Issues:提交 bug 报告、请求新增/更新工具,使用合适的模板创建 issue;
  • Discussions:分享对镜像配置、预装软件的想法或提出新思路,前往 GitHub Community 的 Actions 分类创建讨论(创建前请先搜索确认无相似主题)。

常见问题(FAQs)

README 的 FAQ 章节回答了六个高频问题,这里完整整理:

  1. GitHub Actions 与 Azure DevOps 可用的镜像一样吗?可用性相同,但弃用策略可能不同,细节分别见各自官方文档。
  2. 如何知道我的构建用了哪个镜像版本?镜像部署通常需要 2~3 天,且main分支的文档只在部署完成后才更新。要确认某次构建实际使用的镜像版本与软件版本,查看 GitHub Actions 的Set up job步骤日志或 Azure DevOps 的Initialize job步骤日志即可。
  3. 会提供其他 Linux 发行版吗?官方不计划提供。推荐使用 Docker 在托管 Runner 镜像上构建其他发行版环境;或者使用 self-hosted runners 完全自定义虚拟机镜像。
  4. 如何为 macOS 源码做贡献?macOS 源码就在本仓库且公开,但 macOS 镜像生成的 CI 目前还不支持外部贡献,暂不接受 pull request;在此期间请通过 issue 提出工具请求。
  5. GitHub 如何决定镜像上装哪些工具?部分工具部署时安装最新版,部分固定版本,详见上文“预安装策略”。
  6. 如何请求预装新工具?先创建 issue 并获得批准,再提交 pull request。
  7. 自定义镜像应该用哪个分支?官方强烈建议使用main分支构建。仓库中的多个分支和 release 只是“文档里程碑”(反映某时间点镜像内的软件版本),当前构建不是幂等的——用特定 tag 构建 runner 镜像不保证成功。

纵深:如何基于本仓库构建自己的 Runner 镜像

README 指向的 docs/create-image-and-azure-resources.md 给出了完整构建流程,本文结合源码做要点深化(详细步骤以该文档为准)。

底层原理:Packer + Azure

构建的核心是Packer(仓库要求 1.8.2 或更高):每个镜像由一份HCL2 Packer 模板描述(指定在 Azure 中构建、安装软件与准备磁盘的步骤)。流程为:Packer 通过 Azure CLI 初始化与 Azure 订阅的连接,创建临时资源(资源组、网络接口、基于模板中“干净”镜像的虚拟机)→ 通过 SSH(Linux)或 WinRM(Windows)连接虚拟机并逐一执行安装步骤 →任一步骤失败则中止并销毁临时 VM→ 全部成功后从临时 VM 的磁盘创建托管镜像并删除 VM。Packer 还会尽力清理其创建的临时资源。

源码佐证:GenerateResourcesAndImage辅助函数(helpers/GenerateResourcesAndImage.ps1)内部用Get-PackerTemplateImageType枚举(Windows2022Windows2025Windows2025_vs2026Ubuntu2204Ubuntu2404Ubuntu2604)映射到具体模板文件,例如Ubuntu2404build.ubuntu-24_04.pkr.hclWindows2022build.windows-2022.pkr.hcl,并返回 Packer-only所需的 BuildName 与image_os值(如ubuntu24win22)。

构建 Agent 准备

构建 Agent(运行 Packer 的机器,任意 Windows/Linux 物理机或虚拟机,也可用 Azure VM)需安装:

  • Packer 1.8.2+(Windows 可用choco install packer);
  • Git(Windows 可用choco install git -params '"/GitAndUnixToolsOnPath"');
  • PowerShell 5.0+(Linux 需通过微软 Linux 软件仓库安装powershell包);
  • Azure CLI(Windows 可用Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows ...安装)。

手动生成镜像

克隆仓库后用 PowerShell 导入辅助脚本并调用:

git clone <本仓库地址> Set-Location runner-images Import-Module .\helpers\GenerateResourcesAndImage.ps1

然后调用GenerateResourcesAndImage,四个必填参数为:SubscriptionId(Azure 订阅 ID)、ResourceGroupName(存放产物的资源组,必须已存在)、AzureLocation(如 "East US")、ImageType(有效值即上文枚举的六种)。该函数会自动创建全部 Azure 资源并启动 Packer 构建。

常用可选参数还包括:Tags(为资源打标签的 HashTable)、AzureClientId/AzureClientSecret/AzureTenantId(非交互式认证)、RestrictToAgentIpAddress(仅允许构建 Agent 公网 IP 访问临时 VM)、ManagedImageName(默认Runner-Image-{ImageType})、OnError(默认ask)。完整参数用get-help GenerateResourcesAndImage -Detailed查看。

网络安全与认证

  • 公网模式:若构建 Agent 在订阅之外,会使用公共网络接口与公网 IP,需确保防火墙放行 WinRM(TCP 5986)与 SSH(TCP 22),既包含 Agent 出站也包含临时 VM 入站;设置RestrictToAgentIpAddress=$true可把访问限制在 Agent 公网 IP。
  • 私有网络模式:Agent 与临时 VM 在同一订阅时,可设置环境变量VNET_RESOURCE_GROUPVNET_NAMEVNET_SUBNET让 Packer 走私有虚拟网络。
  • 认证:Packer 使用 Service Principal 访问 Azure。GenerateResourcesAndImage默认通过Connect-AzAccount交互式认证;非交互场景需自行创建具备所选订阅读写权限的 Service Principal,并传入AzureClientIdAzureClientSecretAzureTenantId。文档还给出了用New-AzADServicePrincipal创建 SP 并授予Contributor角色的完整 PowerShell 示例;源码层面,函数还支持UseOidc(GitHub Actions OIDC 联邦凭据认证)与OidcRequestToken/OidcRequestUrl参数。

生成机的部署

镜像生成后,用 helpers/CreateAzureVMFromPackerTemplate.ps1 从托管镜像创建 VM:

Import-Module .\helpers\CreateAzureVMFromPackerTemplate.ps1 CreateAzureVMFromPackerTemplate -SubscriptionId {YourSubscriptionId} -ResourceGroupName {ResourceGroupName} -ManagedImageName "Runner-Image-Ubuntu2204" -VirtualMachineName "testvm1" -AdminUsername "shady1" -AdminPassword "SomeSecurePassword1" -AzureLocation "eastus"

自动化生成(CI/CD 集成)

在流水线中直接调用 Packer,先安装 Azure 插件再构建:

packer plugins install github.com/hashicorp/azure 2.2.1 packer build -only "$BuildName.*" ` -var "subscription_id=$SubscriptionId" ` -var "client_id=$ClientId" ` -var "client_secret=$ClientSecret" ` -var "install_password=$InstallPassword" ` -var "location=$Location" ` -var "image_os=$ImageOS" ` -var "managed_image_name=$ImageName" ` -var "managed_image_resource_group_name=$ImageResourceGroupName" ` -var "tenant_id=$TenantId" ` $TemplatePath

参数说明:BuildName为模板build{}块中定义的构建名(如ubuntu-24_04windows-2025);InstallPassword是软件安装用户密码(仅 Windows);ImageOS是临时 VM 的操作系统类型(如ubuntu24win25);TemplatePath指向模板目录(如images/windows/templates)。

必需变量(模板变量 ↔ 环境变量的对应关系,均可在 images/ubuntu/templates/variable.ubuntu.pkr.hcl 中找到默认值定义):

模板变量环境变量说明
subscription_idARM_SUBSCRIPTION_ID执行构建的订阅
client_idARM_CLIENT_ID与 builder 关联的 AD Service Principal
client_secretARM_CLIENT_SECRETSP 的密码/密钥;设置了client_cert_pathclient_jwt时可省略
client_cert_pathARM_CLIENT_CERT_PATH包含 SP 证书与私钥的 PEM 文件路径;设置了client_secretclient_jwt时可省略
client_jwtARM_CLIENT_JWT用于联合/工作负载身份认证的 bearer JWT(如 Azure DevOps workload identity federation);设置了client_secretclient_cert_path时可省略
locationARM_RESOURCE_LOCATION构建 VM 所在的 Azure 数据中心
managed_image_resource_group_nameARM_RESOURCE_GROUP存放最终产物的资源组

可选变量managed_image_name(默认Runner-Image-{{ImageType}})、build_resource_group_name(指定已存在的构建资源组;默认会创建并销毁临时资源组)、object_idtenant_id(为空时按subscription_id反查)、temp_resource_group_name(临时资源组名,为空则随机分配)、private_virtual_network_with_public_ipvirtual_network_name(使用既有 VNet、不分配公网 IP)、virtual_network_resource_group_namevirtual_network_subnet_name

Builder 变量azure-armbuilder 专用,可覆盖以调整构建性能,见 images/ubuntu/templates/source.ubuntu.pkr.hcl):vm_size(构建用 VM 规格,默认Standard_D4s_v4)、image_os(临时 VM 的 OS 类型)、image_version(启动的 OS 版本,默认latest)。此外 locals.ubuntu.pkr.hcl 定义了各image_os对应的 Azure Marketplace 镜像 SKU(如ubuntu24canonical:ubuntu-24_04-lts:server)与 75GB 的默认系统盘大小。

Toolset:可裁剪的软件配置

部分预装软件的配置集中在toolset.json中(如 images/ubuntu/toolsets/toolset-2404.json),定义 Ruby、Python、Go 版本列表、PowerShell 模块与 VS 组件等。以 toolset-2404.json 为例,toolcache段声明了 Python(3.10.~3.14.)、PyPy(3.9~3.11)、node(22.、24.)、go(1.24.~1.26.,默认 1.24.)、Ruby(3.2.~4.0.)、CodeQL()等版本通配符;java段声明默认 JDK 17、全部 LTS 版本 8/11/17/21/25 及 Maven 3。README 说明:若某些工具用不到,可以修改这些文件以缩短构建时间、缩小镜像体积

Post-generation 脚本:修复用户态环境

镜像生成过程中创建的用户在最终镜像中不存在,因此与用户主目录相关的配置和目录权限需要修正。脚本位于仓库post-gen目录(Ubuntu 在 images/ubuntu/assets/post-gen,Windows 在 images/windows/assets/post-gen),构建时会被复制到镜像中(Linux/opt/post-generation、WindowsC:\post-generation)。注意:Linux 默认用户应具备 sudo 权限。

运行方式(在 Azure 部署的 VM 上执行):

# Ubuntu sudo su -c "find /opt/post-generation -mindepth 1 -maxdepth 1 -type f -name '*.sh' -exec bash {} \;"
# Windows Get-ChildItem C:\post-generation -Filter *.ps1 | ForEach-Object { & $_.FullName }

Ubuntu 侧脚本(以当前仓库实际文件为准):cleanup-logs.sh(清理构建过程日志)、environment-variables.sh(将默认用户主目录相关环境变量中的$HOME替换为默认用户的 home)、systemd-linger.sh(systemd linger 配置)。Windows 侧脚本:GenerateIISExpressCertificate.ps1(生成并导入 IIS Express HTTPS 证书)、InternetExplorerConfiguration.ps1(关闭 IE 增强安全配置)、Msys2FirstLaunch.ps1(初始化 MSYS2 bash 用户配置文件)、VSConfiguration.ps1(执行 Visual Studio 初始配置)。

结语

runner-images 仓库的价值在于把“托管 Runner 上装了什么、为什么装、什么时候换”这一黑盒变成了完全透明的开源工程。通过本文你可以:根据支持矩阵与标签方案选对镜像标签、用显式版本锁定规避-latest迁移风险、理解软件预装与弃用背后的策略逻辑,以及借助 Packer 模板与辅助脚本在 Azure 上构建、定制属于自己的 Runner 镜像。若需进一步动手,优先阅读 docs/create-image-and-azure-resources.md,并以main分支为构建基准。

【免费下载链接】runner-imagesGitHub Actions runner images项目地址: https://gitcode.com/GitHub_Trending/ru/runner-images

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询