K8s Service设置externalTrafficPolicy: Local后请求丢失问题求助
问题:配置
externalTrafficPolicy: Local后Kubernetes Service出现请求丢失 环境信息
- 集群规模:3个工作节点,每个节点均部署ingress-nginx控制器
- ingress-nginx Pod状态:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ingress-nginx-admission-create-ftw46 0/1 Completed 0 3h8m 192.168.186.218 node03 <none> <none> ingress-nginx-admission-patch-29gbc 0/1 Completed 1 3h8m 192.168.140.81 node02 <none> <none> ingress-nginx-controller-66479f6d78-6rbkv 1/1 Running 0 18m 192.168.196.158 node01 <none> <none> ingress-nginx-controller-66479f6d78-gh4bv 1/1 Running 0 18m 192.168.186.226 node03 <none> <none> ingress-nginx-controller-66479f6d78-qwxzq 1/1 Running 0 18m 192.168.140.90 node02 <none> <none>
相关配置
NodePort Service配置(ingress-nginx-controller)
apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.4.0 name: ingress-nginx-controller namespace: ingress-nginx spec: externalTrafficPolicy: Local ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - appProtocol: http name: http port: 80 nodePort: 10080 protocol: TCP targetPort: http - appProtocol: https name: https port: 443 nodePort: 10443 protocol: TCP targetPort: https selector: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx type: NodePort
Ingress资源配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-nginx spec: ingressClassName: nginx rules: - host: my.nginx.local http: paths: - path: / pathType: Exact backend: service: name: nginx port: number: 8080 - host: my.kubia.local http: paths: - path: / pathType: Exact backend: service: name: kubia port: number: 80
问题现象
向节点192.168.56.23:10080发起请求时,部分请求超时,示例如下:
curl -H "Host:my.kubia.local" 192.168.56.23:10080 You've hit kubia-z7slg curl -H "Host:my.kubia.local" 192.168.56.23:10080 You've hit kubia-pjgtc curl -H "Host:my.kubia.local" 192.168.56.23:10080 curl: (28) Failed to connect to 192.168.56.23 port 10080 after 75012 ms: Operation timed out curl -H "Host:my.kubia.local" 192.168.56.23:10080 You've hit kubia-z7slg curl -H "Host:my.kubia.local" 192.168.56.23:10080 curl: (28) Failed to connect to 192.168.56.23 port 10080 after 75012 ms: Operation timed out
删除externalTrafficPolicy: Local配置后,所有请求恢复正常。尝试过Deployment(全节点副本)和DaemonSet两种部署方式,问题现象一致。
可能的原因及排查方向
- kube-proxy规则异常:若集群使用
iptables模式的kube-proxy,externalTrafficPolicy: Local会让kube-proxy仅在节点上配置转发本地Pod的规则。如果节点上的ingress-nginx Pod就绪性存在隐性问题(READY状态显示正常但实际服务未就绪),会导致流量无法转发。 - 节点网络拦截:节点防火墙或安全组可能拦截了NodePort的入站流量,或者阻止了Pod与Service之间的内部通信。
- ingress-nginx版本bug:当前使用的1.4.0版本可能存在与
externalTrafficPolicy: Local兼容的已知问题,升级到稳定版可验证是否解决。 - 会话亲和性冲突:若后端Service配置了会话亲和性,结合本地流量策略可能导致流量无法路由到可用Pod。
排查步骤
- 检查节点iptables规则:在异常节点执行
iptables-save | grep KUBE-SVC-$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.spec.clusterIP}'),确认规则是否正确指向本地ingress-nginx Pod的IP。 - 验证Pod就绪状态:手动调用ingress-nginx Pod的健康检查接口
curl http://<pod-ip>:10254/healthz,确认Pod实际服务状态是否正常。 - 检查节点防火墙:确认节点防火墙允许10080、10443端口的入站流量,且未拦截集群内部Pod通信。
- 切换kube-proxy模式:临时将kube-proxy切换为
ipvs模式,观察问题是否消失。 - 升级ingress-nginx:升级到最新稳定版控制器,验证兼容性问题是否解决。
内容的提问来源于stack exchange,提问作者Artem Shestakov
相关产品推荐
相关产品推荐

