Orchard Worker 部署实战指南:Bootstrap Token 获取、launchd 与 Ansible 批量部署
2026/9/17 20:09:16 网站建设 项目流程

Orchard Worker 部署实战指南:Bootstrap Token 获取、launchd 与 Ansible 批量部署

【免费下载链接】tartmacOS and Linux VMs on Apple Silicon to use in CI and other automations项目地址: https://gitcode.com/GitHub_Trending/ta/tart

Orchard 是一个面向 CI 与自动化场景的 VM 编排集群:Controller 负责管理与调度,Worker 负责在 macOS 主机上执行 VM。本文以 docs/orchard/deploying-workers.md 为骨架,完整讲解如何为 Worker 创建最小权限服务账号、生成 Bootstrap Token,并分别通过 launchd(macOS 原生守护进程)与 Ansible(批量配置)两种持久化方式部署 Worker,同时结合仓库内 架构与安全文档、Controller 部署文档 与 CLI 使用文档 说明其底层信任机制与调度原理。读完本文,你将能独立把一个或多个 macOS 主机接入 Orchard Controller,形成可被客户端调度 VM 的集群。

一、前置概念:Orchard 集群中的 Worker 角色

在深入了解部署步骤之前,先明确 Worker 在 Orchard 集群中的位置。根据 docs/orchard/architecture-and-security.md 的描述,Orchard 集群由三个组件构成:

组件职责部署位置
Controller管理集群、调度资源唯一实例,需被 Worker 与 Client 直接访问
Worker执行 VM可部署一个或多个,可位于 NAT 之后
Client通过 Orchard CLI 或 API 创建、修改、删除 Controller 上的资源任意数量,任意位置

网络要求:只有 Controller 需要被 Worker 和 Client 直接访问;Worker 与 Client 可以部署在任意位置(例如 NAT 之后)。这意味着 Worker 只需主动"外连"到 Controller,非常适合放在机房、家庭网络或 CI 环境的 macOS 主机上。

平台限制:与 Controller 可以部署在 Linux 上(甚至提供了容器镜像)不同,Worker 只能部署在 macOS 机器上——因为 VM 的创建与运行依赖 macOS 的虚拟化能力。这也是本文两种部署方式(launchd、Ansible)都面向 macOS 主机的根本原因。

Worker 与 Controller 之间的信任建立

安全上,Orchard 采用"自动 PKI 验证 + 自签名证书手动验证"的混合模式(详见 docs/orchard/architecture-and-security.md 的 Security 章节):

  • 若 Controller 使用公开有效证书(通过--controller-cert/--controller-key手动配置),Worker 直接依赖系统根 CA 完成 PKI 验证;
  • 若 Controller 使用自签名证书(首次启动未指定证书参数时自动生成),Bootstrap Token 中会内嵌 Controller 证书,Worker 仅信任该证书进行连接;
  • 若 Bootstrap Token 不含证书(对应公开有效证书的 Controller),Worker 则走 PKI 验证;可用--no-pki强制禁用 PKI,让 Worker 快速失败,避免在证书不匹配时静默降级。

理解这一点,就能明白为什么下面的部署流程首先要"获取 Bootstrap Token"——它是 Worker 与 Controller 建立信任、免交互接入集群的关键凭据。

二、第一步:获取 Bootstrap Token

2.1 创建最小权限服务账号

Worker 连接 Controller 需要以某个服务账号(service account)的身份进行,但不需要管理员权限。官方推荐创建一个只含 Worker 运行所需最小角色集合的服务账号,即compute:readcompute:write

orchard create service-account worker-pool-m1 --roles "compute:read" --roles "compute:write"

参数说明:

  • worker-pool-m1:服务账号名称,可按机器池语义命名(例如worker-pool-m1表示 M1 芯片的机器池),便于区分后续不同批次或型号的 Worker;
  • --roles "compute:read":授予读取计算资源(VM 列表、状态等)的权限;
  • --roles "compute:write":授予写入计算资源(创建、启停 VM 等)的权限,Worker 正是靠此权限在 Controller 上注册并执行 VM 调度任务。

这里刻意采用"最小权限"原则:Worker 只需要compute相关的读写能力即可完成工作,不需要vmservice-account等其他资源的管理权限,从而缩小凭据泄露时的攻击面。

提示:若你尚不清楚服务账号与 Controller 如何配对,可先阅读 docs/orchard/using-orchard-cli.md 的 "Setting up a context" 一节——首次运行orchard controller run时控制器会自动创建bootstrap-admin服务账号并把凭据打印到标准输出,之后可通过orchard get service-account查看。

