在K8S中,有个服务使用service的nodeport进行暴露,访问不到如何排查?
在Kubernetes中,通过NodePort暴露的服务无法访问时,可按照以下步骤逐步排查,从服务配置到网络链路逐层定位问题:
1. 检查Service本身配置与状态
首先确认Service是否正确创建且NodePort已正常分配。
-
查看Service基本信息
执行命令:kubectl get svc <service-name> -o wide
重点关注:
TYPE
是否为NodePort
(确保不是ClusterIP或LoadBalancer)。PORT(S)
列是否显示[目标端口]:[NodePort]/TCP
(例如80:30080/TCP
,30080即为NodePort)。- 若未显示NodePort,可能是端口超出默认范围(通常30000-32767)或集群配置限制,需检查Service的
nodePort
字段是否合法。
-
查看Service详细描述
执行命令:kubectl describe svc <service-name>
重点关注:
Endpoints
字段是否有值(格式为PodIP:targetPort
)。若为空,说明Service的selector
与Pod的labels
不匹配,导致没有后端Pod。
2. 检查后端Pod状态与可用性
Service的Endpoints依赖于匹配的Pod,需确认Pod正常运行且应用可访问。
-
检查Pod状态
执行命令:kubectl get pods -l <selector-key>=<selector-value> # 用Service的selector过滤
确保Pod处于
Running
状态,无CrashLoopBackOff
、Error
等异常(若有异常,执行kubectl logs <pod-name>
查看日志)。 -
检查Pod与Service的label匹配
执行命令:kubectl get pods <pod-name> -o jsonpath='{.metadata.labels}' # 查看Pod的labels kubectl get svc <service-name> -o jsonpath='{.spec.selector}' # 查看Service的selector
确保两者的键值对完全一致(例如均为
app: my-app
)。 -
验证Pod内应用是否正常监听端口
进入Pod内部,检查应用是否在Service配置的targetPort
上监听:kubectl exec -it <pod-name> -- sh # 进入Pod # 内部执行:检查端口监听(如targetPort=8080) netstat -tuln | grep 8080 # 或 ss -tuln | grep 8080 # 测试应用是否响应(如HTTP服务) curl localhost:8080
若应用未监听目标端口或无响应,需排查应用本身(如启动失败、配置错误)。
3. 检查节点层面网络与端口
NodePort会在集群所有节点开放端口,需确认节点端口可访问。
-
确认节点IP正确性
获取节点IP(外部可访问的IP,非集群内部IP):kubectl get nodes -o wide # 查看节点的EXTERNAL-IP或INTERNAL-IP(根据网络环境选择)
访问时需使用节点的实际IP(例如
http://<node-ip>:<nodeport>
),而非集群VIP或控制平面IP。 -
检查节点防火墙规则
登录节点(或通过云平台控制台),确认防火墙允许NodePort端口的入站流量:- 对于
iptables
:iptables -L INPUT -n | grep <nodeport> # 检查是否有允许规则
- 对于
firewalld
:firewall-cmd --list-ports | grep <nodeport>/tcp
若未允许,需添加规则开放该端口(例如
firewall-cmd --add-port=<nodeport>/tcp --permanent
)。 - 对于
-
检查节点是否可达
从客户端测试节点网络连通性:ping <node-ip> # 确认节点可ping通 telnet <node-ip> <nodeport> # 确认端口是否开放(连接成功则端口可达)
4. 检查kube-proxy与网络插件
kube-proxy负责维护NodePort的转发规则,网络插件负责Pod与节点的网络连通。
-
检查kube-proxy状态
kube-proxy通常以DaemonSet运行在每个节点,执行:kubectl get pods -n kube-system | grep kube-proxy # 确认所有节点的kube-proxy Pod正常运行 kubectl logs <kube-proxy-pod> -n kube-system # 查看日志是否有错误(如端口冲突、规则配置失败)
-
检查网络插件状态
确认Calico、Flannel、Cilium等网络插件正常运行:kubectl get pods -n <网络插件命名空间> # 例如Calico在kube-system,Cilium在cilium kubectl get nodes # 确认所有节点状态为Ready(NotReady可能是网络插件故障)
5. 检查Service的externalTrafficPolicy配置
若Service配置了 externalTrafficPolicy: Local
,则只有运行对应Pod的节点会响应NodePort请求(未运行Pod的节点会拒绝访问)。
- 查看配置:
kubectl get svc <service-name> -o jsonpath='{.spec.externalTrafficPolicy}'
- 若为
Local
,可临时改为Cluster
(所有节点均会转发请求)排查:kubectl patch svc <service-name> -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
6. 云环境特殊检查(若适用)
若在云厂商(如AWS、GCP、阿里云)的K8s集群中,还需检查:
- 节点公网IP:确保访问的节点有公网IP(或通过负载均衡转发)。
- 安全组规则:云平台的节点安全组需允许NodePort端口的入站流量。
- 网络ACL:子网的网络ACL规则是否阻止了流量。
总结排查流程
- 确认Service配置正确、NodePort已分配、Endpoints非空;
- 确认后端Pod正常运行、应用监听正确端口;
- 确认节点IP正确、防火墙开放NodePort、端口可达;
- 检查kube-proxy和网络插件状态;
- 排查externalTrafficPolicy和云环境特殊限制。
通过以上步骤,可逐步定位从Service到应用的全链路问题,找到访问失败的根源。