Files
gitea-dynamic-runner/README.md
T
panxiao81 d7ba64d6f3
test / python (pull_request) Successful in 9s
test / shell (pull_request) Successful in 21s
接入 OpenSandbox Kata Runner 控制面
2026-09-18 00:56:10 +00:00

72 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gitea dynamic runner
为 Gitea Actions 按需创建一次性执行环境。对 workflow 提供两种稳定的 runner
接口:
```yaml
runs-on: [self-hosted, pod]
```
```yaml
runs-on: [self-hosted, vm]
```
`pod` 使用动态 Kubernetes Pod,`vm` 使用动态 Cloud Hypervisor microVM。每个环境
只执行一个 job,并在 job 结束后连同本地状态一起销毁。完整的设计约束见
[`docs/design-principles.md`](docs/design-principles.md)。
组件:
- `controller`:接收 Gitea `workflow_job` webhook,将指定 label 的 queued job
发布到 NATS JetStream。
- `worker`:领取任务、限制并发,并通过 Pod 或 microVM backend 创建一次性环境。
- `microvm-runner-launch`:为每个任务以 direct I/O 转换出 flat qcow2 root disk、创建 NoCloud seed 和 TAP,运行
Cloud Hypervisor,退出后完整清理。
- `guest-runner`:在 guest 中领取一次性 runner registration token,注册 ephemeral
runner,执行一个 job 后关机。
- `opensandbox-worker`:在正式 sandbox 集群通过 OpenSandbox `ci-vm` Pool 分配
Kata guest,按实际 Pod UID 创建临时 SPIFFE entry,并在任务结束后回收两者。身份
与 Pool 契约见 [`docs/opensandbox-runner.md`](docs/opensandbox-runner.md)。
- `pod-worker`:在 Kubernetes 中创建一次性 privileged Pod;Pod 内的 workflow 使用
host executor,Docker、BuildKit 和 kind 等工具由 pipeline 按需 setup。Runner 固定在
支持原生 job hooks 的 3.x 版本,在 workflow 第一步前等待实际任务对应的 SVID。
- `jwt-broker`:早期共享 Kubernetes runner 的过渡实验;目标架构不部署它,每个
动态 Pod 或 VM 直接取得自己的 SPIFFE 身份。
消息流使用一个 `WorkQueuePolicy` stream。相同 runner label 的所有 worker 共享同一
durable consumer;扩容只需要增加 worker 或提高单机 capacity。
当前 webhook → NATS 流程是用于尽快验证 Pod/VM 生命周期的 bootstrap 实现,不是
长期调度接口。长期目标是让 controller 作为兼容 Gitea Runner 协议的调度器直接注册、
声明 labels、领取 task,并把已领取 task 交给 Pod/VM executor;路线与迁移边界见
[`docs/runner-protocol-roadmap.md`](docs/runner-protocol-roadmap.md)。
## 开发
```bash
python -m venv .venv
. .venv/bin/activate
pip install -e '.[test]'
pytest
```
## 安全边界
- NATS 密码、webhook secret 和 Gitea registration token 只从文件读取。
- registration token 不写入 seed image;worker 通过单次 nonce endpoint 交给 guest。
- guest 启动时从仅监听 microVM bridge 的 worker endpoint 获取固定版本 Runner 和配置
资产;基础镜像无需为 Runner 发布而重做。
- `runner-vm-bootstrap.yaml` 暂时只验证 VM 调度和生命周期,不提供 SPIFFE
identity;VM agent attestation 完成前不得将它当作身份链路验证结果。
- guest runner 使用 `--ephemeral`,每台 VM 只执行一个 job。
- launcher 只接受 UUID instance ID 和 URL-safe nonce,所有临时文件都位于独立目录。
- base image 不得包含 runner identity、registration token、SSH 密码或 host key。
- LXC 内运行 Cloud Hypervisor 必须为 guest memory 启用 `shared=on`。默认的 private
memfd 映射会在 guest 写入后同时产生 shmem 与 anonymous CoW charge,使 LXC cgroup
对 guest RAM 接近双倍计费。
homelab 的 Kubernetes、OpenBao、LXC、bridge 和容量配置保留在
`panxiao81/homelab-infra`。
按需启动 Cloud Hypervisor microVM 的 Gitea Actions runner autoscaler