一个稳定的名字,站在一组会变动的 Pod 前面。

Kubernetes Service 为 Pod 提供稳定入口

既然 Pod 会重建,就很难记住它的地址。Service 在这组 Pod 前面固定一个名字,让调用方不因 Pod 更换而受影响。 一个地址,一组 Pod 多副本带来了多个 Pod,而每个 Pod 都有自己的 IP,还会随时被重建。Service 正是它们前面那个稳定的家:你声明一个选择器,平台就分给它一个固定的集群 IP 和一段可被 DNS 解析的名字。集群 DNS 把名字解析到 Service 上,因此组件(Ingress、负载均衡、别的 Pod)只依赖这个名字,而从不关心具体某个 Pod 的地址。抽象的全部意义就在于:名字是持久的,背后站着的每一样东西都可以即丢即换。 选择规则决定由谁响应 Pod 靠「匹配」加入 Service,而不是靠被人点名登记:标签打中了选择器,它就进入;不再匹配或不再就绪,就被移出。平台从选择器推出后端这份视图,当一个 Pod 通过探针与就绪,就把它加进去,缩容或下线时就拿掉。所以后端列表是一份实时推导的视图,而不是从头到尾手打的名单。也正因为后端由选择器与就绪共同决定,一个没就绪的 Pod 会自己掉出去,流量绝不会被送到不该服务的 Pod 上。 流量总给当前匹配的 这层间接,正是让端点变化落不到调用方身上的原因。客户端只握着那个名字;它背后的集合被扩、被替、被滚动更新,都不需要改客户端设一个字。滚动更新一个接一个地替换掉又续上 Pod,Service 始终把流量导向当前匹配且就绪的那批,于是调用方察觉不到任何断层。你可以依赖这件事:只要选择器精准、Pod 与它匹配,Service 在每个时刻都把流量送进正确的那批。把选择器钉紧、探针管严,这个稳定的家便能在里面的 Pod 全是新面孔时依旧稳如磐石。 ...

八月 23, 2027 · 2 分钟 · XB Field Notes
每个节点都监听的一个端口,背后站着集群的负载均衡。

NodePort 在每台节点的固定端口上开放服务

NodePort 类型的 Service 只做一件很直接的事:在 30000-32767 这个范围里占一个端口,让集群里每一台节点都在上面监听。kube-proxy 会把同一条转发规则写进每台机器的 iptables 或 IPVS 表,于是 curl <任意节点 IP>:<nodePort> 无论落到哪台机器都能到达这个 Service。这正是它全部的吸引力——不需要云负载均衡、不需要 DNS 记录、不需要 Ingress 控制器,就能对外可达。 代价藏在同一个设计里。既然每台节点都应答,包就经常落在没跑这个 Pod 的机器上,集群随后必须决定后端看到的是谁的地址。externalTrafficPolicy 就是这个决定:Cluster 把负载摊开但改写客户端地址,Local 保住客户端地址却在没有本地端点的节点上直接丢包。两者必须选一个,而每一种选择都会弄坏不同的东西。 一个每台节点都占着的端口 kubectl create service nodeport 不带 --node-port 时根本不会输出 nodePort 字段,端口由 API server 从范围里分配。这个分配是集群级而不是节点级的:一个号码在整个集群里只能属于一个 Service。所以两个都钉 31000 的 Service 无法共存,而一条针对某个号码的防火墙规则却可以原样搬到每台机器上。 ...

五月 11, 2027 · 2 分钟 · XB Field Notes
一个前端挂在若干 Pod 上的虚拟 IP 与 DNS 名。

Service 给一组 Pod 一个稳定的虚拟地址

选择器让 Service 从一段固定列表变成动态视图:新增移除都在后台完成,Pod 重启时客户端无需改任何配置。 先声明,再分配地址 Service 把 Pod 的持续更替变成一段稳定名字。你描述选择器(哪些 Pod)、端口与协议,控制面就划给它一个稳定的虚拟 IP 与一个请求不随成员变化的域名,而背后的集合一直可以走马灯。这段稳定名字成了对外的合同:任何资源——另一份 Deployment、一段 Ingress、或者另一个 Pod——都能按名字寻址,而不用关心此刻具体是哪个 Pod 在服务。有了这层间接,成员的多少与增减,永远不会惊动调用方。 选择器就是实时成员 Service 的后端列表不是一份手写的固定名单,而是由选择器随时重建的。一个就绪探针通过的 Pod 加进来,一个没有就绪的 Pod 被立即移出,端点在后台自动增减。因此你永远不会落到过期名单上:只要选择器所指与 Pod 的标签对得上,Service 会自动反映当前真正就绪的后端。这一点正是它与「手写一长串 IP」清单的分界:名单由共识自动生成,而不是靠哪个人按时去刷。 Pod 变了地址依旧稳定 客户端只访问那个虚拟地址,从不直接抓具体某个 Pod,所以调用方与真正的服务实现,靠这一层稳稳地解耦。你可以扩、可以缩、可以换、可以逐批重启,Service 都通过同一个端点把流量带到仍然就绪的那几个背后。客户看不到变化,因为让它依赖的那个名字从没变过。这才允许滚动重启与自动伸缩而不发一条公告。选择器写准、用 probe 把关,Service 就能在一批随时在变的 worker 之上,为你撑住一个始终稳定的前端。 坏掉的样子 地址池是有限的,耗尽是最字面的失败。每个普通 Service 都要从 --service-cluster-ip-range 里占用一个地址,如果网段当初划得很小,或者堆满了无人使用的旧 Service,新 Service 就会在创建时直接报分配错误。此时 Pod 本身看起来一切正常,只有 Service 始终无法就绪。看到 failed to allocate IP 要先当容量账来算:先删掉孤儿 Service,实在不够再放宽网段,否则单纯扩网段只是把同一次故障往后推。 ...

二月 9, 2027 · 2 分钟 · XB Field Notes