Fleetd 开发与发布策略:Fleet 开源项目如何通过 TUF 自动更新保障前后兼容
2026/9/20 14:07:16 网站建设 项目流程
  • 后端
  • 前端
  • 企业应用
  • 运维
  • 网络安全

【免费下载链接】fleet

Open device management

项目地址:https://gitcode.com/GitHub_Trending/fl/fleet
点击查看免费下载

本文基于 Fleet 仓库中的 fleetd 开发与发布策略 展开,阐述 fleetd(Orbit、Fleet Desktop 与 osqueryd 等设备端组件)与 Fleet 服务器之间截然不同的更新机制,以及由此衍生出的强制兼容性规则与发布流程。读完本文,你将理解为何“新 fleetd 版本必须始终兼容旧 Fleet 服务器”是硬性要求,掌握 fleetd 发布到 TUF 仓库、从 edge 提升到 stable、以及处理不支持旧 fleetd 场景时发布说明的写法。

fleetd 与 Fleet 服务器:两种截然不同的更新模型

在 Fleet 生态中,“fleetd”指部署在终端设备上的全部组件集合,主要包括:

  • Orbit:轻量级 osquery 安装器与自动更新器,负责管理 osquery 的启动、配置与版本更新,是 Fleet 推荐的设备端 agent(见 orbit/README.md);
  • Fleet Desktop:设备托盘菜单应用,向终端用户展示设备合规状态等信息;
  • osqueryd:由 Orbit 拉起并持续运行的 osquery 守护进程。

Fleet 服务器是负责集中管理、策略下发、查询汇总的服务端程序。

这两种软件的更新模型根本不同(见 策略文档):

维度fleetd 组件Fleet 服务器
更新方式自动更新(auto-update),持续轮询 TUF 仓库获取新版本由管理员手动升级(on-premises 部署场景)
更新触发者Orbit 在启动时及周期性检查 TUF 元数据管理员根据发布说明手动执行升级
更新频率设备端自动收敛到最新版本由各企业自行安排维护窗口
兼容性压力新组件必须兼容旧的服务器服务器应尽量兼容旧组件

正是这种“组件自动更新、服务器手动升级”的异步节奏,构成了制定发布策略的根本原因:如果 fleetd 新版本依赖了服务器端尚不存在的能力,那些还未升级服务器的自托管(on-premises)Fleet 部署就会被悄然破坏。

TUF 更新机制:fleetd 如何自动获取新版本

fleetd 的自动更新并非简单地“下载最新二进制”,而是基于TUF(The Update Framework,更新框架)的签名元数据机制。Fleet 托管了一个公开的 TUF 仓库,Orbit 通过持续轮询该仓库来判断并拉取新版本。

更新服务器地址

在 orbit/pkg/update/update.go 中可以看到完整的地址定义:

  • 当前生产仓库地址:https://updates.fleetdm.comDefaultURL);
  • 历史旧地址:https://tuf.fleetctl.comOldFleetTUFURL),自 orbit 1.38.0 起完成迁移;
  • 元数据文件名由tuf-metadata.json迁移为updates-metadata.jsonMetadataFileName),迁移期间为兼容旧版本下载,包内会同时携带两个文件。

该文件还内嵌了 TUF 的root元数据(defaultRootMetadata),包含 14 个 ed25519 公钥以及 root/snapshot/targets/timestamp 各角色的密钥与阈值配置,用于引导首次信任。RootKeys作为 Options 的字段注入更新客户端,确保客户端只信任由这些密钥签名的元数据。

Orbit 的轮询行为

Orbit 通过orbit/cmd/orbit的 CLI 参数控制更新行为(见 orbit/cmd/orbit/orbit.go):

参数默认值说明
--update-urlORBIT_UPDATE_URLhttps://updates.fleetdm.com更新服务器地址
--orbit-channelORBIT_ORBIT_CHANNELstableOrbit 使用的更新通道
--osqueryd-channelORBIT_OSQUERYD_CHANNELstableosqueryd 使用的更新通道
--desktop-channelORBIT_DESKTOP_CHANNELstableFleet Desktop 使用的更新通道
--update-intervalORBIT_UPDATE_INTERVAL15m检查更新的周期;注意启动时会先检查一次,之后每次检查带有随机化,最多可能延长 10 分钟
--disable-updatesORBIT_DISABLE_UPDATESfalse关闭自动更新

