服务无法访问的核心原因是流量未到达目标Pod,需按Pod→Endpoints→kube-proxy→Service类型链路逐层验证:先确认Pod运行且标签匹配,再检查Endpoints是否为空、targetPort与containerPort是否一致,接着区分ClusterIP/NodePort/LoadBalancer的正确访问方式,最后排查kube-proxy和CNI插件异常。

服务无法访问,大概率不是“Service写错了”,而是流量根本没走到它该去的地方。先别改YAML,按链路逐层验证:从Pod是否真在跑、到Endpoints有没有被填上、再到kube-proxy规则有没有生效、最后看访问方式是否匹配Service类型。
检查Endpoints是否为空
Endpoints是Service和Pod之间的关键桥梁。如果它为空,说明Service压根没找到后端Pod。
- 运行
kubectl get endpoints <service-name> -n <namespace>,输出中SUBSETS字段为空或NO ENDPOINTS就是问题信号 - 确认Service的
selector字段(比如app: nginx)和Pod的标签完全一致,注意大小写和拼写——app: nginx和app: Nginx不匹配 - 用
kubectl get pods -l app=nginx -n <namespace>验证是否有Pod带这个标签且状态为Running - 如果Pod是通过Deployment创建的,检查Deployment的
template.metadata.labels是否和Service的selector对得上,而不是只看Deployment自身的metadata.labels
验证targetPort与containerPort是否一致
这是最常被忽略的端口错配点。Service不会自动猜容器暴露的是哪个端口,必须显式对齐。
- 查Pod容器实际监听端口:
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[0].ports[0].containerPort}' - 查Service配置的
targetPort:kubectl get service <service-name> -n <namespace> -o jsonpath='{.spec.ports[0].targetPort}' - 二者必须数值相等;如果
targetPort写成字符串(如"http"),需确保Service所在命名空间有对应named port定义,否则解析失败 -
port字段(Service对外暴露的端口)可以任意,但targetPort必须严格匹配容器实际监听端口
区分Service类型并验证访问路径
ClusterIP、NodePort、LoadBalancer三者访问方式完全不同,用错路径必然失败。
-
ClusterIP:只能在集群内部访问,比如从另一个Pod里执行curl http://<service-name>:<port>;从节点或外部curlClusterIP地址会失败,这是正常行为 -
NodePort:必须用<node-ip>:<node-port>访问,且要确认节点防火墙(如ufw、iptables)和云厂商安全组放行了该端口 -
LoadBalancer:等待EXTERNAL-IP字段不再是<pending>;若长期pending,检查云提供商控制器(如cloud-controller-manager)是否就绪、权限是否足够 - 无论哪种类型,都建议先在集群内用
kubectl exec进一个临时Pod测试:kubectl run tmp -it --rm --image=curlimages/curl -- curl -v http://<service-name>:<port>
排查kube-proxy和CNI插件异常
即使前面全对,底层网络组件出问题也会导致流量静默丢弃。
- 检查kube-proxy Pod是否Running:
kubectl get pods -n kube-system | grep kube-proxy;若为CrashLoopBackOff,看日志:kubectl logs -n kube-system <kube-proxy-pod-name> - 确认节点上iptables规则存在:
kubectl exec -n kube-system <kube-proxy-pod-name> -- iptables-save | grep <service-cluster-ip>;无输出说明规则未生成 - CNI插件(如Calico、Cilium)异常时,Pod可能有IP但无法通信;检查CNI相关Pod状态,以及
kubectl get nodes -o wide中INTERNAL-IP是否正常 - 某些CNI(如Cilium)默认禁用kube-proxy,此时需确认Service流量是否由Cilium自身处理,避免规则冲突
真正卡住的地方往往不在Service定义本身,而在它和Pod之间那层看不见的绑定关系,以及底层网络组件是否默默罢工。每次改完配置,务必用kubectl get endpoints和集群内curl双重验证,别依赖“看起来应该没问题”。


















