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) | x64 | ubuntu-26.04 | Ubuntu2604-Readme.md |
| Ubuntu 26.04 Arm64(preview) | arm64 | ubuntu-26.04-arm | Ubuntu2604-Arm64-Readme.md |
| Ubuntu 24.04 | x64 | ubuntu-latest或ubuntu-24.04 | Ubuntu2404-Readme.md |
| Ubuntu 24.04 Arm64 | arm64 | ubuntu-24.04-arm | Ubuntu2404-Arm64-Readme.md |
| Ubuntu 22.04 | x64 | ubuntu-22.04 | Ubuntu2204-Readme.md |
| Ubuntu 22.04 Arm64 | arm64 | ubuntu-22.04-arm | Ubuntu2204-Arm64-Readme.md |
| Ubuntu Slim | x64 | ubuntu-slim | ubuntu-slim-Readme.md |
| Xcode 27(preview) | arm64 | xcode-27或xcode-27-xlarge | xcode-27-arm64-Readme.md |
| macOS 26 | x64 | macos-latest-large、macos-26-intel、macos-26-large | macos-26-Readme.md |
| macOS 26 Arm64 | arm64 | macos-latest、macos-26或macos-26-xlarge | macos-26-arm64-Readme.md |
| macOS 15 | x64 | macos-15-large或macos-15-intel | macos-15-Readme.md |
| macOS 15 Arm64 | arm64 | macos-15或macos-15-xlarge | macos-15-arm64-Readme.md |
| macOS 14(deprecated) | x64 | macos-14-large | macos-14-Readme.md |
| macOS 14 Arm64(deprecated) | arm64 | macos-14或macos-14-xlarge | macos-14-arm64-Readme.md |
| Windows Server 2025 | x64 | windows-latest、windows-2025或windows-2025-vs2026 | Windows2025-VS2026-Readme.md |
| Windows Server 2022 | x64 | windows-2022 | Windows2022-Readme.md |
| Windows 11 Arm64 | arm64 | windows-11-arm | Windows11-Arm64-Readme.md |
| Windows 11 Arm64(带 Visual Studio 2026) | arm64 | windows-11-vs2026-arm | Windows11-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 原文明确列出):
- 已完整经历一段 Beta 期(公开或私有);
- 镜像上安装的大部分主要软件,在底层操作系统上都有兼容版本;
- Beta 期间报告的所有主要 bug 均已解决。
GA 镜像受 Actions 的客户 SLA 保护,并且会依据弃用指南逐步退役——仓库只支持最新 2 个版本的操作系统。例如当前同时维护 Ubuntu 22.04 与 24.04 两张 GA 镜像,而 26.04 尚处于 preview。
-latest迁移流程(Latest Migration Process)
-latest标签(如ubuntu-latest、windows-latest、macos-latest)指向最新的稳定 OS 版本。其迁移是渐进式的,整个迁移过程持续 1~2 个月,以便用户逐步调整 workflow:
- 迁移期间,使用
-latest标签的 workflow 或 pipeline 可能会观测到操作系统版本发生变化; - 若要避免意外的迁移,应在 YAML 中显式指定具体版本(如
macos-14、windows-2022、ubuntu-22.04)。
这也是本文最实用的建议之一:生产流水线应尽量锁定具体版本标签,将-latest留给对最新环境不敏感的作业。
镜像发布节奏:如何跟踪变更
README 提供了四条追踪镜像变更的路径:
- 在仓库的 Releases 页面查找最新发布;
- 订阅本仓库的 release 通知;
- 镜像部署开始时,会创建一个pre-release;部署一结束,pre-release 即被转换为正式 release——订阅 release 通知即可同时收到 pre-release 与正式版通知;也可通过
awaiting-deployment标签跟踪即将部署的变更; - 对高影响变更(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.js | 3 个最新的 LTS 版本 |
| Go | 3 个最新的 minor 版本 |
| Python / Ruby | 5 个最流行的major.minor版本 |
| PyPy | 3 个最流行的major.minor版本 |
| .NET Core | 2 个最新 LTS 版本 + 1 个最新版本;每个 feature 版本只装最新 patch(Ubuntu 镜像的细节见 docs/dotnet-ubuntu.md) |
| GCC / GNU Fortran / Clang / GNU C++ | 3 个最新 major 版本 |
| Android NDK | 1 个最新非 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 给出了权威对照表:
| 操作系统 | 包管理器 | 第三方仓库与包 |
|---|---|---|
| Ubuntu | APT | docker、Eclipse-Temurin(Adoptium)、Erlang、Firefox、git-lfs、git(git-core PPA)、Google Cloud CLI、Heroku、HHvm、MongoDB、Mono、MS Edge、PostgreSQL、R |
| pipx | ansible-core、yamllint | |
| Windows | Chocolatey | 未安装第三方仓库 |
| macOS | Homebrew | aws-cli v2(aws/homebrew-tap)、azure/bicep(Azure/homebrew-bicep)、mongodb/brew |
| pipx | yamllint |
README 同时用 NOTE 注明:第三方仓库每年都会被重新评估,以确认它们仍然有用且安全——这保证了镜像供应链的持续可信度。
镜像弃用策略(Image Deprecation Policy)
弃用是一个分阶段的公告式流程:
- 新 GA OS 版本发布后,最旧的镜像标签开始进入弃用流程;
- 弃用流程始于一次设定弃用日期的公告;
- 临近日期时,GitHub 开始对该镜像进行定期 brownout(有计划地短暂不可用);
- 期间仓库会置顶 Announcement 提醒用户;
- 最终镜像被正式弃用,不再可用。
预安装策略(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 章节回答了六个高频问题,这里完整整理:
- GitHub Actions 与 Azure DevOps 可用的镜像一样吗?可用性相同,但弃用策略可能不同,细节分别见各自官方文档。
- 如何知道我的构建用了哪个镜像版本?镜像部署通常需要 2~3 天,且
main分支的文档只在部署完成后才更新。要确认某次构建实际使用的镜像版本与软件版本,查看 GitHub Actions 的Set up job步骤日志或 Azure DevOps 的Initialize job步骤日志即可。 - 会提供其他 Linux 发行版吗?官方不计划提供。推荐使用 Docker 在托管 Runner 镜像上构建其他发行版环境;或者使用 self-hosted runners 完全自定义虚拟机镜像。
- 如何为 macOS 源码做贡献?macOS 源码就在本仓库且公开,但 macOS 镜像生成的 CI 目前还不支持外部贡献,暂不接受 pull request;在此期间请通过 issue 提出工具请求。
- GitHub 如何决定镜像上装哪些工具?部分工具部署时安装最新版,部分固定版本,详见上文“预安装策略”。
- 如何请求预装新工具?先创建 issue 并获得批准,再提交 pull request。
- 自定义镜像应该用哪个分支?官方强烈建议使用
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-PackerTemplate将ImageType枚举(Windows2022、Windows2025、Windows2025_vs2026、Ubuntu2204、Ubuntu2404、Ubuntu2604)映射到具体模板文件,例如Ubuntu2404→build.ubuntu-24_04.pkr.hcl、Windows2022→build.windows-2022.pkr.hcl,并返回 Packer-only所需的 BuildName 与image_os值(如ubuntu24、win22)。
构建 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_GROUP、VNET_NAME、VNET_SUBNET让 Packer 走私有虚拟网络。 - 认证:Packer 使用 Service Principal 访问 Azure。
GenerateResourcesAndImage默认通过Connect-AzAccount交互式认证;非交互场景需自行创建具备所选订阅读写权限的 Service Principal,并传入AzureClientId、AzureClientSecret、AzureTenantId。文档还给出了用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_04、windows-2025);InstallPassword是软件安装用户密码(仅 Windows);ImageOS是临时 VM 的操作系统类型(如ubuntu24、win25);TemplatePath指向模板目录(如images/windows/templates)。
必需变量(模板变量 ↔ 环境变量的对应关系,均可在 images/ubuntu/templates/variable.ubuntu.pkr.hcl 中找到默认值定义):
| 模板变量 | 环境变量 | 说明 |
|---|---|---|
subscription_id | ARM_SUBSCRIPTION_ID | 执行构建的订阅 |
client_id | ARM_CLIENT_ID | 与 builder 关联的 AD Service Principal |
client_secret | ARM_CLIENT_SECRET | SP 的密码/密钥;设置了client_cert_path或client_jwt时可省略 |
client_cert_path | ARM_CLIENT_CERT_PATH | 包含 SP 证书与私钥的 PEM 文件路径;设置了client_secret或client_jwt时可省略 |
client_jwt | ARM_CLIENT_JWT | 用于联合/工作负载身份认证的 bearer JWT(如 Azure DevOps workload identity federation);设置了client_secret或client_cert_path时可省略 |
location | ARM_RESOURCE_LOCATION | 构建 VM 所在的 Azure 数据中心 |
managed_image_resource_group_name | ARM_RESOURCE_GROUP | 存放最终产物的资源组 |
可选变量:managed_image_name(默认Runner-Image-{{ImageType}})、build_resource_group_name(指定已存在的构建资源组;默认会创建并销毁临时资源组)、object_id、tenant_id(为空时按subscription_id反查)、temp_resource_group_name(临时资源组名,为空则随机分配)、private_virtual_network_with_public_ip、virtual_network_name(使用既有 VNet、不分配公网 IP)、virtual_network_resource_group_name、virtual_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(如ubuntu24→canonical: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),仅供参考