NodePort 改成 Local 后部分节点不通:检查本地端点与负载均衡
externalTrafficPolicy 为 Local 时,全局有后端也不能让无本地端点的节点转发;核对 EndpointSlice 与外部负载均衡检查,并保留源 IP 需求。
Service 有就绪后端,通过某个节点的 NodePort 能访问,换另一个节点却失败;配置中使用了 externalTrafficPolicy: Local。先把失败节点与 EndpointSlice 的 nodeName 对照:Local 只把这类外部流量送到接收节点上的端点,不会因为别的节点有健康 Pod 就跨节点兜底。
这个场景常见于外部负载均衡仍将请求发给全部 worker,而服务 Pod 只落在其中部分节点。Service 全局有后端和当前入口节点有可用本地后端,是两项检查。以下针对 NodePort 或经节点转发的 LoadBalancer 外部入口,具体数据平面还需核对平台实现。
先区分全部失败与按节点失败
下面是只读示例,替换命名空间、服务名及实际 Pod 选择条件:
kubectl -n team-app get service web -o yaml
kubectl -n team-app get pods -l app=web -o wide
kubectl -n team-app get endpointslice \
-l kubernetes.io/service-name=web -o yaml
核对服务类型、外部流量策略、NodePort、targetPort,以及端点地址、nodeName 和就绪条件。不是所有名为 web 的 Pod 都属于这个 Service,也不能只因 Pod Running 就视作可接收流量。
所有入口都失败、没有预期就绪端点时,先处理标签、就绪和应用监听。只有带本地端点的节点可访问,而无端点的节点失败,才支持 Local 入口选择不匹配这个判断。已有本地端点仍失败时,继续查节点防火墙、代理、网络策略及端点实际可用性。
负载均衡必须知道哪些节点能承接服务
外部设备仅探测节点存活、SSH 可达或一个通用 HTTP 页面,不代表该节点有此 Service 的本地端点。Local 策略下,应让负载均衡的后端选择和健康检查对应具体服务。
type 为 LoadBalancer 且 externalTrafficPolicy 为 Local 时,Kubernetes 的 healthCheckNodePort 可供外部系统判断节点是否持有服务端点。这一字段不适用于普通 NodePort Service,不能给 NodePort 随意填上相同字段期待获得自动健康检查。
平台是否创建并使用该检查、如何处理 Pod 迁移与终止,必须以实际控制器和负载均衡配置为准。已有 F5 等外部设备由另一组管理时,需协调它的池成员和服务级检查;只改 Kubernetes 对象,外部设备不一定会自动知道新的可用节点。
将端点节点静态写进设备列表也有维护风险。滚动发布、节点维护或调度变化后,旧列表可能失效;验收应覆盖迁移,而不只验证目前这个节点。
是否切回 Cluster,取决于源地址需求
不要求保留传到后端的源 IP,并且允许相应跨节点转发时,可以评估 Cluster 策略。它让入口按集群端点路由,但会改变来源地址与网络路径,不能作为无影响的临时开关。
如果应用、防火墙或网络策略依赖客户端地址,应先确认在每一跳实际看到什么。外部负载均衡若终止连接并另起连接,Local 也无法把新连接的源地址凭空变回原客户端。HTTP 转发头或 PROXY protocol 需要双方支持和可信边界,而且 HTTP 头不会变成 NetworkPolicy 判断的 IP 包源地址。
不要把全部节点网段加入许可名单来掩盖错误;这可能扩大允许范围,也不解决没有本地端点的节点仍接收流量。需要保留来源地址又无法调整负载均衡时,应由平台设计明确的入口架构和过滤位置,现有约束可能无法仅靠一个 Service 字段满足。
增加副本、调整分布或使用适合的工作负载可以增加有端点的节点,但必须考虑资源和更新过程,不能无条件把应用改成每节点一份。
核对外部入口及发布期间的流量
变更前保存 Service、工作负载和设备配置,列出预期后端与来源地址要求。维护窗口调整时观察错误率、连接中断和现有会话,失败则按依赖顺序恢复配置,防止外部池与 Local 策略再次不一致。
修复后从真实外部入口检查:流量只送往能够接收它的节点,应用看到的地址符合设计,正常发布或端点迁移时不会继续将新请求发送到无端点节点。集群内直接访问 LoadBalancer IP 可能采用 Cluster 语义,因此一次内部成功不能代替外部验收。