2.2 生成 Bootstrap Token

随后为该服务账号生成 Bootstrap Token:

orchard get bootstrap-token worker-pool-m1

命令输出即为该服务账号的 Bootstrap Token。本文将统一用${BOOTSTRAP_TOKEN}指代其值,后续所有部署配置中都应替换为实际输出的 Token 字符串。

Bootstrap Token 的信任语义(依据 docs/orchard/architecture-and-security.md):

  • 若当前 context 对应的是自签名证书的 Controller,生成的 Token 会包含 Controller 证书,Worker 连接时只信任该证书,天然免疫中间人攻击;
  • 若当前 context 对应的是公开有效证书的 Controller,Token不包含证书,Worker 连接时走 PKI 验证。

这种设计让 Token 本身成为一个自包含的信任凭证:拿到 Token 的 Worker 既能通过认证(服务账号身份),也能完成证书信任(内嵌证书或 PKI),从而支持完全非交互式的批量部署。

2.3 假设前提

本文后续所有配置均假设:

  • Orchard Controller 已部署完成,且可从 Worker 主机访问,地址为orchard.example.com(实际请替换为你自己的 FQDN 或 IP 地址);
  • 若 Controller 使用了非默认端口,请在地址中显式携带端口(例如orchard.example.com:6120,默认端口为 6120,参考 docs/orchard/using-orchard-cli.md 与 docs/orchard/deploying-controller.md 中的--listen参数说明)。

三、部署方式总览

虽然可以直接手动运行orchard worker run并携带所需参数把 Worker 跑起来,但官方不推荐这种方式——它缺乏持久化与自愈能力:终端退出、机器重启、进程崩溃后 Worker 不会自动恢复,也无法纳入统一管理。

更可靠的方式是让系统级服务管理器或配置管理工具接管 Worker 的生命周期。官方给出了两种推荐的持久化部署方法:

方式适用场景核心机制
launchd单台 macOS 主机macOS 内置守护进程管理器,KeepAlive保证崩溃自动重启
Ansible一批 macOS 主机官方维护的 playbook,参数化批量部署

四、方式一:launchd 部署(macOS 原生守护进程)

launchd 是 macOS 的 init 系统,负责管理守护进程(daemons)、代理(agents)及其他后台进程。通过定义一个 launchd job 定义文件,可以让系统在开机时自动拉起 Worker,并在进程退出时自动重启。

4.1 安装 Orchard CLI

在 Worker 主机上先安装 Orchard:

brew install openai/tools/orchard

安装完成后,确认可执行文件位置:

which orchard

该命令应输出/opt/homebrew/bin/orchard(Apple Silicon 上的 Homebrew 默认前缀)。如果不是这个路径,需要将下面 job 定义文件中所有出现/opt/homebrew/bin/orchard的地方替换为你的实际路径。

说明:launchd 的ProgramProgramArguments需要绝对路径,且 launchd 环境与交互式 Shell 环境不同(PATH 等环境变量默认不继承),因此这里必须显式写全路径。

4.2 创建 launchd job 定义文件

创建文件/Library/LaunchDaemons/org.cirruslabs.orchard.worker.plist,内容如下:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>org.cirruslabs.orchard.worker</string> <key>Program</key> <string>/opt/homebrew/bin/orchard</string> <key>ProgramArguments</key> <array> <string>/opt/homebrew/bin/orchard</string> <string>worker</string> <string>run</string> <string>--user</string> <string>admin</string> <string>--bootstrap-token</string> <string>${BOOTSTRAP_TOKEN}</string> <string>orchard.example.com</string> </array> <key>EnvironmentVariables</key> <dict> <key>PATH</key> <string>/bin:/usr/bin:/usr/local/bin:/opt/homebrew/bin</string> </dict> <key>WorkingDirectory</key> <string>/var/empty</string> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/Users/admin/orchard-launchd.log</string> <key>StandardErrorPath</key> <string>/Users/admin/orchard-launchd.log</string> </dict> </plist>

