Nebula 的 advertise_addrs 与 static_host_map:按所有者选择
静态映射由每个拨号它的 peer 维护;通告地址由主机发布。根据谁知道端点来选择。
static_host_map 和 advertise_addrs 都会把一个地址放在 peer 前面,但它们回答的是不同的问题。一个是本地文件,列出 overlay 地址和要拨号的 underlay 端点。另一个是主机告诉自己的灯塔,还有哪些端点可以访问它。真正的区别在于归属:映射由所有需要它的人维护,而通告由主机自己维护。
按谁掌握信息来决定
| Setting | Where it lives | Best for |
|---|---|---|
static_host_map | Every peer that needs the entry | Bootstrap endpoints, deliberately fixed paths |
advertise_addrs | The host's own config | Endpoints the host cannot otherwise discover |
每个 peer 的静态文件里每一个会变化的 peer,都是一项随集群规模平方增长的工作。当主机自己就知道答案时,改用另一个设置的实际理由就在这里。
归属问题还能预测地址变化时会发生什么。用静态映射时,总得有人记住所有仍持有旧条目的 peer。用通告时,主机发布新端点,灯塔再把它传下去,于是变化只留在搬走的那台机器上。
Bootstrap 仍然需要静态条目
客户端必须先到达至少一个灯塔,才能向任何人询问其他 peer。这一跳无法来自发现,所以它依赖 客户端配置中的一条静态条目。把这一条写对,剩下的 overlay 就能学出来。
映射条目把 Nebula 地址与一个或多个可达的 IP 或 DNS 端点及端口配对。把灯塔留在那里是正常的;把每个 peer 都留在那里则会迅速过时,因为每加一个 peer 就要在你可能并不控制的机器上改文件。把列表保持得足够短,让人还能靠阅读来核对。
主机知道端点时就通告
位于端口转发之后的主机,可以通过一个并未分配给它任何接口的公网地址被访问。它自己看自己是发现不了这个地址的。advertise_addrs 让它通过灯塔发布这个端点,让其他 peer 学到一条真正可用的路径。这个设置之所以存在,正是因为主机是唯一知道做过映射的一方。
要用其他 peer 真正能访问的地址和端口。同样的道理适用于有多条网络路径的主机,其中某条路径对特定网络上的 peer 更合适。通告是对 underlay 的陈述,而不是对任何东西的请求。映射变化时,在主机上更新通告,让发现去传播它,而不是在整个集群里改静态文件。
通告不等于可达
发布端点并不会创建路由器的转发规则、打开上游防火墙,也不会让 DNS 名称解析成功。这些是彼此独立的工作,而一条正确却缺少端口转发的通告,产生的正是你想修的那个故障。通告是对可达性的声明,不是建立可达性的机制。
先检查外部路径,再怪发现机制。学到端点却完不成握手的 peer,在 underlay 上存在路由或过滤问题,在两个设置里重复同一个地址也不会改变它。
把 overlay 地址和端点分开
节点的证书标识它的 Nebula 地址。通告的地址属于底层网络,可以在不动证书的情况下变化。为不同的 overlay IP 重新签发证书 是另一种操作,它对每一个固定了旧地址的信任关系都有各自的影响。在运行手册里把这两类变更分开,否则一次端点迁移会被记成一次重新签发。
排查卡住时,明确分开两层:发现是否返回了预期的端点,握手是否能到达它?如果发现是对的而数据包失败,问题在 overlay 之下。如果发现是错的,问题在映射或通告里,修复也应落在那里。