更新检查的调度逻辑位于 orbit/pkg/update/runner.go,其中刻意引入了随机化,避免所有设备在同一时刻向 TUF 仓库发起同步请求形成“惊群效应”:

// Randomize the initial interval so that all agents don't synchronize their updates initialInterval := r.opt.CheckInterval

每次检查时,Orbit 会拉取 TUF 的 timestamp/snapshot/targets 元数据,验证签名后与本地已安装版本比对,并下载更新后的目标(target)。默认的目标配置见 orbit/pkg/update/options.go,其中为每个平台定义了 Orbit、osqueryd、Fleet Desktop 等组件在 TUF 中的PlatformChannelTargetFile,例如:

  • macOS 上 osqueryd 的目标为osqueryd.app.tar.gz,解压后从osquery.app/Contents/MacOS/osqueryd提取可执行文件;
  • Windows 上 Orbit 与 osqueryd 分别对应orbit.exeosqueryd.exe
  • Linux 上 Fleet Desktop 使用desktop.tar.gz,并在启动新版本前通过--help做冒烟校验(CustomCheckExec)。

这些目标在 TUF 中的命名常量定义于 orbit/pkg/constant/constant.go:orbitosqueryddesktop

当前 TUF 仓库中的版本矩阵

orbit/TUF.md(由make fleetd-tuf自动生成,请勿手工编辑)列出了部署在stableedge两个通道上的组件版本。以stable通道为例:

组件macOSLinuxWindowsLinux (arm64)Windows (arm64)
orbit1.60.01.60.01.60.01.60.01.60.0
desktop1.60.01.60.01.60.01.60.01.60.0
osqueryd5.23.15.23.15.23.15.23.15.23.1
nudge1.1.10.81462----
swiftDialog2.5.6----
escrowBuddy1.0.0----

其中nudgeswiftDialogescrowBuddy是仅面向 macOS 的组件。edge通道则承载尚未进入稳定版的新构建(例如 orbit 1.61.0),供早期验证使用。

硬性规则(Must rule):新 fleetd 永远兼容旧 Fleet 服务器

策略文档定义了一条不可妥协的规则:

“新 Fleetd 版本始终支持与旧 Fleet 服务器之间的通信与操作。”

这条规则之所以是“必须”,根源仍然在于更新模型的不对称:

  • fleetd 组件通过 TUF 自动更新,Fleet 推送到 TUF 仓库的新版本会自动且不可控地扩散到所有已接入设备;
  • 而 on-premises 的 Fleet 服务器由管理员手动升级,升级节奏完全由企业 IT 决定;
  • 一旦新 fleetd 依赖了旧服务器不支持的 API、接口或行为,所有尚未升级服务器的企业部署都会立刻出现 agent 异常,Fleet 无法在下发前甄别每个设备的服务器版本。

因此,每当为 fleetd 引入新特性时,开发者都必须确保:在旧版本 Fleet 服务器上,新 fleetd 至少能保持“通信 + 基本操作”不出错。这条规则在 fleetd 开发与发布策略文档 中被明确为 Fleetd 开发者引入新特性时必须遵循的策略纲领。

期望项(Nice to have):新 Fleet 服务器兼容旧 fleetd

与上面的硬性规则相对,文档将另一条规则列为“期望但非必须”:

“新 Fleet 服务器版本支持旧版本 fleetd。”

它之所以不是必须,是因为服务器升级由管理员控制、节奏可预期,开发者可以在服务端与设备端特性的配合上保留一定灵活性——例如先让服务器具备新能力,再在下一次 fleetd 发布中让设备端使用该能力。这也与发布流程中“fleetd 先发布、服务器后发布”的顺序约束相互呼应。

发布流程:先发 TUF,再发服务器

策略文档给出了两条发布顺序约束:

1. fleetd 组件必须先于服务器发布

Fleetd 组件(Orbit、Fleet Desktop、osqueryd)必须先发布到 FleetDM 的 TUF 仓库,之后新 Fleet 服务器版本才允许出现在 GitHub Releases 中。

