1. 基础检查
- 确认 Pod 和 Service 状态:
- kubectl get pods -n <namespace>:检查目标 Pod 是否处于 Running 状态,且 READY 列显示为 1/1 或 x/x。
- kubectl get svc -n <namespace>:检查目标 Service 是否存在,CLUSTER-IP 不是 <none>,PORT(S) 正确。
- kubectl describe pod <pod-name> -n <namespace>:检查 Pod 的 Events,看是否有启动失败、镜像拉取失败、资源不足等问题。
- kubectl describe svc <service-name> -n <namespace>:检查 Service 的 Endpoints 是否有对应的 Pod IP。这是关键! 如果 Endpoints 为空,说明 Service 没有找到匹配的后端 Pod。
- 确认 DNS 服务运行正常:
- kubectl get pods -n kube-system | grep kube-dns 或 kubectl get pods -n kube-system | grep coredns:检查 CoreDNS (或 kube-dns) Pod 是否都在 Running 状态。
- kubectl logs -n kube-system <coredns-pod-name>:查看 CoreDNS 日志是否有错误(如配置错误、无法连接 API Server 等)。
2. 检查 Service 与 Pod 的匹配
- 检查标签 (Labels) 和选择器 (Selector):
- kubectl get svc <service-name> -n <namespace> -o yaml:查看 Service 的 spec.selector 字段。
- kubectl get pod <pod-name> -n <namespace> -o yaml:查看目标 Pod 的 metadata.labels。
- 确保 Pod 的标签完全匹配 Service 的选择器。 这是 Endpoints 为空的最常见原因。
3. 检查网络策略 (NetworkPolicy)
- 如果集群启用了 NetworkPolicy,检查是否有策略阻止了从源 Pod 到目标 Service 的流量。
- kubectl get networkpolicy -n <namespace>:查看命名空间下的网络策略。
- 检查策略的 podSelector、ingress 和 egress 规则是否允许必要的通信。
4. 检查 CNI 插件和网络连通性
- CNI 插件状态:
- 检查你使用的 CNI 插件(如 Calico, Flannel, Cilium 等)的 Pod 是否都在 Running 状态(通常在 kube-system 或特定命名空间)。
- 查看 CNI 插件的日志是否有错误。
- Pod 间基本连通性测试:
- 在一个 Pod 中尝试 ping 另一个 Pod 的 IP 地址(kubectl get pod <pod-name> -o wide 获取 IP)。
- 如果 Pod 间 IP 无法 ping 通,问题很可能出在 CNI 网络层面。
5. DNS 解析问题排查
- 进入 Pod 执行 DNS 查询:
- kubectl exec -it <source-pod-name> -n <namespace> -- sh (或 bash)
- 在 Pod 内部执行:
- nslookup <service-name>.<namespace>.svc.cluster.local (使用完全限定域名 FQDN)
- nslookup <service-name>.<namespace>
- nslookup <service-name> (在同一个命名空间内)
- cat /etc/resolv.conf:检查 DNS 配置是否正确(nameserver 应该是 kube-dns 或 coredns 的 ClusterIP,通常是 10.96.0.10 或类似地址,search 域名是否包含 .svc.cluster.local 等)。
- 使用 dig 命令(如果 Pod 内有安装):
- dig @<coredns-service-ip> <service-name>.<namespace>.svc.cluster.local
- 测试 CoreDNS 本身:
- kubectl exec -it <source-pod> -- nslookup kubernetes.default:这个应该总是能解析成功,因为它指向 API Server Service。如果这个都失败,说明 DNS 服务本身或网络有严重问题。
6. 检查 kube-proxy
- kubectl get pods -n kube-system | grep kube-proxy:检查所有节点上的 kube-proxy Pod 是否都在 Running 状态。
- kubectl logs -n kube-system <kube-proxy-pod-name>:查看 kube-proxy 日志是否有错误。
- kube-proxy 负责在每个节点上设置 iptables/ipvs 规则,将 Service 的 ClusterIP 流量转发到后端 Pod。如果它出问题,Service 就无法工作。
7. 检查防火墙和安全组
- 节点间防火墙: 确保 Kubernetes 节点之间的必要端口是开放的(如 6443, 10250, 30000-32767 等,具体取决于 CNI 和配置)。
- 云服务商安全组: 如果在云上(AWS, GCP, Azure, 阿里云等),检查安全组规则是否允许节点间的通信和 Pod 网络流量。
8. 检查资源限制
- kubectl describe node:检查节点是否有足够的 CPU、内存资源。资源不足可能导致 Pod 调度失败或运行异常。
- 检查 Pod 的资源请求和限制是否合理。
9. 特殊情况
- Headless Service: 如果 Service 的 clusterIP: None (Headless Service),它不会分配 ClusterIP,DNS 解析会直接返回后端 Pod 的 A 记录。确保你的应用逻辑能处理这种情况。
- ExternalName Service: 这种 Service 会将请求重定向到外部 CNAME,检查 CNAME 是否正确。
- Pod 网络插件配置错误: 检查 CNI 插件的配置文件(通常在 /etc/cni/net.d/)是否正确。
诊断命令总结
# 1. 检查核心组件
kubectl get pods -n kube-system | grep -E "(coredns|kube-dns|kube-proxy)"
# 2. 检查目标服务和 Pod
kubectl get svc <service-name> -n <namespace>
kubectl get pods -n <namespace> -l <your-service-selector-labels> # 根据 Service 的 selector 查找 Pod
kubectl describe svc <service-name> -n <namespace> # 重点看 Endpoints
# 3. 进入源 Pod 测试
kubectl exec -it <source-pod> -n <namespace> -- sh
# 在 Pod 内:
cat /etc/resolv.conf
nslookup <service-name>.<namespace>.svc.cluster.local
nslookup kubernetes.default # 测试 DNS 基础功能
# 尝试直接访问 Pod IP (如果知道)
ping <target-pod-ip>
curl <target-pod-ip>:<port>
按照这个流程,从最基础的 Pod 和 Service 状态、Endpoints 是否为空开始,逐步向上排查。Endpoints 为空通常是标签不匹配;Endpoints 有 IP 但访问不通,再排查网络、DNS 解析、kube-proxy、CNI 等问题。