NNetpath
原理入门预计 25 分钟

K8s 网络模型:四条铁律

K8s 不实现网络,它只规定了几条必须满足的约束。理解约束,才能理解各家 CNI 的取舍。

学完这节你能做到

  • 复述 K8s 网络模型的强制约束,并解释它为什么排除了端口映射方案
  • 区分 Pod CIDR、Service CIDR、节点网段三套地址
  • 判断一个网络需求该由 CNI、Service 还是 Ingress 来满足

K8s 其实没有实现网络

这是理解容器网络最重要的一句话:Kubernetes 本身不提供网络实现,它只规定了一份必须满足的约束, 剩下的交给 CNI 插件。所以"K8s 网络怎么工作"这个问题没有统一答案,取决于你装了哪个 CNI。

但约束是统一的,而且只有四条。把这四条记住,各家 CNI 的取舍就都能看懂了。

四条铁律

  1. 每个 Pod 有自己独立的 IP,不和宿主机共享端口空间
  2. Pod 之间可以直接用这个 IP 互通,中间不做 NAT
  3. 节点上的进程(比如 kubelet)能直接访问本节点的 Pod
  4. Pod 自己看到的 IP,和别人看到它的 IP 是同一个

第二条和第四条是真正的分水岭。它们直接排除了 Docker 时代的端口映射方案: 一旦做了 NAT,对端看到的源地址就变成了节点 IP,第四条立刻违反。

i为什么这条约束这么重要

分布式系统里到处都是"把自己的地址注册到注册中心"这种模式 —— Ceph 的 OSD、Kafka 的 broker、 各种 RPC 框架都这么干。如果 Pod 看到的自己和别人看到的它不一致,注册进去的地址就是错的。 免 NAT 不是为了性能,是为了让应用不需要感知自己跑在容器里

三套地址,谁都不能重叠

这是新集群规划时最容易埋雷的地方:

地址空间分配给谁谁来管能不能改
节点网段物理机 / 虚机机房网络组改动代价大
Pod CIDR每个 Pod 一个 IPCNI(如 Cilium 的 IPAM)只能追加新段
Service CIDRClusterIP 这类虚拟地址kube-apiserver 启动参数基本改不了

三者互相重叠会出现极其难查的问题:包被路由到错误的地方,而且报错信息毫无指向性。 规划时还要额外确认不能和机房里其它网段冲突,包括 VPN 段和对端机房段。

Pod CIDR 的容量账

Pod CIDR 不是"够用就行",它按节点切块分配。以 Cilium 的 cluster-pool 模式为例, 每个节点从大池子里领一小段(比如 /24):

Pod CIDR = 10.244.0.0/16      → 可切出 256 个 /24
每节点一段 /24                 → 每节点最多 254 个 Pod
                              → 集群最多 256 个节点

节点数上限被地址段写死了。 一旦用尽,新节点上的 Pod 会一直 ContainerCreating, 而错误信息藏在 CNI 日志里,第一次遇到的人通常要查很久。

×Pod CIDR 用尽了只能追加,不能改

Cilium 的处理方式是在 ipam.operator.clusterPoolIPv4PodCIDRList新增一个地址段,然后重启 operator:

kubectl rollout restart deployment/cilium-operator -n kube-system

不能修改已有的地址段 —— 已分配出去的 Pod IP 还在用。所以规划时宁可划大: /16/12 的成本一样是零,但事后补救的成本很高。

东西向与南北向

两个方向的流量由完全不同的组件负责,排障时先分清是哪个方向:

                    ┌─────────── 南北向 ───────────┐
                    │                              │
   集群外客户端 ──► LoadBalancer / Ingress ──► Service ──► Pod
                                                    │
                    Pod ◄──── 东西向(CNI) ────► Pod
需求由谁满足典型实现
Pod 到 Pod 互通CNICilium、Kube-OVN
一组 Pod 的稳定访问入口Servicekube-proxy 或 eBPF 替换
集群外访问(L4)LoadBalancerMetalLB(裸金属)、云 LB
集群外访问(L7)Ingress / GatewayIngress Nginx、Istio
服务发现DNSCoreDNS
Pod 间访问控制NetworkPolicyCilium
Pod 直连物理网次级 CNIMultus / Spiderpool + MacVLAN / SR-IOV

这张表的用法是反向查:拿到一个需求,先确定它该由哪一层解决, 再去看那一层的配置和日志。绝大部分"K8s 网络问题"排查走偏,都是因为在错误的层里找原因。

次级 CNI 是什么时候需要的

默认 CNI 给的那张网卡走的是软件转发路径,对普通业务足够。但两类场景需要 Pod 直连物理网:

  • AI 训练:要用 RDMA 网卡做 GPU 之间的高速通信(L2 会详细讲)
  • 虚拟机:KubeVirt 里的虚机需要二层网络语义,通常挂 Kube-OVN 作为次级 CNI

这时候给 Pod 插第二张网卡,业务流量走默认 CNI,高性能流量走次级网卡。

检查点

检查点单选

K8s 网络模型为什么明确要求 Pod 之间通信不做 NAT?

检查点单选

集群规划时 Pod CIDR 给了 /22,每节点分配 /24。这个集群最多能有几个节点?

检查点多选

下面哪些需求应该由 CNI 而不是 Service 来满足?(多选)

这节课的落点

  • K8s 不实现网络,只规定四条约束:独立 IP、免 NAT 互通、节点可达、IP 视角一致
  • 免 NAT 是为了语义一致,不是为了性能
  • 三套地址(节点网、Pod CIDR、Service CIDR)互不重叠,且都要避开机房其它网段
  • Pod CIDR 的大小直接锁死节点数上限,只能追加不能修改,规划时宁可划大
  • 拿到需求先判断该由哪一层解决:CNI / Service / Ingress / DNS / NetworkPolicy / 次级 CNI

延伸资料