原因在于自动更新的时序:设备端会自动拾取 TUF 上的新 fleetd;若服务器版本先行发布,而与其配套的 fleetd 尚未进入 TUF 自动更新通道,则会形成“新服务器 + 旧 fleetd”的中间态;反之,先发布 fleetd 则能保证任何时刻设备的自动更新都指向“被服务器支持的组件版本”。

2. 不兼容时必须在发布说明中标注最低 fleetd 版本

当新 Fleet 服务器版本不再支持旧版 fleetd(即无法满足“Nice to have”期望项)时,发布说明(release notes)必须明确记录该版本支持的最低 fleetd 版本

这条标注面向两类特殊用户:

  • 关闭自动更新的用户(通过--disable-updates或打包时禁用更新);
  • 将组件固定到特定通道/版本的用户(例如固定使用stable之外的自定义通道,或人为锁定版本)。

这些用户的设备不会自动升级 fleetd,因此在升级 Fleet 服务器之前,必须先手动将设备上的 fleetd 升级到发布说明要求的最低版本,再执行服务器升级,否则设备端与服务器之间会因版本不匹配而失效。发布说明中的示例措辞可见 releasing-fleet.md:

While newer versions of fleetd and fleetctl still function with older versions of the Fleet server (and vice versa), Fleet does not actively test these scenarios and some newer features won't be available.

从源码看发布顺序的落地:tools/tuf 发布脚本

Fleet 仓库中与发布顺序直接对应的实现是 tools/tuf/README.md 描述的releaser.sh发布脚本。该脚本自动化完成“构建组件 → 签名 → 推送 TUF 仓库”的全过程,是“fleetd 先发 TUF”这一规则的工程落地。

发布环境与密钥管理

发布脚本对签名密钥采用严格的 2FA 管理:

  • TUF 的targetssnapshottimestamp三个角色的加密签名密钥存放在专用 USB 闪存盘(如/Volumes/FLEET-UPD/keys);
  • 解密口令与 GitHub API Token 存放在 1Password 私有保管库中,路径形式如Private/UPDATES TARGETS/password
  • 首次加入时需由持有 TUFroot角色的成员对新增签名密钥完成tuf sign/tuf snapshot/tuf timestamp/tuf commit授权。

依赖工具包括makegit、1Password CLI(op)、rclonefleetctl、go-tuf 的tuf可执行文件以及ghCLI。

先上 staging,再同步生产

所有发布先推送到 staging 仓库https://updates-staging.fleetdm.com),完成冒烟测试(smoke test)验证后,再通过服务端同步将 staging 与生产仓库https://updates.fleetdm.com对齐。这为 fleetd 发布增加了一道独立于 GitHub CI 的验证闸门。

常用发布动作示例

以发布 fleetd 1.23.0 到edge通道为例:

TUF_DIRECTORY=/Users/foobar/updates-staging.fleetdm.com \ COMPONENT=fleetd \ ACTION=release-to-edge \ VERSION=1.23.0 \ KEYS_SOURCE_DIRECTORY=/Volumes/FLEET-UPD/keys \ TARGETS_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES TARGETS/password" \ SNAPSHOT_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES SNAPSHOT/password" \ TIMESTAMP_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES TIMESTAMP/password" \ GITHUB_USERNAME=foobar \ GITHUB_TOKEN_1PASSWORD_PATH="Private/Github Token/password" \ ./tools/tuf/releaser.sh

冒烟测试通过后推送到生产:

ACTION=release-to-production \ COMPONENT=fleetd \ VERSION=1.23.0 \ ./tools/tuf/releaser.sh

随后创建发布 PR 并更新 CHANGELOG:

ACTION=create-fleetd-release-pr \ VERSION=1.23.0 \ ./tools/tuf/releaser.sh

从 edge 提升到 stable

当 fleetd 1.23.0 在edge通道验证充分后,可通过promote-edge-to-stable动作将其提升到stable通道,使所有使用默认stable通道的设备自动升级:

