【架构实战】Kubernetes网络模型深度剖析:从Pod通信到Service流量转发
【架构实战】Kubernetes网络模型深度剖析:从Pod通信到Service流量转发
当我们把应用搬上 Kubernetes,最先被劝退的往往是网络。为什么 Pod 之间能直接互通?Service 的 ClusterIP 到底是个啥?kube-proxy 在背后干了什么?Ingress 又是怎么把流量导进来的?这一篇把 Kubernetes 的网络模型拆开揉碎,从底层原理到生产实践一次讲透。
一、K8s 网络的三大前提假设
Kubernetes 网络模型建立在三个"理所当然"的假设之上,理解它们就理解了一半:
- Pod 拥有的 IP 全局可达:任意节点上的任意 Pod,都可以不经由 NAT 直接访问其他任意节点上的任意 Pod。
- 节点上的代理(如 kubelet)可以访问同节点的 Pod:哪怕跨网络平面也行。
- Pod 视角的自己 IP == 别人看到的 IP:Pod 内部
curl自己,和集群里别人curl它,IP 是一致的,没有"内部地址 / 外部地址"的分裂。
这三条合在一起,就是著名的"IP-per-Pod"模型。每个 Pod 拿到一个真实可用的 IP,应用不用关心自己在哪个节点,像活在同一个大二层网络里。
二、Pod 网络是怎么打通的:CNI 与 overlay
Pod 之间能互通,靠的是CNI(Container Network Interface)。kubelet 创建 Pod 时,会调用 CNI 插件给 Pod 的网卡分配 IP、配置路由、把 veth 插进节点的网桥。
实现方式分两派:
- Underlay(路由方案):如 Calico(BGP 模式)、直接用底层网络路由 Pod CIDR。性能最好,延迟接近物理网络,但需要底层网络配合(或 BGP 打通)。
- Overlay(隧道方案):如 Flannel(VXLAN)、Calico(IPIP)、Cilium(VXLAN / Geneve)。在节点间建隧道封装,对底层无要求,代价是封装/解封装的 CPU 开销和一点点延迟。
选型建议:节点都在同二层或能跑 BGP,优先 Calico 路由模式;云上跨 VPC 或无法改路由,用 overlay。生产环境我更推荐Cilium——基于 eBPF,既能做网络又能做可观测性和安全策略,性能还吊打 iptables 方案。
三、Service:给一组 Pod 一个稳定入口
Pod 是会漂移、会重建的,IP 随时变。Service 干的事就是"给一组动态 Pod 一个固定虚拟 IP(ClusterIP)"。
流量路径是这样的:
- 客户端访问
Service ClusterIP:Port; - 内核根据 iptables/IPVS 规则,把目标 IP 改写成某个后端 Pod 的真实 IP(DNAT);
- 请求被转发到被选中的 Pod。
kube-proxy 的三种模式:
- userspace(已淘汰):慢,每次转发走一遍用户态。
- iptables:默认模式,靠链式规则做 DNAT。规则一多万条时,新增/更新 Service 会抖动,且转发是纯随机/O 哈希。
- IPVS:基于内核哈希表,转发性能稳定,支持轮询、最少连接等多种负载均衡算法,大规模集群首选。
实践上,超过几百个 Service 就建议切 IPVS:kube-proxy --proxy-mode=ipvs。
四、DNS 与 Service 发现
集群里服务之间很少记 IP,都是记名字。CoreDNS把service.namespace.svc.cluster.local解析成 ClusterIP。注意两个坑:
- DNS 解析有缓存:Pod 内的 ndots 配置可能导致短域名(如只写
service)被错误地追加搜索域,造成多余的 DNS 查询甚至解析失败。微服务调用链长时,DNS 抖动会放大成连锁超时。 - headless Service(
clusterIP: None)不做负载均衡,DNS 直接返回所有后端 Pod IP,适合有状态服务(如数据库集群)自己做选主。
五、Ingress:把外部流量引进来
Service 的 ClusterIP 只在集群内可达。要把流量从公网导进来,靠Ingress。它本质是一个七层(HTTP/HTTPS)路由规则:根据域名、路径把请求转发到对应的 Service。
背后跑着一个Ingress Controller(本质是监听 Ingress 对象的 Pod,典型如 Nginx Ingress、Traefik、APISIX)。它把规则翻译成自身的转发配置。对比一下:
- Nginx Ingress:生态成熟、稳,但配置 reload 有延迟;
- APISIX / Traefik:动态配置、支持插件化鉴权限流,更适合云原生网关场景;
- 四层(TCP/UDP)流量则要用LoadBalancer 类型的 Service或
type: NodePort。
生产建议:Ingress Controller 前置一个云 LB 或 L4 负载,再做 TLS termination,证书用 cert-manager 自动续期,别再手动换证书了。
六、网络策略与可观测性
网络通了,还得管"谁能访问谁"。NetworkPolicy用标签声明 Pod 间的访问白名单,默认是"放行一切",配了策略后变成"默认拒绝"。注意:它依赖 CNI 插件支持(Calico、Cilium 都支持,Flannel 默认不支持)。
出了问题怎么查?几个黄金命令:
kubectl get pods-owide# 看 Pod IP 和所在节点kubectlexec-it<pod>--curl-I<svc># 验证服务连通kubectl port-forward<pod>8080:80# 本地转发调试更进阶的,用 Cilium 的cilium monitor或 Hubble 直接看每个请求的转发路径、丢包原因,比抓包省事十倍。
七、小结
Kubernetes 网络看着吓人,其实就三层:
- Pod 网络(CNI)解决"Pod 之间怎么通";
- Service + kube-proxy解决"Pod 漂移了怎么稳定访问";
- Ingress解决"外面流量怎么进来"。
记住一句话:网络问题 80% 是 DNS 和 iptables 规则,剩下 20% 才是 CNI 本身。把这三层模型刻进脑子里,再复杂的网络故障你也能顺着流量路径一路定位到底。
下一篇预告:Kubernetes 安全加固——从 RBAC 到 Pod Security Standards 的实战落地。