K8s创建Service和Endpoint后Pod无法访问私有IP如何排查
Kubernetes普通Pod无法访问手动绑定外部IP的Service排查方案
基础配置参考
Service配置
kind: Service apiVersion: v1 metadata: name: alloydb spec: ports: - port: 5432 targetPort: 5432 protocol: TCP
Endpoints配置
kind: Endpoints apiVersion: v1 metadata: name: alloydb subsets: - addresses: - ip: 10.60.242.7 ports: - port: 5432
已确认的状态
- 执行
kubectl get svc输出:NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE alloydb ClusterIP 10.107.254.93 <none> 5432/TCP 5m38s - 执行
kubectl get ep输出:NAME ENDPOINTS AGE alloydb 10.60.242.7:5432 6m7s - 执行
kubectl get netpol输出:No resources found in default namespace. - 集群节点直接访问
10.60.242.7:5432正常,hostNetwork: true模式的工作负载访问正常 - 普通Pod内服务名解析正常,可以正确得到Service的ClusterIP,但连接超时:
root@ubuntu:/# telnet alloydb 5432 Trying 10.107.254.93... telnet: Unable to connect to remote host: Connection timed out
排查步骤与解决方案
1. 优先排查外部网络回程路由问题(90%以上同类问题根因)
普通Pod访问Service时,流量经过kube-proxy DNAT后直接转发到外部目标IP,源IP为Pod自身的网段地址(属于集群Pod CIDR段,和节点网段不属于同一个广播域)。如果目标IP所在的私有网络没有配置Pod CIDR、Service CIDR段的回程路由,回包无法正确送达Pod所在节点,就会出现连接超时。
- 排查操作:
- 在节点出口网卡抓包验证:
tcpdump -i <节点出口网卡名> host 10.60.242.7 and port 5432,发起测试访问时如果只看到出站SYN包,看不到返回的SYN+ACK包,即可确认是路由问题。 - 核对集群的Pod CIDR、Service CIDR配置,确认这两个网段没有在目标私有网络的路由表中被指向集群节点所在网关。
- 在节点出口网卡抓包验证:
- 解决方案:
- 在私有网络核心交换机、VPC路由表中添加静态路由,将集群Pod CIDR、Service CIDR段的下一跳指向集群节点的子网网关,保证目标网络回包可以正常到达集群节点。
- 若暂时无法调整全局路由,可在节点上配置SNAT规则伪装源IP,让回包先回到节点再由节点转发给Pod:
配置后规则立即生效,注意需要将规则持久化避免节点重启后丢失。iptables -t nat -A POSTROUTING -s <集群Pod CIDR段> -d 10.60.242.7 -j MASQUERADE
2. 检查kube-proxy转发规则是否正常
如果抓包能看到回包但依然连接超时,检查kube-proxy是否生成了正确的转发规则:
- 确认kube-proxy工作模式:
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode - 若为ipvs模式,在节点上执行
ipvsadm -Ln | grep -A5 10.107.254.93,确认存在转发到10.60.242.7:5432的规则;若为iptables模式,执行iptables -t nat -L KUBE-SERVICES -n | grep 10.107.254.93确认nat规则存在。 - 若规则缺失,重启对应节点的kube-proxy Pod触发规则同步:
kubectl delete pod -n kube-system -l k8s-app=kube-proxy --field-selector spec.nodeName=<节点名>
3. 检查节点转发防火墙规则
节点默认FORWARD链策略为DROP、或者主机防火墙(firewalld/ufw)拦截跨网段转发时,也会导致流量被丢弃:
- 查看FORWARD链默认策略:
iptables -L FORWARD -n | head -n1,如果返回policy DROP,需要添加放通规则:iptables -I FORWARD -s <Pod CIDR段> -d 10.60.242.7 -j ACCEPT - 临时关闭主机防火墙测试连通性,确认是防火墙拦截的话,添加对应放通规则即可。
4. 检查EndpointSlice同步状态
K8s 1.21+版本默认使用EndpointSlice作为服务发现的数据源,如果对应Service的EndpointSlice资源异常缺失,kube-proxy不会生成转发规则:
- 执行命令检查:
kubectl get endpointslices -l kubernetes.io/service-name=alloydb - 若返回资源不存在或者地址段不包含10.60.242.7,直接删除异常的EndpointSlice,控制面会自动重建正确资源。
内容的提问来源于stack exchange,提问作者Bal Krishna Jha
相关产品推荐
相关产品推荐

