你部署了一个名为 vpn-gateway 的 Pod,把测试客户端指向它的地址,却看到数据包消失。清单里没有任何错误,kubelet 也无从抱怨。原因在于结构而非配置:Kubernetes 为每个 Pod 提供自己的网络命名空间,因此名称、标签或共享的 API 命名空间都不会改变数据包的去向。所以,决定 VPN 流量如何离开集群,要从所有权问题开始,而不是从容器镜像开始。

两种机制覆盖了大多数真实部署,它们不能互换。一种把隧道放进工作负载自己的网络命名空间。另一种请 CNI 把选定的流量引导经过指定的网关节点。它们的失败方式不同、扩缩方式不同、归属的团队也不同,因此这个容器问题往往引出永远无法收场的争论。

Pod 的边界是命名空间,不是跳板机

Linux 网络命名空间拥有自己的接口、地址、路由和防火墙规则,每个 Pod 都会得到一个。该 Pod 内的容器加入其中,正因如此,辅助容器才能改写应用随后遵循的路由。相邻的 Pod 有着看起来相同却完全独立的协议栈。不存在可供网关 Pod 继承的共享路由表,也不存在从一个命名空间到另一个命名空间的隐式流量交接。

这也是为什么网关 Pod 模式只有在有上游真的把数据包送给它时才成立:一个 Service、节点上的静态路由,或 CNI 中的引导策略。仅有地址本身吸引不了任何流量。

按 Pod 建隧道能买到什么,又要付出什么

在工作负载命名空间中运行的隧道,让该工作负载拥有自己的客户端身份,许多远程访问服务在授权或计费会话前都要求这一点。影响半径也保持局部:隧道损坏只让一个 Deployment 下线,而不是所有东西共用的路径。它如何运行取决于实现,而这正是人们容易猜错的地方。

只需要内核状态的配置可以在 init 容器中完成并退出。必须随 Pod 整个生命周期存活的用户态守护进程,则需要 Kubernetes 1.29 中作为原生 sidecar 引入的可重启 init 容器形式,这个区别来自隧道的实现方式,而不是个人偏好。这种模型的代价是重复:每个副本都要认证、获得自己的隧道地址并占用一个远端会话名额,于是扩缩容事件变成链路另一端的容量事件。把同一份凭据复制到所有副本并不能消除这项代价,只会消除审计线索。权限同样值得审视,因为一个想在自己命名空间里获得 NET_ADMIN 的隧道,没有理由继承 privileged: true 示例中横跨整个主机的权限。

当 CNI 拥有外发流量时

如果 CNI 支持,外发网关会按工作负载和目标网段选择流量,然后通过选定节点在单一可预测的源地址下发送。Cilium 的实现是常见参照,其文档明确指出该功能需要特定的 Cilium 配置,以及配备正确接口和地址的网关节点。它还提到 Pod 创建后有一段初始时期引导尚未生效,这是设计输入而不是脚注。

把这个延迟放到你自己的承诺面前看。如果规则是不允许任何流量走别的路径,那么在这段空窗期内发送流量的新 Pod 已经违反了它,因此启动流程需要自己的答案:在策略生效前挂起应用,或者接受这个窗口并记录下来。

把主张收紧。外发网关只选择和转换路径。它不终结 VPN,也不会在没有受支持连接的情况下把集群变成你远程网络的客户端。

QuestionPer-Pod tunnelCNI egress gateway
Who holds the client identityEach workloadThe gateway, shared
What scaling changesEnrollment and sessions per replicaThroughput and capacity per node
What the remote side seesDistinct addressesOne translated source
Failure scopeOne DeploymentEvery workload behind the gateway

地址转换悄悄改变了远端看到的东西

一旦网关重写源地址,按 Pod 划分的地址就不复存在,于是以身份为键的允许列表变成以一个共享地址为键的列表。这是交换而非缺陷:要维护的规则更少,出问题时归因更粗。

应用层认证和请求日志必须承担网络不再报告的东西。把网关容量和更换当作共享基础设施,因为单节点重启现在会中断其背后的每个工作负载;同时尽早检查回程路径:远端必须知道如何到达转换后的地址,通常要经由一条人或流程、而不是清单所拥有的路由或 NAT。地址规划也属于这里,因为重叠的集群与远端网段会破坏任一模型,采用 IPv6 并不能为冲突的方案开脱。

按所有权做决定,然后测试你承诺过的故障

当远程服务对单个工作负载做认证、只有少数 Deployment 需要这条链路、以及故障应当留在局部时,选择按 Pod 建隧道。当网络团队已经拥有路径、许多工作负载共用一个目的地、以及稳定源地址正是这次练习的全部目的时,选择网关。

无论哪种,都要验证你卖出的属性,而不是稳态。创建一个 Pod,让它立即发送,如果承诺是没有任何东西逃出隧道,就观察最初几秒。扩到五个副本,如果承诺是按工作负载的身份,就数一数远端报告的会话数。这两项检查比审阅清单更快地暴露机制的局限,也会告诉你下一个事故归哪个团队。

相关文章