小型网络系列:脚本、Scheduler 和可恢复性
系列导航
- 小型网络系列:开篇 - 300-500 Devices 的网络为什么也会复杂
- 小型网络系列:RouterOS 和 Switch 的职责边界
- 小型网络系列:LAG、VLAN 和 Macvlan 为什么会一起出现
- 小型网络系列:PCC 分流逻辑和故障行为
- 小型网络系列:WireGuard 为什么是日常路径
- 小型网络系列:脚本、Scheduler 和可恢复性
背景
前面几篇讲的是网络形状:RouterOS 和 Switch 怎么分工,LAG / VLAN / Macvlan 怎么承载 Multi-WAN,PCC 怎么分流,WireGuard 怎么承载日常站点路径。
最后一篇讲一个更运维的问题:这些状态不能只靠手工记忆。
小型网络最容易出现的不是“大型系统崩溃”,而是一些小操作慢慢失控:
- PCC 模式切错几条规则
- WireGuard Peer 偶发 Down 了没人注意
- PPPoE 线路长期运行后状态不稳定
- 黑名单更新靠手工跑
- RouterOS 上有哪些脚本、哪些 Scheduler,过几个月没人说得清
DC-101RouterOS 版本更老,部署能力和新版本不完全一样
所以我现在更倾向于把 RouterOS 的脚本和 Scheduler 做成 repo-backed state。
Manifest 是 Desired State
RouterOS 这边的核心不是“把脚本复制过去”,而是 Manifest。
每个 host 有自己的 rsc/<host>/manifest.yml,里面描述:
- 应该存在的 System Scripts
- 这些脚本对应哪些文件
- Scheduler 应该怎样运行
- 哪些旧文件或旧脚本应该删除
- host 的特殊部署差异
Office-JT、Office-SQ、DC-101 的状态不是一样的。
| Site | Manifest 重点 |
|---|---|
Office-JT |
PCC 模式脚本、WireGuard Watchdog、WireGuard Trigger、print-per-ip-counts、update-blackip |
Office-SQ |
WireGuard Watchdog、update-blackip、PPPoE Redial、Watchdog Scheduler |
DC-101 |
老 RouterOS 限制更多,保留更简单的 update-blackip 部署方式 |
这让“当前应该有哪些脚本”变成 repo 里的可审计事实,而不是 RouterOS 终端历史。
部署路径
RouterOS 维护现在走 routerosctl.py,不是旧的“复制到某台 PVE 再手工导入”。
常用操作大概是:
|
|
这里文章里继续用内部 host label 表达,不展开真实连接方式、密码环境变量或公网 Endpoint。
audit 用来检查 Live State 和 Manifest 是否一致。sync 上传非 secret runtime files。install 会做更完整的安装流程,并留下 pre/post audit evidence。
这个设计的价值在于:我可以知道一次变更之前和之后 RouterOS 长什么样,而不是只知道“我刚刚好像导入了一个脚本”。
PCC 脚本的可恢复边界
PCC 脚本是 Office-JT 里最容易出错的一类脚本。
它们的可恢复边界来自前一篇讲的命名:
pcc-mark-*是 Bucket Layerpcc-routing-*是 Routing Layer- 模式切换脚本只禁用
^pcc-mark- - 模式切换脚本只启用自己的
^pcc-mark-N/ - 不动
pcc-routing-*
这意味着 PCC 模式切换可以反复执行。
如果当前想从 1:1:1 切到 0:1:1,脚本不会假设现在的状态干净,而是先把所有 Bucket Rules 收敛,再启用目标组。出问题时,也可以换回另一组模式,而不是手工逐条找哪几条 Mangle Rule 开着。
这不等于完全自动化,但它比手工点规则可靠得多。
WireGuard Watchdog 的边界
WireGuard 是日常路径,但 Watchdog 不应该做太多事。
Office-JT 和 Office-SQ 的 Watchdog 思路都很克制:
sequenceDiagram
participant Netwatch as RouterOS Netwatch
participant Scheduler as Scheduler
participant Script as wireguard-watchdog
participant Peer as WireGuard Peer
Scheduler->>Script: Run Every 1m
Script->>Netwatch: Read Peer Status
alt Peer Down
Script->>Peer: Disable Peer
Script->>Peer: Wait 5s
Script->>Peer: Enable Peer
else Peer Up
Script-->>Scheduler: No Change
end
sequenceDiagram
participant Netwatch as RouterOS Netwatch
participant Scheduler as Scheduler
participant Script as wireguard-watchdog
participant Peer as WireGuard Peer
Scheduler->>Script: Run Every 1m
Script->>Netwatch: Read Peer Status
alt Peer Down
Script->>Peer: Disable Peer
Script->>Peer: Wait 5s
Script->>Peer: Enable Peer
else Peer Up
Script-->>Scheduler: No Change
end
sequenceDiagram
participant Netwatch as RouterOS Netwatch
participant Scheduler as Scheduler
participant Script as wireguard-watchdog
participant Peer as WireGuard Peer
Scheduler->>Script: Run Every 1m
Script->>Netwatch: Read Peer Status
alt Peer Down
Script->>Peer: Disable Peer
Script->>Peer: Wait 5s
Script->>Peer: Enable Peer
else Peer Up
Script-->>Scheduler: No Change
endsequenceDiagram
participant Netwatch as RouterOS Netwatch
participant Scheduler as Scheduler
participant Script as wireguard-watchdog
participant Peer as WireGuard Peer
Scheduler->>Script: Run Every 1m
Script->>Netwatch: Read Peer Status
alt Peer Down
Script->>Peer: Disable Peer
Script->>Peer: Wait 5s
Script->>Peer: Enable Peer
else Peer Up
Script-->>Scheduler: No Change
end
它只做一件事:Peer Down 时重启 Peer。
它不会重写密钥,不会改 Endpoint,不会改 Route,也不会把办公室日常路径切到 NetBird 或 ZeroTier。
这个边界很重要。自动化越小,误伤范围越小。
Scheduler 是运行约束
Manifest 里除了脚本,还有 Scheduler。
Office-JT 里有几个典型 Scheduler:
pppoe1-redial:周期性重启 PPPoE 接口watchdog-wg-peer-office-sq:定时执行 WireGuard Watchdogupdate-blackip:定时更新黑名单
Office-SQ 也有类似的 Watchdog 和 PPPoE Redial。
这些 Scheduler 不是什么高大上的编排系统,它们只是把“我平时会手工做的维护动作”变成固定节奏。
这样做的好处是:
- 频率明确
- 目标脚本明确
- 是否启用可以在 Manifest 里看到
- 下次换人或过几个月回来排障,不用猜这件事是不是靠某个终端历史在跑
print-per-ip-counts 这种小脚本也有价值
Office-JT 里还有一个很朴素的脚本:统计绑定 DHCP Lease 的客户端,在连接表里找连接数超过阈值的地址。
它不是监控系统,也不负责自动限速。
但它在排障时有用:
- 某台机器连接数异常高,会影响 PCC 体感
- 下载器、同步工具、浏览器异常 Tab 都可能把连接表撑大
- 先看到高连接客户端,再决定要不要调 PCC 或做策略
这也符合这套网络的风格:不追求一次性上完整企业监控和准入治理,但把常见排障动作固化成可以重复执行的小工具。
DC-101 为什么特殊
DC-101 是 RouterOS-based L3 Switching,但它的 RouterOS 版本和能力边界更老。
在部署流程里,它和 Office-JT / Office-SQ 不完全一样:
- 不支持同样的
import dry-run流程 - 不接受较新的 repo-style remote
scripts/directory 方式 - Manifest 里需要用更简单的 remote file 形态表达
这类差异要写在稳定文档里,而不是靠人记。
否则自动化最容易在“看起来都是 RouterOS”的地方踩坑。版本不同、设备类型不同,部署能力就可能不同。
最后的结论
这个小型网络不是靠一个巨大的自动化系统维护的。
它更像几层简单机制叠起来:
- Manifest 描述 RouterOS Desired State
routerosctl.py负责 Audit / Sync / Install- PCC 脚本只切 Bucket Layer
- WireGuard Watchdog 只重启 Peer
- Scheduler 固化周期性维护动作
- 小脚本辅助排障,不假装自己是完整监控平台
这套做法很朴素,但适合当前规模。
它的目标不是把网络变成无人值守系统,而是让每次变更和每个自动动作都有边界、有证据、有回退方向。对 300-500 Devices 的小型网络来说,这比堆一套复杂控制平台更现实。