跳转到正文

DNS 灰度与回滚操作手册 ​

按本手册部署 DNS 设计所述的子系统。

本清单只用于部署,未在本地开发环境执行。真实 eBPF 加载与挂接、网络命名空间 变更、透明套接字和路由 map 发布需要隔离、明确授权且具备 root 权限的 Linux 主机。

前置条件 ​

  • 一台可丢弃或隔离的授权主机、带外恢复通道和维护窗口。不要把共享生产网关 作为首次灰度主机。
  • 仅特权灰度需要 root 或免密 sudo、带 cgroup v2 与原始 BTF 的受支持 Linux 内核(内核自带、OpenWrt 的 /usr/lib/debug/boot/vmlinux,或通过 HONK_VMLINUX_BTF 指定外部文件),以及真实 冒烟检查所需的目标接口、路由与 DNS 客户端。
  • Rust stable、项目 nightly 工具链、rust-src、bpf-linker、CMake、C/C++ 编译器、libclang/bindgen 依赖与 readelf。
  • 当前二进制、配置、BPF 目标文件与持久化状态(<data_dir>/state/,状态数据库之前为 cache.db)的准确路径;足够保存只读回滚 副本的空间;上一已知可用二进制与配置的校验和。
  • 观察服务日志与主机健康的渠道。DNS 计数器和结构化日志用于内部诊断;没有新增 公开 DNS 指标端点。

部署前与备份 ​

  1. 记录主机、内核、接口、当前二进制与配置的校验和、日志中的当前路由 代次、服务命令与 UTC 时间。

  2. 使用候选版本的准确源码执行无特权独立 DNS 冒烟检查:

    bash
    just dns-smoke

    此命令构建 debug honk-core,通过 --mock-ebpf 启动实际进程。它在配置不变的 SIGHUP 前后,经 UDP 与一条持久 TCP 连接验证配置的回环监听器。命令返回前 会停止进程并移除所有临时资源。

  3. 使用正常服务管理器暂停已安装服务。把当前二进制与配置复制到带 时间戳、只读的回滚路径。

  4. 服务暂停期间备份持久化状态(<data_dir>/state/ 或 cache.db),保留所有者与权限模式。启用 global.store_subscribe 时,还要备份旧订阅存储,即在 <data_dir>/.sub、 /var/share/honk/.sub、./.sub 中找到的第一个私有 .sub 目录:带状态数据库的候选版本 首次启动会导入并删除其中的 *.sub 正文。记录二进制、配置、状态与 .sub 备份的 校验和。不要删除、改写、压缩整理或迁移数据库。

  5. 重启旧版本并完成 UDP/TCP DNS 冒烟检查,确认回滚文件可用后再继续。

特权灰度 ​

状态:本地开发环境中 NOT EXECUTED。只有在满足以上全部前置条件、隔离且明确授权的 主机上才能执行以下步骤。

  1. 在授权主机上构建并检查候选版本:

    bash
    just build-ebpf
    cargo build --release -p honk-core --features ebpf

    确认 eBPF 目标文件含 .BTF 并保留构建日志。

  2. 正常停止旧服务。安装候选二进制,但不得覆盖回滚副本;随后通过主机的服务 管理器,使用保留的生产配置和显式 BPF 目标文件启动。

  3. 确认加载与挂接成功、接口与策略路由正常,并已发布新的路由代次。 不要运行 just clean-all,也不要删除已固定的 map、命名空间、路由或缓存行。

  4. 从授权客户端经拦截路径各发一个 UDP 与 TCP DNS 查询。若原本已启用 Clash, 还要执行 /dns/query 和 /cache/dns/flush;不要只为灰度临时启用 Clash。

  5. 通过正常 SIGHUP/服务管理器路径重载未变配置并重复查询;再做一次预先 批准且可逆的策略变更,重载后验证新的完整路由代次。

  6. 观察内部低基数诊断:缓存命中/未命中/过期、flight 饱和/取消/重试、持久化 drop/flush 失败、运行时退役、传输初始化/重置、投影的旧代次/ 写入失败/重试与 DNS 结果分类。任何持续增长的失败/重试计数、退役超时、 map 满、DNS 应答回归或路由不一致都判定灰度失败。

回滚 ​

  1. 正常停止候选版本并保留日志。不要清理 BPF 状态或修改持久化状态。
  2. 从已验证的回滚副本恢复旧二进制与配置。仅当灰度损坏或替换了数据库时才 恢复数据库备份;通常保留当前数据库。带状态数据库的候选版本首次启动时会导入 并删除 cache.db,启用 global.store_subscribe 时还会删除旧 .sub 订阅正文,因此回滚到没有状态数据库的版本时,需要恢复 cache.db 与 .sub 备份。
  3. 使用旧配置与 BPF 目标文件启动旧二进制。再触发一次常规配置重载, 使其重新推送旧路由代次;重新开放流量前从日志确认代次已提交。
  4. 重复 UDP/TCP DNS、路由,以及原本已配置时的 Clash 冒烟检查。确认主机健康,并把 计数器/日志与部署前记录比较。
  5. 为事件复盘保存候选日志、校验和、构建输出和查询结果。绝不能把破坏性清理 当作回滚方式。

证据记录 ​

在部署工单中记录每条命令、退出状态、时间戳、校验和、路由代次、 查询结果与相关计数器/日志快照。除非在隔离授权主机上满足全部前置条件,否则 必须把特权清单标记为 NOT EXECUTED。

相关文档 ​


来源:honk 上游文档,采用 GPL-3.0-only 许可证。