Kubernetes 网络深度解析:从 Pod 通信到 Ingress 故障定位
Kubernetes 网络的目标很清晰:每个 Pod 拥有独立 IP,Pod 之间可以直接通信,Service 提供稳定访问入口,Ingress 或 Gateway 负责南北向流量。但在生产环境中,网络问题往往最难排查,因为它横跨应用、DNS、Service、kube-proxy、CNI、节点路由、安全组、防火墙和外部负载均衡。
理解 K8s 网络的第一步,是把路径拆开。一次外部请求通常经历:客户端、DNS、公网负载均衡、Ingress Controller、Service、EndpointSlice、Pod、应用容器。任意一层异常,最终都可能表现为 502、503、超时、连接重置或间歇性失败。
Pod 网络模型
K8s 要求所有 Pod 在集群内拥有可路由 IP,且不需要 NAT 就能互相访问。真正实现这一点的是 CNI 插件,例如 Calico、Cilium、Flannel、Weave、云厂商 VPC CNI 等。
不同 CNI 的实现差异很大:
- Overlay 模式通过封装实现跨节点通信,部署简单,但有额外封装开销。
- Underlay 或 VPC 原生模式让 Pod IP 直接进入基础网络,性能和可观测性更好,但对 IP 地址规划要求更高。
- eBPF CNI 可以绕过部分 iptables 复杂度,提升性能和策略能力。
生产选型时,不要只看性能指标。还要评估 NetworkPolicy 支持、可观测性、升级复杂度、云网络兼容性、故障排查工具、团队熟悉度。
Service 与 EndpointSlice
Service 是稳定访问抽象,背后通过 selector 选择 Pod,并生成 EndpointSlice。请求进入 Service 后,会被转发到后端 Pod。
排查 Service 问题时,先看三件事:
kubectl get svc -n <namespace>
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service>
kubectl get pod -n <namespace> -l app=<app> -o wide
如果 Service 没有 endpoint,通常是 selector 与 Pod labels 不匹配,或者 Pod 没有 Ready。很多 503 问题并不是 Ingress 坏了,而是后端 endpoint 为空。
Service 类型也要区分:
- ClusterIP:集群内部访问。
- NodePort:通过节点端口暴露。
- LoadBalancer:由云厂商或负载均衡实现暴露。
- ExternalName:DNS CNAME 映射。
生产中不建议大量直接使用 NodePort 暴露业务。它绕过了更清晰的入口治理,容易增加安全面。
kube-proxy 与流量转发
kube-proxy 负责实现 Service 到后端 Pod 的转发。常见模式包括 iptables、IPVS,以及部分 eBPF CNI 的替代实现。
iptables 模式在大规模 Service 和 Endpoint 下规则会膨胀,排查也更复杂。IPVS 更适合大规模集群,但仍然需要关注内核模块、连接跟踪表和节点负载。
连接跟踪表耗尽时,会出现非常隐蔽的网络问题:请求随机失败、DNS 间歇性超时、Service 访问不稳定。可以关注节点上的 conntrack 使用率,并为高连接场景调整内核参数。
DNS 是高频故障点
CoreDNS 是集群内服务发现核心。应用访问 svc.namespace.svc.cluster.local 时,背后依赖 CoreDNS。DNS 慢或失败,会让应用表现为连接超时、启动慢、依赖不可达。
排查 DNS:
kubectl -n kube-system get deploy coredns
kubectl -n kube-system logs deploy/coredns
kubectl run dns-test --rm -it --image=busybox:1.36 -- nslookup kubernetes.default
常见问题包括 CoreDNS 副本不足、节点 DNS 配置异常、上游 DNS 慢、ndots 配置导致额外查询过多、应用短连接频繁解析。
对高并发业务,建议观察 CoreDNS QPS、错误率、延迟和缓存命中率。CoreDNS 不是“装上就不用管”的组件。
Ingress 故障定位
Ingress Controller 通常是外部流量进入集群的第一站。常见实现包括 NGINX Ingress、Traefik、HAProxy、Envoy Gateway、云厂商 ALB Ingress Controller 等。
外部访问失败时,按路径分层排查:
- 域名是否解析到正确负载均衡。
- 负载均衡健康检查是否通过。
- Ingress Controller Pod 是否 Ready。
- Ingress 规则 host/path 是否匹配。
- 后端 Service 是否存在 endpoint。
- 应用容器是否监听目标端口。
- readinessProbe 是否导致 Pod 未加入 endpoint。
502 往往表示入口能到达后端但连接失败,503 往往表示后端不可用或 endpoint 为空,504 往往表示后端超时。具体还要结合 Controller 日志确认。
NetworkPolicy
默认情况下,很多集群内 Pod 可以互相访问。生产环境建议使用 NetworkPolicy 做最小权限网络隔离,尤其是多团队共享集群。
一个典型策略是默认拒绝 namespace 内所有入站,然后只开放必要来源:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-to-api
namespace: prod
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: gateway
ports:
- protocol: TCP
port: 8080
注意:NetworkPolicy 是否生效取决于 CNI 插件支持。如果 CNI 不支持,策略对象存在也不会真正拦截流量。
生产网络建议
第一,建立网络基线测试。每个集群都应有固定的连通性探测:Pod 到 Pod、Pod 到 Service、Pod 到外部、外部到 Ingress、DNS 解析、跨可用区访问。
第二,保留排障工具镜像。生产环境可以准备一个受控的 debug 镜像,包含 curl、dig、tcpdump、ss、iproute2 等工具,并通过 RBAC 限制使用权限。
第三,监控网络控制面。CNI DaemonSet、CoreDNS、Ingress Controller、kube-proxy 或替代组件都要纳入告警。
第四,重视 IP 地址容量。VPC 原生 CNI 场景下,Pod IP 可能受子网、ENI、节点规格限制。大量 Pod Pending 有时不是 CPU 不够,而是 IP 不够。
总结
K8s 网络排障的关键是路径拆解。不要一看到访问失败就重启 Ingress,也不要只盯应用日志。把请求从 DNS、入口、Service、Endpoint、Pod、容器端口逐层验证,问题通常会变得清晰。生产级网络能力不是某个 CNI 的单点选择,而是设计、监控、隔离、容量和排障流程的组合。
适用场景
适合正在处理 K8s、Kubernetes, Networking, CNI, Ingress 相关问题的团队,用于快速建立排查路径和交付标准。
问题背景
解析 K8s 网络模型、CNI、Service、DNS、Ingress 和 NetworkPolicy,并给出生产环境网络故障的排查路径。
排查步骤
先确认影响范围和最近变更,再收集日志、配置、指标和链路数据,最后按风险从低到高执行修复。
命令示例
示例命令请替换为你的真实资源名,并使用环境变量保存账号、密码、token 等敏感信息。
风险说明
生产环境操作前需要确认备份、权限边界、变更窗口和回滚路径,避免扩大故障影响。
回滚方案
保留原配置和发布版本;如修复后指标异常,立即回退配置、镜像或数据库变更并复核日志。
交付清单
问题定位记录、关键命令、修复步骤、验证结果、后续优化建议。
遇到类似技术问题?
如果你的服务器、K8s、Docker、CI/CD、数据库或监控系统出现类似问题,可以提交日志和配置文件,我们帮你远程诊断。