Google Cloud上Kubernetes UDP服务无法通过负载均衡访问
首先得纠正一个关键误区:你用telnet测试UDP端口是行不通的!telnet是基于TCP协议的工具,而UDP是无连接协议,不会建立TCP那样的握手连接,所以你看到的Connection refused其实是TCP连接失败的提示,和你的UDP服务本身没关系。
你应该用UDP专用的测试工具,比如nc(netcat)来测试:
nc -u 35.192.59.72 10001
输入任意内容后回车,如果服务正常,应该能收到镜像返回的响应(比如jpoon/udp-server会回显你发送的内容)。
接下来我们一步步排查可能的问题:
1. 先确认Pod和服务关联是否正常
首先检查你的Pod是否正常运行,以及Service有没有正确绑定到Pod:
- 查看Pod状态:
kubectl get pods -l name=udp-server
确保所有2个副本都处于Running状态,没有重启或启动失败的情况。
- 查看Service的端点:
kubectl describe service udp-server-service
在输出的Endpoints字段里,应该能看到两个Pod的IP地址(对应你设置的2个副本)。如果这里是空的,说明Service的selector和Pod的label不匹配——不过看你的配置,Service用的selector: name: udp-server和Pod的labels: name: udp-server是匹配的,这部分应该没问题,但还是要确认一下。
2. 检查GCP的防火墙规则
GKE创建LoadBalancer时会自动生成对应的防火墙规则,但偶尔可能需要手动确认:
- 登录GCP控制台,进入「VPC网络」→「防火墙规则」,搜索包含
k8s-fw-udp-server-service(或你的Service名称)的规则,确认它允许UDP协议,来源是0.0.0.0/0(或者你需要的IP范围),目标是你的集群节点标签。 - 也可以用gcloud命令快速查看:
gcloud compute firewall-rules list --filter="name~k8s-fw-udp"
确保规则的ALLOW字段包含udp:10001,TARGET_TAGS是你的集群节点的标签(比如gke-你的集群名称-node-pool-xxxx)。
3. 验证Pod内部的UDP服务是否正常工作
进入其中一个Pod,直接测试内部的服务是否在监听UDP端口:
kubectl exec -it <你的Pod名称> -- sh
在Pod内用ss命令查看端口监听状态:
ss -ulnp | grep 10001
正常情况下应该能看到类似udp UNCONN 0 0 *:10001 *:*的输出,说明服务在正确监听UDP的10001端口。你也可以在Pod内用nc测试服务本身:
nc -u localhost 10001
输入内容后如果能收到回显,说明服务本身没有问题。
4. 确认LoadBalancer的状态是否就绪
查看Service的外部IP是否已经完全分配:
kubectl get service udp-server-service
确保EXTERNAL-IP不是<pending>状态,而是已经分配了你使用的35.192.59.72。另外,GCP的UDP LoadBalancer可能需要几分钟才能完成配置,如果是刚创建的服务,可以等个2-3分钟再测试。
5. 额外检查:节点的iptables规则
虽然LoadBalancer的防火墙规则应该已经开放,但也可以确认节点本身的iptables没有阻止UDP流量:
通过GCP控制台或者gcloud compute ssh <节点名称>登录到集群节点,然后执行:
sudo iptables -L -n | grep 10001
应该能看到允许UDP 10001流量通过的规则。
总结一下,最可能的问题就是你用了错误的测试工具,先换成nc -u试试,如果还是不行,再按照上面的步骤逐一排查。
内容的提问来源于stack exchange,提问作者Tameem Iftikhar