配置项逐行解读

  • Label:job 的唯一标识,建议保持org.cirruslabs.orchard.worker不变;
  • Program:要执行的可执行文件绝对路径(对应上一步which orchard的输出);
  • ProgramArguments:传给程序的完整参数数组,等效于执行:
    /opt/homebrew/bin/orchard worker run \ --user admin \ --bootstrap-token ${BOOTSTRAP_TOKEN} \ orchard.example.com
    • worker run:启动 Worker 子命令;
    • --user admin:指定 Worker 运行所对应的 macOS 用户(即 VM 运行/管理归属的用户,见下文"admin 说明");
    • --bootstrap-token ${BOOTSTRAP_TOKEN}:传入第 2 节生成的 Token;
    • 末尾的orchard.example.com:Controller 的 FQDN 或 IP 地址(若 Controller 使用非 6120 端口,在此追加:端口);
  • EnvironmentVariables.PATH:launchd 不会继承登录 Shell 的环境变量,这里显式给出 PATH,确保orchard运行时能解析其依赖的外部命令(如 git、diskutil 等);
  • WorkingDirectory:工作目录设为/var/empty,避免在任意目录下启动产生意外副作用;
  • RunAtLoad:设为true,在 launchd 加载 job 时立即启动 Worker;
  • KeepAlive:设为true,Worker 进程若意外退出,launchd 会自动将其重新拉起——这是持久化部署的核心保障;
  • StandardOutPath/StandardErrorPath:标准输出与错误日志统一写入/Users/admin/orchard-launchd.log,便于排障。

关于admin的说明:上述配置假定你的 macOS 主机用户名为admin。如果实际用户名不是admin,请把 job 定义中所有admin出现的位置替换为$USER对应的实际用户名(包括--user参数与日志路径)。

4.3 修改 Controller 地址并启动

将 plist 中ProgramArguments末尾的orchard.example.com替换为你的 Orchard Controller 的 FQDN 或 IP 地址。

启动 job:

launchctl load -w /Library/LaunchDaemons/org.cirruslabs.orchard.worker.plist
  • load:加载并注册该 job;
  • -w:同时覆盖(overwrite)配置,确保 job 被永久启用(即使被launchctl unload标记禁用也能恢复)。

启动后可查看日志文件确认 Worker 是否成功连接 Controller:

tail -f /Users/admin/orchard-launchd.log

之后在客户端执行orchard get vm或查看 Worker 列表,即可看到该 Worker 已在线并可接受 VM 调度。

4.4 管理 launchd job 的常用操作

# 停止并卸载(从 launchd 注册中移除) sudo launchctl unload /Library/LaunchDaemons/org.cirruslabs.orchard.worker.plist # 查看 job 状态 sudo launchctl list | grep orchard # 修改配置后重新加载(先卸载再加载) sudo launchctl unload -w /Library/LaunchDaemons/org.cirruslabs.orchard.worker.plist sudo launchctl load -w /Library/LaunchDaemons/org.cirruslabs.orchard.worker.plist

注意:/Library/LaunchDaemons属于系统级守护进程目录,文件属主需为 root 且权限受限(644),修改 plist 需要sudo

五、方式二:Ansible 批量部署

如果你有一批 macOS 主机都要接入 Orchard 集群,逐台手写 launchd plist 显然不现实。官方为此维护了 cirruslabs/ansible-orchard 仓库,内含基础 Ansible playbook,用于便捷地批量配置 Worker。

5.1 克隆 playbook 并安装依赖

在任意一台可访问目标主机的控制机上操作:

git clone https://github.com/cirruslabs/ansible-orchard.git cd ansible-orchard/

安装 Ansible Galaxy 依赖(requirements.yml 中声明的 roles/collections):

ansible-galaxy install -r requirements.yml

5.2 编辑 inventory 文件production-pool

打开production-pool文件,按下表填充各字段:

字段说明示例值
hosts替换worker-1.hosts.internal为你的 Worker 的 FQDN 或 IP 地址;多台主机则逐行追加worker-1.example.com
ansible_userSSH 登录该主机所用的 macOS 用户admin
orchard_worker_userWorker 运行所归属的 macOS 用户admin
orchard_worker_controller_urlOrchard Controller 的 FQDN 或 IP 地址orchard.example.com
orchard_worker_bootstrap_token第 2 节生成的${BOOTSTRAP_TOKEN}eyJ...

字段含义对照 launchd 方式可以快速理解:orchard_worker_user对应 plist 中的--user参数,orchard_worker_controller_url对应ProgramArguments末尾的地址参数,orchard_worker_bootstrap_token对应--bootstrap-token参数值。

5.3 执行部署

ansible-playbook --inventory-file production-pool --ask-pass playbook-workers.yml
  • --inventory-file production-pool:使用编辑好的 inventory;
  • --ask-pass:SSH 以密码方式认证时提示输入密码(若已配置 SSH 密钥可去掉该参数);
  • playbook-workers.yml:官方提供的 Worker 部署 playbook,内部会自动完成 Orchard 安装、launchd/服务配置、Token 注入与启动。

部署完成后,可回到客户端执行orchard get vm或查看集群 Worker 状态,确认各主机已成功注册。

