externalTrafficPolicy 是什么
externalTrafficPolicy 决定来自集群外部的流量如何落到后端 Pod,只对 NodePort 与 LoadBalancer 类型的 Service 有意义。Cluster 是默认值:流量可以在节点之间转发,任何节点都能接住请求,但转发时会做一次源地址转换,上游看到的客户端 IP 会变成节点 IP;Local 只把流量交给本节点上的后端 Pod,少一跳且保留真实客户端 IP,代价是没有后端的节点会直接丢弃或拒绝流量。
两种策略对比
| 维度 | Cluster | Local |
|---|---|---|
| 节点无后端时 | 转发到其他节点上的 Pod | 该节点不承接流量(云 LB 通常据此摘除) |
| 客户端源 IP | 经源地址转换后丢失 | 保留真实源 IP |
| 网络跳数 | 多一跳(节点间转发) | 少一跳,直达本机 Pod |
| 负载分布 | 跨节点较均匀 | 取决于副本在节点上的分布 |
| 适用场景 | 一般服务,简单省心 | 需要源 IP 做风控、限流、审计的场景 |
典型使用场景
- 风控与审计:需要真实客户端 IP 做封禁、限流或日志分析时使用 Local
- 降低延迟:跳数减少,对延迟敏感的边缘入口有价值
- 云负载均衡健康检查:Local 下健康检查失败即摘除节点,能避免把流量送到没有后端的机器
- 副本分布不均的集群:Local 会让流量集中到有后端的少数节点,需要先保证副本分散
- 灰度入口切换:先从 Cluster 切到 Local 观察,再决定是否长期保留
配置与核对
配置与核对
spec:
type: LoadBalancer
externalTrafficPolicy: Local # 保留源 IP,节点无后端时不接流量
ports:
- port: 80
targetPort: 8080命令行检查
命令行检查
kubectl get svc web-lb -o jsonpath='{.spec.externalTrafficPolicy}' # 当前策略
kubectl get pods -o wide -l app=web | awk '{print $7}' | sort | uniq -c # 副本分布在哪些节点
kubectl get endpoints web-lb -o wide # 各节点的后端地址
kubectl get events --field-selector reason=LoadBalancerHealthCheckFailed | tail -5字段与现象读法
| 观察点 | 含义 | 风险信号 |
|---|---|---|
| externalTrafficPolicy 值 | Cluster 或 Local | 与设计不符时源 IP 可能悄悄丢失 |
| 副本所在节点数 | 有多少节点具备承接能力 | Local 下节点数过少会成为单点 |
| Endpoints 列表 | 参与负载的地址 | 为空说明没有就绪副本,流量全失 |
| 健康检查事件 | LB 对节点的探测结果 | 频繁失败说明节点上后端不稳定 |
Local 策略下,副本集中在少数节点意味着这些节点的网络与资源成为瓶颈:应配合反亲和、拓扑分布约束与 PodDisruptionBudget,让后端分布在足够多的节点上,否则扩缩容与节点维护都会造成容量骤降。
切到 Local 后,上游看到的源 IP 会变化。依赖 IP 白名单的下游系统需要同步调整,否则会出现「换了策略后调用被拒」这类看似无关的副作用。