计算机网络 34:Service 的虚拟入口怎样转发,服务发现、规则、后端集合与策略
客户端访问 Kubernetes Service 的 ClusterIP:port 时,目标地址通常没有对应的普通监听 socket。请求仍能到达 Pod,是因为控制面发布 Service 与 EndpointSlice,对应的数据面实现再把虚拟入口转换为一个可达后端。
第 21 篇讨论名字解析,第 32 篇讨论负载均衡和健康检查,第 33 篇讨论容器路径。本篇只解释固定 Service 的入口、后端集合和一次更新,不把 kube-proxy 的某种模式写成 Service 的固有协议。
Service 与 EndpointSlice 描述期望状态
Service 用稳定名字和虚拟 IP 表示一组后端。本文样例把 10.96.0.10:80/TCP 映射到后端端口 8080。Service 的 selector 可以驱动控制器生成 EndpointSlice,但数据面转发并不读取“Pod”这个抽象对象;它需要可以选择的地址、端口和就绪条件。
EndpointSlice 把后端分片保存,并为端点记录 ready、serving、terminating 等条件。ready: true 表示端点已准备接收流量。处于终止过程的端点不能仅凭地址仍存在就当作普通新请求目标;具体排空行为还受实现、策略和已有连接状态约束。
控制面对象只是声明。节点上的 kube-proxy 或其他兼容实现观察这些对象,再建立实际数据面。iptables、IPVS、nftables 或 eBPF 都可能承担这一步,但它们的规则形态、选择算法和连接状态不同。
模式提炼:把声明与执行证据分开
期望后端 = Service + EndpointSlice;实际路径 = 节点数据面 + 当前连接状态
排查时需要同时保存对象快照和节点证据。只看到 EndpointSlice 更新,最多证明控制面已发布新状态;只看到一条转发表规则,也无法解释规则为何存在及何时应变化。
一次新连接怎样选择后端
固定快照中有两个 ready 端点:10.244.1.21:8080 和 10.244.2.34:8080。教学模型对规范化后的四元组做 SHA-256,并用摘要整数对后端数量取模。它只用于给定输入得到可复算结果,不声称 kube-proxy 使用这种算法。
客户端先按路由把目标为 ClusterIP 的包交给本机协议栈。数据面在适当挂点匹配 VIP、端口和协议,选择后端,然后改写目标或按实现定义的方式重定向。后续包是否沿用同一后端,取决于 conntrack、socket 负载均衡或实现自己的连接状态;不能把“每个包轮询”当作普遍行为。
若流量由集群外进入,externalTrafficPolicy 等策略还可能改变可选后端和源地址保留方式。本篇样例只处理集群内 ClusterIP,不据此推导 NodePort、LoadBalancer 或拓扑感知路由。
后端变化不是已有连接迁移
第二份 EndpointSlice 快照把端点 A 标记为 ready: false、serving: false、terminating: true,端点 B 保持 ready。模型重建后端集合后,新选择只会落到 B。
这不能证明已经建立到 A 的 TCP 连接被迁移到 B。TCP 连接由两端状态和四元组标识;从新连接候选集合删除 A,不会把原连接的字节流无损搬到另一个 Pod。已有连接可能继续、复位或超时,结果要由连接状态、终止宽限期和数据面实现共同解释。
EndpointSlice 更新到节点规则也有传播时间。控制器已写入对象而节点尚未收敛时,两个观察点可以短暂不一致。因此,故障时间线至少要记录对象版本、节点规则快照和请求发生时刻。
静态模型验证
service_model.py 读取一份 Service 和更新前后的 EndpointSlice,检查端口映射、端点条件及选择结果,并输出两个数据面快照。
1 | |
素材包括Service 快照、更新前 EndpointSlice、更新后 EndpointSlice、静态模型脚本、模型输出、资料与运行记录和审阅记录。
条件、限制和反例
Service 存在不等于后端可用。selector 写错、EndpointSlice 没有 ready 端点、节点规则未收敛、Pod 路由不通或后端未监听,都能产生不同断点。
EndpointSlice 有 ready 端点也不等于任意客户端可达。NetworkPolicy、主机防火墙、跨节点隧道、MTU 和返回路由仍在请求路径上。
模型中的确定性选择不是 Kubernetes API 保证。真实实现可能随机选择、按连接哈希、按拓扑过滤或委托云负载均衡器;升级实现也可能改变细节。本文模型只验证“候选集合变化会改变新连接选择域”这一机制。
练习
练习一:更新前端点 A、B 都 ready,更新后 A terminating 且不 ready。分别列出控制面、节点数据面和已有 TCP 连接需要保存的证据,并说明哪一项不能由另外两项替代。
练习二:Service 名字能解析到 ClusterIP,但连接超时。按 DNS、Service 对象、EndpointSlice、节点规则、Pod 路由和后端监听顺序列出检查点,为每一步写一个可排除的解释。
模式速查表
| 观察 | 能证明 | 不能证明 |
|---|---|---|
| Service 快照 | 虚拟入口和端口声明 | 节点已安装规则 |
| EndpointSlice 快照 | 控制面发布的后端与条件 | 后端进程已正确响应 |
| 节点规则或 eBPF map | 某节点的数据面状态 | 所有节点均已收敛 |
| 新连接到达后端 B | 当前请求选中了 B | 已有连接从 A 迁移到 B |
| Hexo 构建成功 | 页面可生成 | Kubernetes 转发成立 |
官方参考资料
- Kubernetes Documentation:Service,Kubernetes,访问于 2026-09-24。
- Kubernetes Documentation:Virtual IPs and Service Proxies,Kubernetes,访问于 2026-09-24。
- Kubernetes Documentation:EndpointSlices,Kubernetes,访问于 2026-09-24。
- Kubernetes Reference:kube-proxy,Kubernetes,访问于 2026-09-24。
验证边界
已验证:Python 3 标准库读取固定对象快照,重建 ready 后端集合并复算更新前后的确定性选择,验证类型为 HAND_CALC。
NOT_RUN:当前环境没有 Kubernetes 集群、kube-proxy/CNI、ip、nft 与 tcpdump,未取得真实节点规则、eBPF map、conntrack、双端抓包或后端变更时序。未来补证应在自建集群或专用虚拟机中保存 kubectl get service,endpointslice -o yaml、节点数据面快照和受控请求记录,不访问生产系统。