5.4 Ansible 方式的扩展场景

由于 playbook 是参数化的,你可以:

  • 在 inventory 中为不同硬件平台维护多个组(例如 M1 池、M2 池),通过不同服务账号与 Token 区分;
  • 结合 docs/orchard/using-orchard-cli.md 中的标签(--labels location=DC1-R12-S4,model=macmini)与资源(--resources bandwidth-mbps=1000)能力,让不同 Worker 声明自身的硬件属性,供 Controller 调度器按标签匹配、按资源余量分配 VM。

六、部署后的调度行为与验证

6.1 Worker 上报的自动资源

Worker 启动后会自动采集主机信息并上报为可调度资源(参考 docs/orchard/using-orchard-cli.md 的 "Automatic resources" 一节):

  • org.cirruslabs.logical-cores:主机逻辑核心数;
  • org.cirruslabs.memory-mib:主机总内存(MiB)。

注意:这两个资源值仅在 Worker 启动时采集一次,因此如果你改动了主机硬件或希望刷新数值,需要重启 Worker 进程(launchd 方式下可launchctl unload+load,Ansible 方式可重跑 playbook)。

6.2 验证 Worker 在线

部署完成后,从任意已配置 context 的客户端执行:

# 列出集群中的 VM(能看到 Worker 调度上来的 VM 即说明链路通畅) orchard get vm # 查看服务账号(确认 worker-pool-m1 存在) orchard get service-account

更直接的验证是:用orchard create vm创建一台 VM(不带--labels时由调度器在可用 Worker 间自由选择;带--labels model=xxx时精确调度到指定 Worker),随后orchard run vm/orchard ssh vm连接进入,确认 VM 确实运行在新接入的 Worker 主机上。

6.3 排障速查

现象排查方向
Worker 未出现在集群中检查 launchd 日志(/Users/admin/orchard-launchd.log)或 systemd/journal;确认orchard.example.com可达(Controller 端口默认 6120)
认证失败/证书错误确认${BOOTSTRAP_TOKEN}orchard get bootstrap-token实际输出值;确认 Token 对应的 context 与 Controller 证书类型匹配(自签名证书会内嵌证书,公开证书走 PKI)
orchard: command not found(launchd 方式)which orchard路径与 plist 中Program不一致;或 PATH 环境变量未包含该目录
VM 总是调度到特定 Worker检查 VM 是否携带--labels/--resources约束,以及目标 Worker 的标签与资源余量

七、两种部署方式的对比与选择建议

维度launchdAnsible
适用规模单机或少量手动管理的主机一批/大量主机
配置入口手写 plist,人工维护inventory 参数化,可版本化管理
自愈能力KeepAlive=true自动重启playbook 可重复执行,幂等收敛
依赖仅 macOS + HomebrewAnsible 控制机 + SSH 可达的目标主机
与官方推荐的关系官方文档首选示例官方维护的现成 playbook,批量部署推荐

选型建议:1~2 台主机、追求最小依赖时用 launchd;主机数量增长、需要统一变更管理时,尽快迁移到 Ansible playbook 方案,把 Token、Controller 地址、运行用户等全部收敛到 inventory 中管理。

八、安全最佳实践小结

结合 docs/orchard/architecture-and-security.md 的 Security 章节,部署 Worker 时请牢记:

  1. 最小权限服务账号:只授予compute:read+compute:write,不要复用bootstrap-admin或授予无关资源权限;
  2. Token 即凭据${BOOTSTRAP_TOKEN}是 Worker 的"身份证",应妥善保管(避免写入公开的 inventory/仓库),并在轮换时重新生成并更新所有 Worker;
  3. 信任模型自适应:自签名 Controller 的 Token 内嵌证书,天然防中间人;公开证书 Controller 走 PKI,必要时用--no-pki强制快速失败以暴露信任配置问题;
  4. 日志与运行环境:通过 launchd/Ansible 统一管理日志路径、运行用户与工作目录,避免以 root 或任意目录运行 Worker 带来的权限与路径污染问题。

至此,你已经掌握了从"创建服务账号 → 生成 Bootstrap Token"到"launchd / Ansible 两种持久化部署 Worker"的完整闭环,并理解了 Worker 与 Controller 之间的信任机制与调度前提,可以据此将任意数量的 macOS 主机接入 Orchard 集群,为 CI 与自动化场景提供可调度的 VM 计算资源。

【免费下载链接】tartmacOS and Linux VMs on Apple Silicon to use in CI and other automations项目地址: https://gitcode.com/GitHub_Trending/ta/tart

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

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

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

立即咨询