You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
多组织共享集成测试环境问题分析与解决方案
问题背景
当前架构
当前集成测试采用基于 GitHub Actions 的集成测试方案,通过自托管 Runner(Self-hosted Runner)连接本地硬件测试环境。整体架构如下:
graph TB subgraph GitHub["GitHub 平台层"] direction LR OrgA["组织 A<br/>(arceos-hypervisor)<br/>└─ 仓库: axvisor<br/>└─ .github/workflows/"] OrgB["组织 B"] OrgC["组织 C"] OrgN["..."] end subgraph Runners["自托管 Runner 层"] direction LR Runner1["Runner-1"] Runner2["Runner-2"] Runner3["Runner-3"] RunnerN["Runner-N"] end subgraph Hardware["本地测试环境(独占资源)"] direction TB subgraph Devices["硬件设备"] Dev1["开发板 1"] Dev2["开发板 2"] Dev3["开发板 3"] DevX["x86 设备"] end subgraph Control["控制设备"] Power["电源控制"] Router["路由器"] PXE["PXE 服务"] end end OrgA -->|Webhook| Runner1 OrgB -->|Webhook| Runner2 OrgC -->|Webhook| Runner3 OrgN -->|Webhook| RunnerN Runner1 --> Hardware Runner2 --> Hardware Runner3 --> Hardware RunnerN --> Hardware style GitHub fill:#e1f5ff style Runners fill:#fff4e1 style Hardware fill:#ffe1f5 style Devices fill:#f0f0f0 style Control fill:#f0f0f0核心问题
由于当前我们组件化内核的各个组件和衍生的 OS 分布在不同的 GitHub 组织中(例如
arceos-hypervisor、arceos-org等),而集成测试环境(硬件设备、测试服务器)是物理上唯一的独占资源。当多个组织的仓库同时触发 CI 时,会出现以下问题:技术原因:
影响范围:
详细问题分析
1. GitHub Actions 的多租户隔离机制
GitHub Actions 的设计天然支持多租户隔离:
graph LR subgraph OrgA["组织 A 的 Runner Pool"] direction TB RunnerA1["Runner A1<br/>只能执行组织 A 的任务"] RunnerA2["Runner A2<br/>只能执行组织 A 的任务"] RunnerAN["..."] end subgraph OrgB["组织 B 的 Runner Pool"] direction TB RunnerB1["Runner B1<br/>只能执行组织 B 的任务"] RunnerB2["Runner B2<br/>只能执行组织 B 的任务"] RunnerBN["..."] end style OrgA fill:#e1f5ff style OrgB fill:#ffe1f5 style RunnerA1 fill:#ffffff style RunnerA2 fill:#ffffff style RunnerB1 fill:#ffffff style RunnerB2 fill:#ffffff隔离特性:
2. 硬件资源的独占性
测试环境的硬件设备具有独占性:
3. 当前方案的局限性
基于现有实现:
# 每个 Runner 独立注册到一个组织 ./config.sh --url https://github.com/arceos-hypervisor/axvisor \ --token TOKEN_A \ --name runner-1 ./config.sh --url https://github.com/another-org/repo \ --token TOKEN_B \ --name runner-2导致问题场景:
主流解决方案
方案一:GitHub Enterprise Server(企业版)
方案概述
使用 GitHub Enterprise Server 将所有组织纳入统一的企业账号下,将 Runner 注册到 Enterprise 而非单个组织,通过企业级 Runner Pool 实现跨组织的资源共享和统一调度。
架构设计
与 GitHub Actions(开源版)的不同,企业版可以利用 GitHub 原生的任务调度机制实现并发控制,完全兼容 GitHub Actions 的工作流语法,无需修改现有的 CI 配置文件。
graph TB subgraph Enterprise["GitHub Enterprise Server"] direction TB subgraph Orgs["组织层"] direction LR OrgA["组织 A<br/>(axvisor-core)"] OrgB["组织 B<br/>(axvisor-apps)"] OrgC["组织 C<br/>(axvisor-drivers)"] end subgraph RunnerPool["企业级 Runner Pool<br/>(共享资源池)"] direction LR SharedRunner1["共享 Runner-1<br/>(hardware-test)"] SharedRunner2["共享 Runner-2<br/>(hardware-test)"] SharedRunnerN["共享 Runner-N"] end subgraph Scheduler["企业级调度器"] Sched["统一任务调度<br/>并发控制"] end end subgraph Hardware["本地测试环境"] direction TB HW1["硬件设备 1"] HW2["硬件设备 2"] HWN["..."] end OrgA --> Scheduler OrgB --> Scheduler OrgC --> Scheduler Scheduler --> RunnerPool RunnerPool --> Hardware style Enterprise fill:#e1f5ff style Orgs fill:#ffffff style RunnerPool fill:#fff4e1 style Scheduler fill:#f0f0f0 style Hardware fill:#ffe1f5 style OrgA fill:#e8f4f8 style OrgB fill:#e8f4f8 style OrgC fill:#e8f4f8实施步骤
1. 申请和部署 GitHub Enterprise
选择部署方式:
选项 A:GitHub Enterprise Cloud(云端托管)
选项 B:GitHub Enterprise Server(自托管)
2. 迁移组织到企业
3. 配置企业级 Runner
步骤 3.1:创建 Runner Group
步骤 3.2:获取注册令牌
步骤 3.3:注册 Runner 到企业级别
步骤 3.4:配置并发控制
4. 配置访问控制策略
创建 Runner Group 并限制访问
设置组织级别权限
5. 更新工作流配置
对于已经支持使用当前的测试环境的组织,例如 AxVisor,则无需任何更改;对于其他组织,参考 AxVisor 的 CI 更新使用自托管 runner 即可。
6. 验证配置
测试跨组织访问
监控 Runner 状态
方案二:第三方 CI/CD 平台
方案概述
使用支持自托管和并发控制的第三方 CI/CD 平台(如 GitLab CI、Jenkins、CircleCI 等)替代 GitHub Actions,通过统一任务队列和集中式调度解决多组织共享硬件资源的问题。
架构设计
所有组织的代码仍然托管在 GitHub,无需迁移代码仓库,通过 Webhook 触发 CI/CD 平台。CI 平台层接收来自 GitHub 的推送事件,然后执行处理。所有组织的任务进入同一个队列,根据并发限制配置分配任务给 Agent。
graph TB subgraph GitHub["GitHub 仓库层"] direction LR OrgA["org-a/repo"] OrgB["org-b/repo"] OrgC["org-c/repo"] end subgraph CI["第三方 CI 平台<br/>(GitLab CI / Jenkins)"] direction TB subgraph Webhook["Webhook 接收"] WH["Webhook Server"] end subgraph Queue["统一任务队列"] Task1["Task 1<br/>(org-a/repo)<br/>[执行中]"] Task2["Task 2<br/>(org-b/repo)<br/>[排队中]"] Task3["Task 3<br/>(org-c/repo)<br/>[排队中]"] end subgraph Scheduler["中央调度器"] Sched["调度器<br/>concurrent=1"] end end subgraph Agents["自托管 Executor/Agent"] direction LR Agent1["Agent-1<br/>串行执行任务"] Agent2["Agent-2"] AgentN["..."] end subgraph Hardware["本地测试环境"] direction TB HW1["硬件设备 1"] HW2["硬件设备 2"] HWN["..."] end OrgA -->|Webhook| Webhook OrgB -->|Webhook| Webhook OrgC -->|Webhook| Webhook Webhook --> Queue Queue --> Scheduler Scheduler --> Agents Agents --> Hardware style GitHub fill:#e1f5ff style CI fill:#fff4e1 style Queue fill:#ffffff style Scheduler fill:#f0f0f0 style Agents fill:#e1f5ff style Hardware fill:#ffe1f5 style Task1 fill:#d4edda style Task2 fill:#fff3cd style Task3 fill:#fff3cd方案 2.1:GitLab CI with Self-Hosted Runners
实施步骤
安装 GitLab CE/EE
# 使用 Docker 安装 GitLab docker run -d \ --hostname gitlab.example.com \ --publish 443:443 --publish 80:80 --publish 22:22 \ --name gitlab \ --restart always \ --volume /srv/gitlab/config:/etc/gitlab \ --volume /srv/gitlab/logs:/var/log/gitlab \ --volume /srv/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest配置 GitLab Runner
配置并发控制
创建 CI 配置
配置 GitHub 集成
方案 2.2:Jenkins with Shared Agents
实施步骤
安装 Jenkins
# 使用 Docker 安装 docker run -d \ --name jenkins \ -p 8080:8080 -p 50000:50000 \ -v jenkins_home:/var/jenkins_home \ jenkins/jenkins:lts配置 GitHub 集成
配置共享 Agent
设置 Agent 并发限制
方案 2.3:CircleCI Self-Hosted Runner
实施步骤
安装 CircleCI Self-Hosted Runner
配置并发控制
方案三:修改自托管 Runner 程序
方案概述
通过修改 GitHub Actions 自托管 Runner 的行为,实现跨组织的任务排队和串行执行。
架构设计
GitHub Actions Runner 是完全开源的,开源地址: https://github.com/actions/runner,许可证: MIT License。
graph TB subgraph Orgs["多个 GitHub 组织"] direction LR OrgA["组织 A"] OrgB["组织 B"] OrgC["组织 C"] OrgN["..."] end subgraph Wrapper["自定义 Runner 包装层"] direction TB subgraph LockService["分布式锁服务<br/>(Redis / etcd / 文件锁)"] Lock1["Lock: hardware-dev-1<br/>(org-a) [持有中]"] Lock2["Lock: hardware-dev-2<br/>(org-b) [等待中]"] Lock3["Lock: serial-port-1<br/>(org-c) [等待中]"] end end subgraph Runners["实际 Runner 执行层"] direction LR Runner1["Runner-1"] Runner2["Runner-2"] Runner3["Runner-3"] RunnerN["..."] end subgraph Hardware["本地测试环境"] direction TB HW1["硬件设备 1"] HW2["硬件设备 2"] HWN["..."] end OrgA --> Wrapper OrgB --> Wrapper OrgC --> Wrapper OrgN --> Wrapper Wrapper --> Runners Runners --> Hardware style Orgs fill:#e1f5ff style Wrapper fill:#fff4e1 style LockService fill:#ffffff style Runners fill:#e1f5ff style Hardware fill:#ffe1f5 style Lock1 fill:#d4edda style Lock2 fill:#fff3cd style Lock3 fill:#fff3cd实施方案 3.1:基于 Redis 的分布式锁
系统架构
部署步骤
安装 Redis
修改 Runner 启动脚本
配置 Docker Compose
配置多个 Runner
实施方案 3.2:基于文件锁的简单方案
系统架构
部署步骤
创建包装脚本
# 保存为 runner-wrapper.sh chmod +x runner-wrapper.sh修改 Runner 服务
重启服务
实施方案 3.3:基于 etcd 的分布式锁
系统架构
部署步骤
安装 etcd
# 使用 Docker 安装 etcd docker run -d \ --name etcd \ -p 2379:2379 \ -p 2380:2380 \ -e ETCD_NAME=etcd0 \ -e ETCD_INITIAL_ADVERTISE_PEER_URLS=http://localhost:2380 \ -e ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 \ -e ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \ -e ETCD_ADVERTISE_CLIENT_URLS=http://localhost:2379 \ -e ETCD_INITIAL_CLUSTER=etcd0=http://localhost:2380 \ -e ETCD_INITIAL_CLUSTER_STATE=new \ -e ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster \ bitnami/etcd:latest编译包装程序
配置 Runner
方案四:为每个组织部署一套独立测试环境
如题
附录
A. 相关文档
B. 示例代码仓库
Beta Was this translation helpful? Give feedback.
All reactions