Skip to content

CLI 与脚本参考

Node Agent 命令行,以及仓库里全部运维与开发脚本的参考清单。配置项见 配置参考;具体操作流程见 操作手册


Node Agent CLI

入口 python -m agent.main(安装后亦可用 dn42-node-agent)。参数解析见 apps/node-agent/agent/main.py

默认行为是后台常驻守护进程:启动即 reconcile 一次,然后连接控制面 WebSocket,收到事件再 reconcile。--once / --plan-only / --doctor 是诊断用的单次模式。

参数含义默认
--config PATHagent.toml 配置文件路径约定 /etc/dn42-control/agent.toml
--controller-url URLControl Server 基础 URL(常驻模式必需)
--enrollment-token TOKEN一次性 enrollment token
--requested-node-id ID希望绑定的 node_id无(从状态目录推断)
--hostname FQDN覆盖 inventory 中的 hostname自动探测
--state-dir PATH本地状态目录/var/lib/dn42-control
--rendered-dir PATH渲染输出目录(覆盖默认)<state-dir>/nodes/<node_id>/rendered
--desired-state PATH离线运行使用的 DesiredState JSON
--mode {apply,write-rendered,plan-only}reconcile 深度apply
--once诊断:只跑一次 reconcile 后退出
--plan-only诊断:等价于 --once --mode plan-only
--doctor诊断:跑一次自检后退出
--log-level LEVEL日志级别INFO

模式与约束

模式行为
apply(默认)写盘 + 部署容器 + 本机收敛(WireGuard 同步、BIRD 热重载)
write-rendered只写渲染文件,不碰容器。适合无 Docker 的演示或调试环境
plan-only只渲染与规划,不写不部署
  • --once / --plan-only / --doctor 互斥(同一个互斥组)。
  • --plan-only 与非 plan-only--mode 同给即 SystemExit
  • --controller-url--desired-state 互斥:在线(连控制面)与离线(吃本地 JSON)二选一。
  • 常驻模式前置:必须有 --controller-url,且 mode 不能是 plan-only;不满足即退出并提示。
  • 收到 SIGTERM / SIGINT 优雅退出。

退出码

模式退出码
--doctor自检全过 0,否则 1
--once / --plan-onlydeploy 失败 1,否则 0(输出 JSON 摘要到 stdout)
常驻收到信号优雅退出 0

运行模式与守护循环的原理见 Node Agent 内部


运维工具(deploy/tools/

面向生产 fleet 的工具。多数通过管理 API 操作(环境变量 DN42_CP 为控制面 URL、DN42_ADMIN_TOKEN 为管理 token),默认 dry-run,需显式 apply / deploy 才落地,并写 .json 备份供回滚。

Agent 自更新子系统(deploy/tools/agent-self-update/

fleet 升级的默认路径:wheel 只上传到控制面一处,各节点 agent 自行拉取安装。

文件作用
install-updater.sh每节点一次性安装更新器:把 agent-update.sh 放到 /opt/dn42-agent/、unit 放到 /etc/systemd/system/,建 /opt/dn42-wheels/run/dn42-control
agent-update.sh更新器本体:读 agent 写的更新标记 → flock 串行化 → 快照当前版本 wheel 到回滚目录 → 离线 pip install -U 整组安装 → 重启 agent → 健康门轮询 → 失败回滚旧版并记 CRITICAL
dn42-node-agent-update.servicesystemd oneshot 更新器 unit,由 agent systemctl start --no-block 触发。进程隔离,不随被升级的 agent 一起被杀
README.md架构说明、首次引导步骤与发版操作序列

wheel 构建与引导

脚本作用
build_wheels.sh构建 5 个一方 wheel(dn42-{common,schemas,runtime,templates} 加 node-agent),版本号 = 1.0.<git-rev-count>,产物落 deploy/dist/
agent_pip_rollout.shSSH 到节点,传 deploy/dist/*.whl/opt/dn42-wheels,离线 pip install -U --no-index --find-links,重启 dn42-node-agent.service
wheel-release.md发版操作清单

agent_pip_rollout.sh 用于两种场景:首次引导(含自更新代码的那一版本身还得手动滚一次),以及自更新链路不可用时的兜底重滚——比如跨 API 前缀切换期间,健康门只在 WS 心跳成功时才写,新 agent 配旧控制面会超时自动回滚。

systemd 单元(deploy/tools/systemd/

文件作用
dn42-control-server.service控制面的 systemd 单元:uvicorn 起 app.main:app:8000),Restart=on-failureProtectSystem=strict 加固;DSN 与 token 经 Environment= 注入
dn42-node-agent@.servicenode-agent 的模板常驻单元(%inode_id,可同机多实例);节点专属变量放 /etc/dn42-control/<node_id>.env

迁移与编排脚本

脚本作用
renumber_loopbacks.py把节点 loopback 对齐到单播段;同步所有节点的 internal_topology.hosts 与 DNS 记录。默认 dry-run,apply 落地,--verify 校验
unify_internal_topology.py把各节点 internal_topology 统一为全节点 full-mesh。deploy / --verify / --rollback。⚠️ 脚本内有地址常量,renumber 后须先更新再跑
dns_anycast_lo_cleanup.py把任播 DNS 地址从每节点的 dn42-lo 迁到共享的 dns-anycast dummy 接口,剥除重复。--dry-run / apply / --rollback
bird_socket_mount_rollout.py预注入 /run/bird 可写挂载(路由采集从 docker exec birdc 切到直连 socket)。deploy / --verify / --rollback
state_snapshot.sh抓取一份控制面状态快照,供变更前后对账

离线恢复工具(deploy/tools/dn42-recover/

dn42_recover.py——离线 WireGuard 私钥托管恢复 CLI,只依赖 dn42_common.crypto永不在控制面运行。托管是可选能力,生产当前未配置恢复公钥,故库中无密文可解。

子命令作用
keygen生成 RSA 恢复密钥对:私钥用口令加密写 recovery-private.pem,公钥写 recovery-public.pem
recover用恢复私钥解封上报里的托管密文,还原节点 WG 私钥;可 --expect-public 校验

完整托管模型与恢复演练见 密钥托管与恢复

其它

deploy/tools/postman/ 存 auth-server 的 Postman collection,供手工联调 OAuth 与验证流。


开发脚本(scripts/

scripts/dev/ —— 本地演示与渲染

脚本作用
provision-three-node.py等控制面 /healthz 就绪后,向 POST /control/v1/admin/provision 灌入 3 个节点的本地 lab。独立脚本,对任意运行中的控制面可用
render-local-three-node.py把三节点 lab 渲染到磁盘(独立渲染,不依赖控制面)
render-local-two-node.py两节点 iBGP 拓扑的本地渲染
render-two-internal-one-ebgp-demo.py2 内部加 1 外部 eBGP 对端的多场景渲染
sanitize_examples.py清洗示例渲染产物(脱敏)

scripts/tools/ —— 数据导入与 backfill

脚本作用
import_node_config.py解析既有节点配置(bird.confwireguard/*.confscripts/wg/apply-*.sh)为 DesiredState,导入 DB 或 --dry-run 输出 JSON
backfill_node_lla.py从 WG 接口 addresses 里剥掉本端 fe80::X/64 副本(link-local 集中到 NodeSpec.link_local 之后)。dry-run / apply / 幂等
create_rdns_26.py/26 寻址创建反向 DNS zone 与记录

Alembic 迁移的操作见 数据库迁移