容器网络排障最困难的地方,不是命令不够多,而是故障路径很长。一次服务访问失败,可能发生在应用监听、Pod IP、Service 选择器、kube-proxy、CoreDNS、Ingress、NetworkPolicy、CNI 插件、节点路由、防火墙或外部负载均衡任意一层。如果没有分层方法,排障很容易在不同组件之间来回跳转。
Kubernetes 网络的基本假设是:Pod 之间可以通过 Pod IP 互通,Service 为后端 Pod 提供稳定访问入口,DNS 负责服务名解析,Ingress 或网关负责集群入口流量,CNI 插件负责底层网络实现。排障时应沿着访问链路逐层验证,而不是一开始就怀疑 CNI。
先确认故障范围
排障第一步不是执行命令,而是确认故障范围。只有某个 Pod 无法访问,还是同一应用所有副本都失败?只有跨命名空间失败,还是同命名空间也失败?只有通过 Service 失败,还是 Pod IP 直连也失败?只有外部入口失败,还是集群内部也失败?这些问题能快速缩小范围。
如果 Pod IP 直连失败,重点看 Pod 状态、应用监听、网络策略、CNI 和节点网络。如果 Pod IP 可访问但 Service 不可访问,重点看 Service selector、EndpointSlice、kube-proxy 或代理模式。如果 Service 可访问但域名不可解析,重点看 CoreDNS。如果集群内可访问但外部不可访问,重点看 Ingress、网关、负载均衡和安全组。
把故障范围先划清楚,可以避免一上来就重启 CoreDNS、重建 Pod 或修改网络插件配置。
Pod连通性怎么验证
Pod 层排障要确认三件事:目标应用是否真正监听,Pod IP 是否可达,容器内部是否存在本地防火墙或进程异常。可以先查看 Pod 状态和 IP:
kubectl get pod -o wide -n <namespace>
kubectl describe pod <pod_name> -n <namespace>
进入临时调试 Pod 后,用 curl、nc、dig 等工具验证目标地址。不要只在业务容器里排查,因为业务镜像可能缺少网络工具,也可能因为安全策略限制无法执行命令。生产环境建议准备标准调试镜像,并由平台控制使用权限。
如果同节点 Pod 能访问、跨节点 Pod 不能访问,问题可能与 CNI 路由、隧道、节点防火墙或安全组有关。如果所有方向都无法访问,先检查目标应用是否监听正确端口,以及容器端口和服务端口是否混淆。
Service访问失败看三项
Service 访问失败时,最常见的原因不是 Kubernetes 网络坏了,而是 selector 不匹配、后端 Pod 未 Ready、端口配置错误。排查时先看 Service 和 EndpointSlice:
kubectl get svc -n <namespace>
kubectl get endpointslice -n <namespace>
kubectl describe svc <service_name> -n <namespace>
如果 Service 没有后端地址,应检查 selector 是否匹配 Pod label,以及 Pod 是否处于 Ready 状态。如果有后端地址但访问失败,再检查 targetPort 是否对应应用真实监听端口。Service 的 port、targetPort、nodePort 各自含义不同,配置错位会造成看似正常但无法访问。
在 kube-proxy 使用 iptables 或 IPVS 模式时,还可能出现节点代理规则异常。但这类问题通常影响范围较大,不应在没有证据时优先假设。先确认 Service 对象和后端端点,再进入节点代理层。
DNS问题不要和网络问题混在一起
很多“服务访问失败”其实是 DNS 解析失败。典型表现是使用服务名访问失败,但直接访问 Service ClusterIP 可以成功。此时重点看 CoreDNS、服务域名、命名空间和 search path。
Kubernetes 中完整服务域名通常是:
<service>.<namespace>.svc.cluster.local
如果跨命名空间访问,只写服务名可能解析到当前命名空间,导致访问错误。排查时可以在调试 Pod 中执行:
nslookup <service>.<namespace>.svc.cluster.local
dig <service>.<namespace>.svc.cluster.local
CoreDNS 问题通常会影响多个服务和命名空间。如果只有一个服务解析失败,优先检查 Service 是否存在、命名空间是否正确、服务名是否拼写错误。不要因为一次解析失败就直接重启 CoreDNS。
NetworkPolicy要按默认行为判断
NetworkPolicy 的难点在于默认行为。没有任何 NetworkPolicy 时,Pod 通常默认允许流量;一旦某个 Pod 被 NetworkPolicy 选中,未明确允许的流量可能被拒绝。排障时要看策略是否选中了目标 Pod 或源 Pod,以及 ingress、egress 方向是否都需要放行。
常见误区是只配置入站规则,忽略出站规则;只允许业务端口,忽略 DNS;只按 namespaceSelector 放行,忘记 podSelector;策略选择器写错导致保护对象和预期不同。
建议把网络策略排障拆成三步:第一,确认故障 Pod 是否被策略选中;第二,确认源、目标、端口和协议是否被允许;第三,确认 DNS、健康检查和监控采集等辅助流量是否被误拦。对于复杂策略,可以在测试命名空间复现,而不是直接在生产大范围修改。
外部入口要看完整链路
外部访问失败通常经过负载均衡、Ingress 或网关、Service、Pod 多层链路。排障时要从外到内验证:域名是否解析到正确入口,证书和 TLS 是否正常,Ingress 规则是否匹配,后端 Service 是否存在,EndpointSlice 是否有 Ready Pod,应用是否返回预期状态码。
Ingress 返回 404、502、503 的含义不同。404 往往是路由规则不匹配,502 可能是后端连接失败,503 可能是没有可用后端或上游异常。不同网关实现的错误码细节不完全一致,但分层排查思路相同。
对于生产入口,建议把网关指标、访问日志和后端服务事件关联起来。只看应用日志可能看不到请求,因为请求可能还没有到达业务 Pod。
节点和CNI问题如何判断
只有在 Pod、Service、DNS、策略都排除后,才应深入节点和 CNI。节点层要看路由、网卡、iptables/IPVS、CNI 插件 Pod、节点防火墙、安全组、MTU 和跨节点连通性。CNI 问题往往影响某个节点、某个节点池或一类跨节点访问,而不是只影响一个服务。
常见信号包括:同节点访问正常、跨节点访问失败;新建 Pod 无法分配 IP;节点上 CNI 插件异常重启;Pod 创建卡在 ContainerCreating;大量网络超时集中在某个节点池。此时可以结合 CNI 插件日志、节点事件和网络监控判断。
生产环境不建议临时手工修改节点网络规则来“修好”问题。CNI 和节点网络属于基础层,临时修改很容易被重启或自动化工具覆盖,也可能影响其他业务。
常见问题
Pod之间不能访问,先查什么?
先确认源 Pod、目标 Pod 是否 Running 且 Ready,再确认目标应用是否监听正确端口。然后测试 Pod IP 直连和 Service 访问,判断问题在 Pod 层还是 Service 层。不要一开始就怀疑 CNI,很多问题来自端口、标签和就绪状态配置错误。
Service有ClusterIP但访问不了是什么原因?
常见原因包括 selector 不匹配、EndpointSlice 为空、targetPort 配错、后端 Pod 未 Ready、网络策略拦截或 kube-proxy 规则异常。建议先看 Service 描述和 EndpointSlice,如果没有后端端点,问题通常不在网络转发层。
CoreDNS异常会影响哪些访问?
CoreDNS异常主要影响通过域名访问服务的场景。若直接访问 ClusterIP 可以成功,但服务名解析失败,就应检查 DNS。若 Pod IP、ClusterIP 和服务名都访问失败,则问题不只是 DNS,需要继续排查 Pod、Service 或网络层。
网络策略生效后为什么DNS也失败了?
如果启用了 egress 限制,但没有放行到 CoreDNS 的 UDP/TCP 53 端口,Pod 可能无法解析服务域名。网络策略设计时要把 DNS、监控、日志、镜像仓库、外部依赖等基础流量纳入考虑,而不是只放行业务服务端口。
结语
容器网络排障的关键是按链路分层:先定范围,再看 Pod,接着看 Service、DNS、NetworkPolicy、Ingress,最后进入 CNI 和节点网络。只要建立稳定的排障顺序,大多数 Kubernetes 网络故障都能被归类到明确层级,避免盲目重启和误改基础组件。
转载请注明出处:https://www.cloudnative-tech.com/p/7481/