Kubernetes同命名空间跨ClusterIP服务访问偶发请求失败问题
Kubernetes同命名空间ClusterIP服务互访偶发失败排查方案
问题背景
同一Kubernetes命名空间内创建两个ClusterIP类型服务,通过ClusterIP地址跨服务访问时出现请求偶发成功、偶发失败的异常,经核查两个服务关联Pod均处于正常运行状态,服务配置如下:
apiVersion: v1 kind: Service metadata: name: serviceA spec: selector: app: ServiceA ports: - name: http port: 80 targetPort: 8080 type: ClusterIP --- apiVersion: v1 kind: Service metadata: name: serviceB spec: selector: app: ServiceB ports: - name: http port: 80 targetPort: 8123 type: ClusterIP
排查步骤与修复方案
- 核对Service端点列表有效性
执行kubectl get endpoints serviceA -n <你的命名空间>、kubectl get endpoints serviceB -n <你的命名空间>查看后端地址列表,确认所有条目都是可正常提供服务的Pod IP+端口:- ServiceA的后端端口必须是Pod实际监听的8080,ServiceB的后端端口必须是Pod实际监听的8123,如果存在端口配置和应用实际监听端口不一致的情况,修改Service的
targetPort字段和应用监听端口对齐即可 - 如果端点列表中存在已经销毁、不存在的Pod IP,说明端点同步存在延迟,检查kube-controller-manager的工作状态,确认Pod生命周期事件正常推送
- ServiceA的后端端口必须是Pod实际监听的8080,ServiceB的后端端口必须是Pod实际监听的8123,如果存在端口配置和应用实际监听端口不一致的情况,修改Service的
- 检查Service标签选择器匹配范围
执行kubectl get pods -l app=ServiceA -n <你的命名空间>、kubectl get pods -l app=ServiceB -n <你的命名空间>,核对返回的Pod列表是否完全是预期的业务副本:
如果存在其他误打了相同app标签的无关Pod(比如未清理的旧版本副本、其他工作负载),Service会将这些Pod也加入负载均衡池,请求转发到未启动对应服务的无关Pod时就会触发失败,修改无关Pod的标签避免和Service selector冲突即可修复 - 检查kube-proxy转发规则状态
登录客户端Pod所在的集群节点,执行iptables -t nat -L KUBE-SERVICES | grep <目标服务的ClusterIP>(iptables模式)或ipvsadm -Ln | grep <目标服务的ClusterIP>(ipvs模式),核对转发规则是否和Service端点列表一致:
如果规则存在缺失、后端地址和实际端点不匹配,属于kube-proxy规则同步异常,删除对应节点上的kube-proxy Pod触发其重启重建全量转发规则即可 - 核对应用与连接配置
- 检查业务Pod是否配置了正确的就绪探针(readinessProbe):如果未配置就绪探针,Pod启动过程中还没完成服务初始化就会被加入Service后端池,请求转发到还没准备好的Pod就会失败;如果就绪探针配置的检查端口、检查路径错误,会导致Pod状态判断异常,异常Pod被错误加入后端池
- 检查客户端HTTP连接配置:如果客户端开启长连接且未配置连接存活检测,后端Pod重建销毁后旧连接未被客户端感知,复用失效连接发请求时会偶发失败,调整客户端连接空闲超时、开启连接健康检查即可
- 网络层连通性校验
如果以上配置都无异常,在请求失败时同时在客户端Pod、服务端Pod上使用tcpdump抓包,确认请求是否正常到达服务端、响应是否正常返回,排查是否为CNI插件故障、节点安全组/防火墙规则偶发拦截导致的丢包问题。
内容的提问来源于stack exchange,提问作者siva
相关产品推荐
相关产品推荐

