Kubernetes多租户网络回滚与生产验证 - 第2节

2.1 Pod 网络模型:IP-per-Pod 与扁平网络

Kubernetes 网络模型的核心原则是 “每个 Pod 拥有一个独立的 Cluster IP”,且集群内所有 Pod 可以直接通过该 IP 互相通信,无需 NAT 转换。这一设计从根本上简化了应用间的寻址与端口管理。

2.1.1 核心原则

  • IP-per-Pod:每个 Pod 被分配一个唯一的 IP 地址,Pod 内的所有容器共享该 IP 和网络命名空间(Network Namespace)。
  • 扁平网络:集群内任意两个 Pod(无论是否在同一 Node)可以直接通过 Pod IP 通信,中间不经过 NAT。
  • 端口无冲突:由于每个 Pod 拥有独立 IP,Pod 内的容器可以使用任意端口(如 80、8080),无需担心与同一 Node 上其他 Pod 的端口冲突。
设计意图: 将 Pod 视为“逻辑主机”,容器视为该主机上的进程。这种模型与虚拟机时代的网络习惯高度一致,降低了应用迁移到 K8s 的认知成本。

2.1.2 网络模型对比

特性 传统 Docker 桥接网络 Kubernetes Pod 网络
IP 分配粒度 容器级别 Pod 级别(共享 IP)
跨主机通信 需端口映射或 overlay 原生支持,扁平网络
端口冲突 同一主机上容器端口不能重复 Pod 间端口独立,无冲突
NAT 需求 通常需要 不需要(Pod 间)

2.1.3 Pod 网络通信路径

Pod 内的多个容器通过 localhost 通信(共享 Network Namespace);Pod 与 Pod 之间通过 Node 的根网络命名空间转发,最终由 CNI 插件实现跨节点连通。

关键约束: K8s 本身不实现 Pod 网络,只定义模型。具体的 IP 分配、路由、封装由 CNI 插件完成。
Pod 网络模型:IP-per-Pod 与扁平通信 Node 1 (10.0.1.0/24) Pod A IP: 10.0.1.2 容器: c1, c2 Pod B IP: 10.0.1.3 容器: c3 veth0 veth1 cbr0 (网桥) Node 2 (10.0.2.0/24) Pod C IP: 10.0.2.2 容器: c4 Pod D IP: 10.0.2.3 容器: c5 veth2 veth3 cbr1 (网桥) 直接通信 (无 NAT) Pod A (10.0.1.2) → Pod C (10.0.2.2):跨节点直接路由,CNI 插件负责底层转发

2.2 Service 与 ClusterIP:稳定的服务抽象

Pod 是“临时”的——它们可能因滚动更新、故障、扩缩容而频繁创建和销毁,IP 地址随之变化。Service 通过 ClusterIP 提供了一个稳定的虚拟 IP,作为一组 Pod 的访问入口,并实现负载均衡。

2.2.1 Service 类型与 ClusterIP 原理

Service 类型 访问范围 典型用途
ClusterIP 集群内部 内部微服务间调用
NodePort 集群外部(通过 Node IP + 端口) 开发调试、对外暴露服务
LoadBalancer 集群外部(通过云负载均衡器) 生产环境对外暴露
ExternalName DNS 映射 将外部服务映射到集群内

2.2.2 ClusterIP 数据流

  1. kube-proxy 监听 API Server 上 Service 和 Endpoint 的变化。
  2. kube-proxy 在 Node 上创建 iptables/IPVS 规则,将 ClusterIP 流量转发到后端 Pod IP。
  3. 客户端访问 ClusterIP:Port,请求被 DNAT 到某个健康的 Pod。
注意: ClusterIP 是虚拟 IP,无法 ping 通。它只存在于 iptables/IPVS 规则中,不绑定任何网络接口。

2.2.3 关键组件:kube-proxy 模式对比