TUF_DIRECTORY=/Users/foobar/updates-staging.fleetdm.com \ COMPONENT=fleetd \ ACTION=promote-edge-to-stable \ VERSION=1.23.0 \ KEYS_SOURCE_DIRECTORY=/Volumes/FLEET-UPD/keys \ TARGETS_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES TARGETS/password" \ SNAPSHOT_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES SNAPSHOT/password" \ TIMESTAMP_PASSPHRASE_1PASSWORD_PATH="Private/UPDATES TIMESTAMP/password" \ ./tools/tuf/releaser.sh

提升同样遵循“staging 验证 → 同步生产”的两段式流程。osqueryd 的发布与提升过程与 fleetd 一致,区别仅在于COMPONENT=osqueryd;此外 osqueryd 提升到 stable 后,还需通过ACTION=update-osquery-schema同步 osquery 的 schema 与 flags。

值得注意的是,当某次发布只包含 Orbit 变更时,脚本仍要求 Fleet Desktop 组件同步 bump 版本号,以便用户在托盘图标中看到新的版本字符串(如 “Fleet Desktop v1.21.0”)。

patch 版本发布

fleetd 的 patch 发布流程与 minor 发布一致,区别在于需从 patch 分支(如rc-minor-fleetd-v1.41.1)发起,且VERSION需与 patch 版本号一致。若脚本重复运行且 PR 与 tag 已生成,可设置SKIP_PR_AND_TAG_PUSH=1跳过重复推送。

macOS 专属组件的发布

releaser.sh尚未支持全部组件:nudgeescrowBuddy需要手工通过make nudge-app-tar-gz/make escrow-buddy-pkg构建,再用fleetctl updates add添加到指定通道:

fleetctl updates add --target /path/to/escrowBuddy.pkg --platform macos --name escrowBuddy --version 1.0.0 -t stable

swiftDialog则由专用的 GitHub Actions workflow 生成swiftDialog.app.tar.gz后,通过ACTION=release-swiftDialog-to-stable发布。

实战要点:何时需要手动升级 fleetd

结合策略与源码,以下是设备端管理员最需要关注的三种场景:

  1. 默认场景(自动更新开启):设备上的 Orbit 会周期性轮询https://updates.fleetdm.comstable通道并自动升级,无需人工干预;
  2. 固定通道或关闭自动更新:如果通过--orbit-channel/--osqueryd-channel/--desktop-channel固定了通道,或使用--disable-updates关闭更新,那么在升级 Fleet 服务器前,必须核对新服务器版本的发布说明中标注的最低支持的 fleetd 版本,并先在设备端完成 fleetd 升级;
  3. 自建 TUF 仓库:大型企业可使用fleetctl updates系列命令自建/自管更新仓库(对应文档中的“custom TUF”场景,元数据文件同样采用updates-metadata.json),此时发布节奏与兼容性约束由企业自行控制,但硬性规则“新 fleetd 兼容旧服务器”仍然适用。

小结

Fleet 的 fleetd 发布策略本质上是对“自动更新”与“手动升级”两种节奏之间差异的系统性补偿:

  • 硬性规则:新 fleetd 必须兼容旧 Fleet 服务器,防止 TUF 自动更新意外破坏 on-premises 部署;
  • 期望项:新服务器尽量兼容旧 fleetd,为两端开发保留灵活性;
  • 发布顺序:fleetd 组件必须先进入 TUF 仓库,服务器版本才可发布;若服务器不兼容旧 fleetd,发布说明必须写明最低支持的 fleetd 版本;
  • 工程落地tools/tuf/releaser.sh以“USB 密钥 + 1Password 口令”的双因子签名、staging→production 两段式发布、edge→stable 通道提升,保障了上述策略可被可靠执行。

对于任何向 fleetd 贡献新特性的开发者,这份策略就是引入变更前必须对照的检查清单:先确认旧服务器下的通信与基本操作不受影响,再按“先 TUF、后 GitHub”的顺序完成发布。

  • 后端
  • 前端
  • 企业应用
  • 运维
  • 网络安全

【免费下载链接】fleet

Open device management

项目地址:https://gitcode.com/GitHub_Trending/fl/fleet
点击查看免费下载

相关推荐

上一篇:CDCS项目平台对比分析:天池、biendata、DataFountain优劣解析
下一篇:HandyControl高级技巧:数据绑定与事件处理的最佳实践

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

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

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

立即咨询