使用 VPC CNI 时,Pod 可以从 VPC 取得地址,拥有正确路由的 VPN 用户可以直接访问它。这让直接访问 Pod 看起来是最简单的选择,事实也确实如此,直到 Pod 被替换。用户记住的地址应当属于应用,而不是某个副本。比较这三种入口,最终归结为地址归哪个对象所有,以及工作负载迁移时什么必须继续工作。

先按生命周期选择,再按网络为了让入口可达需要做到什么来选择。

三种入口,三种生命周期

Pod IP 归 Pod 所有:随 Pod 一起分配,并在结束时释放。ClusterIP 归 Service 所有,是虚拟地址,只有在集群的服务路由存在的地方才有意义。内部负载均衡器归云资源所有,由集群控制器用后端来配置。这些归属模型预示了你会遇到的故障:地址过期、名字无法解析,或者后端集合未更新。

在做出选择之前,先把比较写下来。一旦说出所有者和故障,选择通常就自己浮现了。

EntryOwnerFailure when the workload moves
Pod IPThe PodAddress changes and saved links break
ClusterIPThe ServiceVirtual address with no meaning outside cluster routing
Internal balancerCloud resource plus controllerBackends update, but the DNS view is yours to maintain

直接访问 Pod:有用,但只是临时的

对于受控检查,直接访问确实有用:一个管理员、一次短会话、一个特定端口。但对用户它是糟糕的契约,因为地址是实现细节,每次发布都会改变。把它记进 wiki,正是一项正常服务变成传闻的方式。

它还会招来过宽的规则。允许一个管理员访问一个 Pod,并不等于允许访问节点子网中的每个地址,而通常写下的正是后者。

ClusterIP:设计上局限于集群

ClusterIP 之所以有效,是因为集群的数据平面在集群内部为它编程路由。从 VPN 上的笔记本看,除非有东西刻意暴露它,这个地址毫无意义。以 svc.cluster.local 结尾的名字属于集群 DNS,因此把它复制到使用其他解析器的客户端上,得到的是不存在的名字,而不是路由错误。

对于集群内部的调用方,包括其他工作负载,ClusterIP 仍然是正确的入口。它只是不是面向集群路由域之外用户的发布机制。

内部负载均衡器:被发布的路径

内部负载均衡器为你提供稳定的私有地址,以及你自己的区域可以指向的名字,同时控制器让后端集合保持最新,正如 EKS 负载均衡指南 所述。它才是能在普通 Pod 替换后依然存在、无需任何人改文档的入口。它的代价是一个云资源、一份控制器配置和一条来自 VPN 的路由,而这些正是人们低估的部分。

使用集群实际运行的控制器模型。为一种集成编写的注解不适用于另一种。

源地址是谁

安全组看到的是到达其边界的源,具体取决于 VPN 与负载均衡路径,它可能是已连接的客户端,也可能是转换后的地址。在基于 EC2 的节点上,普通 VPC CNI Pod 默认继承节点的 ENI 安全组,而受支持的配置可以挂载 Pod 专属的安全组。请按文档化的路径写规则,而不是按猜想的笔记本地址。

把应用自身的监听器和身份验证作为独立的控制手段。允许流量的网络规则不是授权决定,也不应被当作授权决定。

该交给用户什么

交给用户的是服务名,而不是地址。把名字发布到私有区域,让它指向内部入口,然后在客户端保持同一名字打开的情况下替换一个后端 Pod 来验证。这个练习检验的正是真正重要的性质:例行部署之后仍能到达同一个应用。

把直接访问 Pod 保留为有明确范围的、有文档记载的运维例外,远离面向用户的说明。

相关文章