模式 工作原理 性能 适用场景
userspace 用户态代理,性能差 低 已废弃
iptables 内核态 NAT 规则,随机选择后端 中等 中小规模集群(< 5000 服务)
IPVS 内核态 L4 负载均衡,支持多种调度算法 高 大规模集群(> 5000 服务)
Service ClusterIP 流量转发流程 客户端 Pod ClusterIP:80 kube-proxy iptables/IPVS DNAT 规则 Pod A (v1) 10.0.1.2:8080 Pod B (v1) 10.0.1.3:8080 Pod C (v1) 10.0.2.2:8080 客户端访问 ClusterIP:80 → kube-proxy DNAT → 随机选择一个后端 Pod 回滚时,只需更新 Service 的 selector 指向新版本 Pod 即可切换流量

2.3 CNI 插件原理:Calico 与 Flannel

CNI(Container Network Interface)是 K8s 与网络实现之间的标准接口。CNI 插件负责:分配 Pod IP、配置网络接口、建立跨节点路由。生产环境中,Calico 和 Flannel 是最广泛使用的两种方案。

2.3.1 CNI 插件工作流程

  1. kubelet 在创建 Pod 时调用 CNI 插件(通过二进制或 gRPC)。
  2. CNI 插件从 IPAM(IP Address Management)模块获取一个可用 IP。
  3. CNI 插件创建 veth pair,一端放入 Pod 网络命名空间,另一端接入主机网桥或路由表。
  4. CNI 插件配置路由规则,确保 Pod IP 在整个集群可达。

2.3.2 Flannel:简单 Overlay 网络

  • 数据面: 使用 VXLAN 或 host-gw 封装。VXLAN 模式将 Pod 流量封装在 UDP 包中,跨节点传输。
  • 控制面: 通过 etcd 或 Kubernetes API 存储子网分配信息,每个 Node 拥有一个 /24 子网。
  • 优点: 部署简单,无需额外依赖,适合中小规模集群。
  • 缺点: VXLAN 封装带来性能损耗;不支持 NetworkPolicy(需额外组件)。

2.3.3 Calico:高性能与网络策略

  • 数据面: 基于 BGP 路由协议,Pod 流量直接通过三层路由转发,无需封装(纯 L3 网络)。
  • 控制面: 每个 Node 运行 BGP 客户端(Bird),与集群内其他 Node 或 ToR 交换机交换路由。
  • 优点: 接近原生性能;原生支持 Kubernetes NetworkPolicy,实现精细化的租户隔离。
  • 缺点: 配置相对复杂;BGP 在大规模集群中可能产生较多路由条目。

2.3.4 对比总结

特性 Flannel (VXLAN) Calico (BGP)
封装方式 VXLAN (UDP 封装) 无封装 (纯路由)
性能 中等(有封装开销) 高(接近线速)
NetworkPolicy 不支持(需额外组件) 原生支持
部署复杂度 低 中
适用规模 中小规模(< 500 Node) 大规模(> 500 Node)
多租户隔离 需配合 NetworkPolicy 插件 原生支持,策略丰富
生产建议: 对于多租户隔离场景,推荐使用 Calico。其 BGP 路由模式提供高性能,且原生 NetworkPolicy 可以精确控制租户间的流量访问规则,是回滚验证中网络隔离的基础保障。
CNI 插件架构对比:Flannel (VXLAN) vs Calico (BGP) Flannel (VXLAN 模式) Node 1 Pod: 10.1.1.2 flannel.1 (VTEP) eth0: 192.168.1.1 Node 2 Pod: 10.1.2.2 flannel.1 (VTEP) eth0: 192.168.1.2 VXLAN 封装 UDP 封装,性能中等 无需 BGP,部署简单 NetworkPolicy 需额外组件 Calico (BGP 模式) Node 1 Pod: 10.2.1.2 cali0 (veth) BGP Peer: Bird Node 2 Pod: 10.2.2.2 cali0 (veth) BGP Peer: Bird BGP 路由交换 无封装,性能高 原生 NetworkPolicy 适合多租户隔离

2.4 本章小结

  • Pod 网络模型 定义了 IP-per-Pod 和扁平网络,是 K8s 网络的基础。
  • Service 与 ClusterIP 提供了稳定的服务发现和负载均衡,是回滚时流量切换的关键抽象。
  • CNI 插件 实现了 Pod 网络的具体落地:Flannel 简单易用但性能有限,Calico 高性能且原生支持 NetworkPolicy,是多租户隔离场景的首选。