The panel decides which probes link to which agents (probes dial out): an auto-link setting plus per-pair manual overrides with a link matrix in the admin, and the hovered overview card is lifted above its neighbours.
24 KiB
部署
节点(Agent、Probe)是单个 NativeAOT 可执行文件,没有运行时依赖,只需要系统的 OpenSSL 3(libssl.so.3)。启动时会自检,缺少时第一步就明确报错。
1. 构建与打包
scripts/publish.sh <agent|probe|backend|fleet-enroll> <rid> → backend/artifacts/publish/<project>/<rid>/
scripts/package.sh <agent|probe> <rid> → backend/artifacts/packages/monitor-<role>-<version>-<rid>.tar.gz(附 .sha256)
构建信息(程序里显示的 tag、提交、构建时间):publish.sh 会用 git describe --tags --always --dirty、git rev-parse 和当前时间自动设置环境变量 MONITOR_TAG、MONITOR_COMMIT、MONITOR_BUILT_AT,直接用 dotnet publish 或 CI 构建时自己设置它们(容器的 Fastlane 构建用同名的 --build-arg);不设置就是空,本地构建照常可重复。版本号取自 backend/Directory.Build.props 的 Version。前端的信息由 web/build-info.mjs 在构建时写入(版本取自 web/package.json)。
| rid | 目标 | 构建方式 |
|---|---|---|
linux-x64、linux-arm64 |
Debian/Ubuntu glibc 服务器 | Windows CI 主机通过 AotAnywhere 交叉编译 |
linux-musl-x64、linux-musl-arm64 |
Alpine、amd64 OpenWrt、aarch64 OpenWrt 路由器 | Windows CI 主机通过 AotAnywhere 交叉编译 |
osx-x64、osx-arm64 |
Intel Mac、Apple Silicon | Windows CI 主机通过 AotAnywhere 交叉编译;发布包未做 Developer ID 签名或 Apple 公证 |
win-x64、win-arm64 |
Windows x64、ARM64 | Windows CI 主机上的 Visual Studio C++ 工具链 |
macOS 的 Apple Silicon 产物带临时 ad-hoc 签名,Intel 产物未签名。通过浏览器下载时,macOS Gatekeeper 可能阻止启动;面向普通用户分发前需要 Developer ID 签名和 Apple 公证。MIPS 不在当前目标列表中(见 project-layout.md)。
仓库内的 scripts/publish.sh 面向本机目标平台;Woodpecker 的 tag 流水线在 Windows runner 上构建 Agent、Probe 和 fleet-enroll 的所有发布目标,Backend OCI 镜像仍在 Linux runner 上构建。
Backend 容器
Backend 使用 OCI 标准镜像,通过 registry.oeo.one/monitor/monitor-backend:<version> 分发,支持 linux/amd64 和 linux/arm64。容器基于 .NET 10 ASP.NET noble-chiseled-extra 运行时镜像,以非 root 用户运行,在 8080/tcp 提供 HTTP 服务;数据库和原始数据统一写入 /data。extra 变体带 IANA 时区数据,供按时区查询使用。将 /data 挂载为持久卷,并在反向代理处配置 HTTPS。
在部署目录保存此仓库的 compose.yaml,先通过部署平台的环境变量或密钥管理设置 MONITOR_ADMIN_PASSWORD(可选设置 MONITOR_ADMIN_USER、MONITOR_VERSION),然后启动:
docker compose up -d
Compose 将容器端口只绑定到宿主机 127.0.0.1:8080,适合由同机 HTTPS 反向代理转发;数据保存在 Docker 命名卷 monitor-data。首次启动成功创建管理员后,改密应在管理端完成。
健康检查端点为 GET /healthz。容器定义见 ../packaging/container/Backend.Containerfile。
节点二进制发布
Woodpecker 在 vMAJOR.MINOR.PATCH tag 上,由 Windows runner 使用 AotAnywhere 并行构建 Agent/Probe 的 Linux glibc、Linux musl、macOS 和 Windows 产物。Agent 包还包含一次性注册工具 fleet-enroll。Linux 归档带有安装脚本和 systemd/OpenWrt 单元;Windows 产物为 .zip,Linux/macOS 产物为 .tar.gz。Linux glibc 的 Agent 与 Probe 二进制还会打包为 OCI 镜像,支持 linux/amd64 和 linux/arm64;musl、macOS、Windows 仍通过对应平台归档分发。所有平台产物和 OCI 镜像发布成功后,CI 会创建对应的 Gitea Release,并附上压缩包和 SHA-256 校验文件。macOS 产物目前未签名/公证。安装说明见 ../backend/agent/README.md 与 ../backend/probe/README.md。
CI 工作流
Pull request 与 dev 验证
Pull request 和 dev push 会运行 Backend tests;通过后,独立的 web-build workflow 才会构建前端并检查 CSS。提交信息后缀 [SKIP TESTS] 只跳过 Backend tests,前端构建仍会运行。Gitea PR 事件的 CI_COMMIT_MESSAGE 是 PR 标题,因此在 PR 中跳过测试时,把后缀写入 PR 标题;普通分支 push 则写在 commit message 中。
main 开发镜像
main 上只有提交信息包含 [CI] 的 push 才构建镜像。合并 PR 时,请把 [CI] 放入 PR 标题或合并提交标题。Backend、Agent、Probe 的 Linux/amd64 镜像会并行构建,并推送到同一个 Zot Registry 下独立的 monitor-dev/ 仓库:
| 镜像 | 滚动标签 | 固定提交标签 |
|---|---|---|
| Backend | registry.oeo.one/monitor-dev/monitor-backend:latest |
registry.oeo.one/monitor-dev/monitor-backend:dev-<12位SHA> |
| Agent | registry.oeo.one/monitor-dev/monitor-agent:latest |
registry.oeo.one/monitor-dev/monitor-agent:dev-<12位SHA> |
| Probe | registry.oeo.one/monitor-dev/monitor-probe:latest |
registry.oeo.one/monitor-dev/monitor-probe:dev-<12位SHA> |
Dev 镜像目前仅支持 amd64。它们不创建 Gitea Release,也不修改正式版 monitor/ 仓库中的标签。普通 main push 不会构建镜像。
正式版发布
推送匹配项目版本的 vMAJOR.MINOR.PATCH tag 会触发完整跨平台构建、正式 OCI 镜像推送和 Gitea Release。正式镜像使用 registry.oeo.one/monitor/ 路径;Agent、Probe 提供 amd64 与 arm64 多架构标签,稳定版本更新正式仓库自己的 latest。这与 monitor-dev/ 的 dev latest 相互独立。
Agent 和 Probe 镜像分别发布为 registry.oeo.one/monitor/monitor-agent:<version> 与 registry.oeo.one/monitor/monitor-probe:<version>,包含 amd64、arm64 多架构索引;也可指定 :<version>-amd64 或 :<version>-arm64。稳定版本同时更新 latest。镜像以非 root 用户(UID/GID 1654)运行,默认读取 /etc/monitor/agent.json 或 /etc/monitor/probe.json。运行容器时挂载对应配置目录;Probe 还会在该目录写入 agents.json,因此目录需可由 1654 用户写入。Agent、Probe 需使用宿主网络以保持节点端口和测量流量行为,并按需添加 NET_RAW 能力以执行 ICMP 测量:
docker run -d --name monitor-agent --restart unless-stopped --network host \
--cap-add NET_RAW -v "$PWD/agent-config:/etc/monitor" \
registry.oeo.one/monitor/monitor-agent:<version>
docker run -d --name monitor-probe --restart unless-stopped --network host \
--cap-add NET_RAW -v "$PWD/probe-config:/etc/monitor" \
registry.oeo.one/monitor/monitor-probe:<version>
宿主机配置目录应允许 UID/GID 1654 读写;Probe 需要写权限来更新 agents.json。也可通过 Docker Compose 配置相同的网络、卷和能力。
实测体积(StackTraceSupport=false、IlcFoldIdenticalMethodBodies=true、OptimizationPreference=Size):
| 程序 | linux-musl-x64 | linux-x64 | win-x64 |
|---|---|---|---|
| monitor-probe | 7.7 MB | 7.7 MB | 5.6 MB |
| monitor-agent | 8.4 MB | 8.4 MB | 7.3 MB |
| fleet-enroll | 6.4 MB | 6.4 MB | — |
Linux 上比 Windows 大,是因为 .NET 的加密、压缩、网络本机库被静态链接进来。tar.gz 压缩后 Probe 约 3.6 MB。
2. 安装
解压 tar.gz,在解压目录里运行 install.sh(POSIX sh,root 运行;Debian、Ubuntu、Alpine、OpenWrt 都测试过):
# Agent(服务器):注册并启动
./install.sh agent --server https://panel.example.com --join <加入令牌> --name hk-1
# Probe(家宽网络里的机器或 OpenWrt 路由器):先在面板生成身份(POST /api/admin/probes,只能下载一次)
./install.sh probe --probe-json ./probe.json
./install.sh uninstall agent|probe [--purge] # --purge 同时删除身份(节点需要重新注册)
| 位置 | 内容 | 所有者 |
|---|---|---|
/usr/lib/monitor/ |
二进制 | root,0755:采集进程不能改写自己的可执行文件 |
/etc/monitor/ |
agent.json 或 probe.json、身份(node.json、node.key、tls.pfx)、agents.json |
monitor 用户,0750 |
安装脚本会:检查 OpenSSL、创建 monitor 用户(useradd、busybox adduser,OpenWrt 没有这些时直接写 /etc/passwd)、安装二进制和服务文件;缺少配置时只安装、不启动,并打印下一步。
systemd(packaging/systemd/*.service)
以 monitor 用户运行,沙箱:NoNewPrivileges、ProtectSystem=strict、ProtectHome、PrivateTmp/Devices、ProtectKernel*、RestrictAddressFamilies=AF_INET AF_INET6、RestrictNamespaces、MemoryDenyWriteExecute(NativeAOT 不 JIT)、SystemCallArchitectures=native,MemoryMax(Agent 128 MB、Probe 64 MB)。
- Agent 只保留
CAP_NET_RAW(ICMP 目标任务用),/etc/monitor只读;Probe 没有任何 capability,只对agents.json所在的目录可写。 - 监听 1024 以下的端口(例如把数据面放到 443)需要在 drop-in 里加
AmbientCapabilities=CAP_NET_BIND_SERVICE和对应的CapabilityBoundingSet。默认端口是 7443/tcp+udp(Probe 控制通道和 UDP 数据面)、7444/tcp。
OpenWrt(packaging/openwrt/)
只支持 Probe(Agent 面向服务器)。install.sh probe 安装 /etc/init.d/monitor-probe(procd,崩溃自动重启,日志进 logd)并写入 /lib/upgrade/keep.d/monitor,sysupgrade 时保留 /etc/monitor/。
OpenWrt 默认不带 OpenSSL:opkg install libopenssl3(较新的快照和 24.10 之后用 apk add libopenssl3)。闪存很小时注意:二进制 7.7 MB,配置只在 Agent 列表变化时才写。路由器上建议把 probe.json 的 limits.max_test_mbps 调低。
3. 验证
scripts/smoke-linux.sh 在 Linux 容器里用发布的二进制跑完整链路(后端 → 注册 → Agent → Probe → 数据落库),MODE=install 用打包产物和 install.sh 安装、以 monitor 用户运行。scripts/smoke-systemd.sh 在 systemd 容器里验证服务单元。已经验证过:
- Alpine 3.22(musl)、Debian 12(glibc):直接运行和
install.sh安装都通; - OpenWrt(官方 rootfs,busybox,无
install/useradd/su):安装、建用户、卸载、二进制启动和 OpenSSL 自检; - systemd(Debian 12):两个服务 active,Agent 只有
CAP_NET_RAW、Probe 没有 capability,NoNewPrivs、seccomp 生效,Agent 无法写/etc/monitor,没有重启和错误日志。
没有验证的:arm64 构建、真正的 OpenWrt 设备(有 procd 和真实的内存/闪存限制)、跨公网的真实线路。
实测常驻内存(RSS,回环,默认模板,稳定后):Linux 上 Probe 约 21 MB、Agent 约 23 MB;Windows 上约 22 MB、25 MB。
跨机器的真实链路(Windows Probe → WSL2 里的 Agent 和 Backend)
scripts/smoke-wsl.py 用 Windows 上的 NativeAOT Probe 连 WSL2 里的 Agent(真实的虚拟网络,两端的单调时钟原点相差约 38 小时),并用 tc netem 在 WSL 里注入故障。结果(Probe 的 RTT 基线约 0.4 ms):
| 注入 | 期望 | 实测 |
|---|---|---|
| Agent→Probe 方向 10% 丢包、30 ms ± 5 ms 延迟(egress netem,只匹配 7443/7444) | 丢包在下行,下行抖动变大 | loss.down 8.2%、loss.up 0;jitter.down.p95 8.7 ms、jitter.up.p95 0.18 ms;RTT +31 ms;TCP:tcp.rtt.p99 1.2 s、tcp.slow 28.8%、tcp.retrans 5.9%(Agent 一侧内核计数) |
| Probe→Agent 方向 10% 丢包、20 ms ± 3 ms 延迟(ingress + ifb) | 丢包在上行 | loss.up 9.4%、loss.down 0;jitter.up.p95 5.2 ms、jitter.down.p95 0 |
| 8 秒黑洞(tc ingress drop 7443/7444) | UDP 连续丢包 ~80 个;TCP 不丢包,只有几秒的长尾 | UDP 最长连续丢包 80(10 Hz × 8 s);tcp.rtt.max 9.5 s、tcp.stall_max 9.6 s |
hy2_ladder(10/25/50/100 Mbit/s) |
无丢包 | train.loss 0.006%、train.jitter.p95 0.64 ms、可持续 100 Mbit/s |
| 杀掉 Agent / 杀掉 Probe 再启动 | 自动恢复 | Agent 重启后 2.1 s 恢复在线并重新连上 Probe;Probe 重启后 0.5 s 重新连上 |
验证中发现并修掉的两个问题:
- Probe 重启后,Agent 沿用了上一个会话的记录:Probe 重启之后序号从 0 开始,Agent 里同一个序号的旧 t2/t3 还在,于是真正的上行丢失被算成了下行丢失(黑洞测试里
loss.up0、loss.down7.4%)。现在新的 Probe 会话开始时 Agent 清空所有流的记录。 - TCP 回显的几秒中断被记成丢包:Probe 像 UDP 那样等 2 秒就把没有回复的行交出去,TCP 随后才到的回复没有行可以回填,最严重的长尾反而在 RTT 里看不到(黑洞期间
tcp.rtt.max只有 4 ms)。现在 TCP 的行等回复,30 秒仍然没有才当作连接已断(t4 缺失)。
没有覆盖的:Windows 上的 Agent(需要给 Windows 防火墙加入站规则)、NAT 重绑定。跨公网的线路见下一节。
跨公网的真实线路(广东移动家宽 → 日本 IIJ 的 VPS)
2026-10-03 在一条真实线路上试跑过:家宽机器(Debian 13,用户态运行,没有公网 IPv4 入站)跑 Probe 和 Backend,VPS(Debian 12,1 核 470 MB,上面本来就跑着 xray、hysteria2、caddy 等服务)跑 Agent。
浏览器 / 本机前端 ──► https://<公网域名> ──隧道(Cloudflare Tunnel 之类)──► 家宽机器: Backend (:29181)
家宽机器: Probe ──WSS 到 https://<公网域名>──► Backend(身份、Agent 列表)
家宽机器: Probe ──TCP/UDP 7443、TCP 7444──► VPS: Agent
VPS: Agent ──WSS 到 https://<公网域名>──► Backend
做法和要点:
- Backend 通过隧道暴露:隧道把一个公网域名转到家宽机器的
29181;Backend 监听http://0.0.0.0:29181(只写一个监听地址,同时写0.0.0.0和[::]会报地址已被占用),家宽路由器的防火墙不放行这个端口,公网只能经隧道进来。Agent 用fleet-enroll --server https://<公网域名>注册,之后用 WSS 连回 Backend。 - 经隧道注册之后,检查 Agent 的
public_host:Backend 看到的来源地址是隧道的出口,不是 VPS 的地址,要改成 VPS 的真实地址,Probe 才连得上。 - Probe 直连面板:
probe.json里的server就是面板地址(取自Monitor__PublicUrl,没配就用创建它时的请求地址),Probe 用它连面板,Agent 列表由面板下发;先注册还是先创建 Probe 都可以。 - 小 VPS 把
limits.max_total_mbps调低(试跑时用 100);Agent 常驻约 23 MB,VPS 上原有的服务不受影响,结束后删除/opt/…、停掉进程即可,没有留下任何东西。 - 家宽的 IPv6 前缀会在路由器重新拨号(比如停电)后变化,SSH 地址要跟着换;面板走隧道的域名,不受影响。
- 本地电脑没有直连 VPS 的路径时,用家宽机器当跳板(
SSH_ASKPASS+SSH_ASKPASS_REQUIRE=force,密码放环境变量,不写进文件)。
常驻(开机自启):
- 家宽机器(没有 root 时):
~/.config/systemd/user/monitor-backend.service和monitor-probe.service,EnvironmentFile指向放配置的backend.env,Restart=always,systemctl --user enable --now …,再用sudo loginctl enable-linger <用户>让它们不登录也能起来。Probe 的命令行是monitor-probe --config <probe.json 路径>(默认路径是/etc/monitor/probe.json)。 - VPS:
/etc/systemd/system/monitor-agent.service,Restart=always,加NoNewPrivileges、ProtectSystem=strict、ReadWritePaths=/opt/monitor、ProtectHome、PrivateTmp。这是不走安装脚本的手动方式;正式安装用上面的packaging/systemd。 - 日志进 journal:
journalctl -u monitor-agent、journalctl --user -u monitor-probe。重启 Backend 用systemctl而不是手动再起一个进程,否则会端口冲突。
国家和运营商:Backend 用 Probe、Agent 的来源地址向 IP 归属服务查一次,展示在国旗和运营商图标上(Monitor__GeoLookupUrl,缺省 https://ip.007995.xyz;留空就不查;这个服务只供公益使用,署名和使用条款由部署的人自己遵守)。Probe、Agent 自己不访问外部服务,所以客户的防火墙审计里不会多出出站连接;Backend 发出去的只有公网 IP(内网地址不发)。
从别处看这个面板:本机跑前端,在页面里把数据源指向这个域名,用 API 令牌访问,Backend 设 Monitor__CorsOrigins 放行前端的来源(见 web/README.md)。
实测(Probe 在广东移动家宽,Agent 在日本 IIJ):
| 项目 | 结果 |
|---|---|
| 延迟 p50 / p95 / p99 | 107 / 107 / 114 ms |
| 丢包 | 上行 0%,下行 8.1%(hy2_ladder 在 10、25、50、100 Mbit/s 四档下的丢包都是 8~10%,与速率无关:随机丢包,不是限速) |
| 抖动 p95(上 / 下) | 0.9 / 5.2 ms |
| TCP | 重传 1.9%(批量传输时 5.8%),RTT 最大 412 ms |
reality_session |
建连成功率 100%,TCP 建连 p95 115 ms,TLS 握手 p95 117 ms,30 秒长连接无重置;4 秒批量传输峰值 133 Mbit/s、中位数 90 Mbit/s(Agent 上限 100) |
| 评分 | REALITY 82(含按需测试)、Hy2 42 |
| Agent 主机状态 | CPU 1.5%,内存 274 / 493 MB,已运行约 20.5 天 |
这次试跑发现并修掉的问题:hy2_ladder 的阶梯按「块」而不是按「阶段」计算,真实的 Probe 把一个阶段切成几块,4 个阶段出了 7 步(模拟数据不切块,所以之前的测试没有发现);现在同一阶段的块先合并。
容器节点的运行(podman + systemd)
Agent 和 Probe 推荐在宿主机上用 root 的 podman 加 systemd 运行,这样宿主机更新器(下一节)才能重启它们。以 Agent 为例(Probe 把名字和目录换成 monitor-probe,配置文件换成 probe.json):
# /etc/systemd/system/monitor-agent-container.service
[Unit]
Description=Monitor Agent (podman)
After=network-online.target
Wants=network-online.target
[Service]
EnvironmentFile=/etc/monitor-update/agent.image # IMAGE=<仓库>@sha256:<digest>,更新器更新时改写它
Restart=always
RestartSec=5
TimeoutStopSec=30
ExecStartPre=-/usr/bin/podman rm -f monitor-agent
ExecStart=/usr/bin/podman run --rm --name monitor-agent --network host --read-only --security-opt no-new-privileges --cap-drop all -v /etc/os-release:/etc/os-release:ro -v /opt/monitor/etc:/etc/monitor:Z ${IMAGE}
ExecStop=/usr/bin/podman stop -t 20 monitor-agent
[Install]
WantedBy=multi-user.target
- 数据目录(上面挂到容器
/etc/monitor的/opt/monitor/etc)归容器用户(UID/GID 1654),里面放agent.json、身份目录(fleet-enroll注册之后的agent-id/),Probe 放probe.json和agents.json。agent.json里的fleet.identity_dir写容器里的路径(例如/etc/monitor/agent-id)。 - 首次注册 Agent:
podman run --rm --network host -v <数据目录>:/etc/monitor --entrypoint /usr/local/bin/fleet-enroll <镜像> --server https://<面板> --join <加入令牌> --name <名字> --identity-dir /etc/monitor/agent-id,再写agent.json。Probe:在管理端创建(或轮换密钥)之后下载probe.json,放进数据目录。 - 拉取私有镜像需要 Registry 的登录信息:用
podman login --authfile /etc/monitor-update/registry-auth.json …生成一份只有 root 能读(600)的认证文件,更新器用它拉取,容器本身用不到。 - 挂载宿主机的
/etc/os-release(只读):节点读系统名展示在面板上,不挂的话读到的是镜像里的 Ubuntu。 - ICMP 目标任务要在
podman run里加--cap-add NET_RAW。 - 经隧道注册之后检查 Agent 的
public_host:面板看到的来源地址是隧道的出口(通常是内网地址),要在管理端改成这台机器自己的公网地址(PATCH /api/admin/agents/{id}),Probe 才连得上。 packaging/compose/里的 compose 文件是不带宿主机更新器的简单方式:更新靠手动改版本再docker compose pull && up -d,面板的更新按钮对它不起作用。
容器节点的更新(Agent、Probe)
面板通知、节点验签、宿主机更新,面板即使被攻破也装不上假镜像:
CI 构建并推镜像(Zot)──► ci/release-manifest.sh:对镜像 digest 的清单签名(ECDSA P-256,私钥只在 Woodpecker 密钥 release_signing_key 里)
└─ POST /api/admin/releases ──► 面板:只存下并原样转发(不验签)──► 在线的 Agent、Probe(连上时补发)
节点进程:只把清单和签名写进数据目录的 update/,不执行任何命令
│ systemd.path 监视到 offer.sig
▼
宿主机 monitor-update(root):复制到临时目录 → 用本机的发布公钥验签 → 核对组件和镜像仓库 → seq 必须比已安装的大
→ status:available / invalid(写进 update-status/,节点随心跳报给面板,管理端「版本」页显示)
→ 管理员点「更新」(或本机配置 POLICY=auto)→ podman pull <仓库>@sha256:<digest>(内容寻址,Registry 或链路上换不了)
→ 写 IMAGE=… 到 /etc/monitor-update/<组件>.image,重启容器单元;20 秒内没有健康就换回旧镜像(rolled_back)
- 安装更新器(每个容器节点一次,root):
packaging/update/install-updater.sh agent --data-dir /opt/monitor/etc --image-repo registry.oeo.one/monitor/monitor-agent --unit monitor-agent-container.service [--policy auto] [--authfile <Registry 认证文件>]。它装好monitor-update脚本和发布公钥,写/etc/monitor-update/<组件>.conf,启用两个 systemd 路径单元。容器单元要用EnvironmentFile=/etc/monitor-update/<组件>.image和${IMAGE}启动容器。 - 镜像仓库、服务名、公钥都在本机配置里,清单里写什么都不会改变拉取哪个仓库;清单被篡改、签名对不上、组件或仓库不符、
seq不比已安装的大(重放旧清单),都会被拒绝,状态是invalid。 - 业务进程不能改二进制,也不执行命令:它只能往
update/里放清单和请求;状态在 root 拥有的update-status/里(只读)。 - CI 的配置:Woodpecker 密钥
release_signing_key(发布私钥,PEM)、release_api_token(面板的 API 令牌,作用域release,只能登记清单);环境变量RELEASE_API_URL(面板地址)。没有release_signing_key就只构建镜像、不发清单。 - 管理端:「系统 → 版本」页显示最新发布的 tag、每个节点的更新状态(已是最新、有新版本、更新中、已回滚、清单无效),有新版本的节点有「更新」按钮,也可以「全部更新」。更新策略在节点本机配置:
/etc/monitor-update/<组件>.conf里POLICY=manual(默认,等管理员请求)或auto(验签通过就更新)。 - 发布公钥在
packaging/update/release-key.pub.pem;私钥不入库,请离线备份。更换密钥:节点上换新公钥之后再用新私钥发布。 - 纯二进制的安装方式(
fleet-updater、fleet-release,见 fleet/update.md)还没有实现;容器方式优先。