Netpath
学习路径40 / 49 · K8s 网络看全程 →
原理预计 30 分钟

地址与 VLAN 规划:给集群划地盘

地址规划是一次性决定、长期后悔的事。Pod CIDR 划小了以后加不了节点。

学完这节你能做到

  • 按节点数与单节点 Pod 数上限反推 Pod CIDR 大小
  • 规划节点网、Service CIDR、LB 地址池不重叠
  • 给出一份可交给网络组执行的 VLAN 与网段表

建议先学

跳过这几节会看不懂本节的部分推导

一次性决定,长期后悔

地址规划的特点是错了几乎改不回来:

项能改吗
节点网段能,但要停机改配置
Pod CIDR只能追加新段,已有段不能改
Service CIDR基本改不了,要改就是重建集群
LB 地址池能追加
VLAN 划分能改,但涉及交换机配置变更

所以这一节的核心不是"怎么算",而是怎么一次算够。

五套地址,互不重叠

K8s 网络模型 讲了三套,加上 LB 池和带外网,实际是五套:

地址空间谁用谁分配典型大小
节点网物理机 / 虚机机房网络组/24 每机架
Pod CIDR每个 Pod 一个 IPCNI 的 IPAM/16
Service CIDRClusterIPapiserver 启动参数/12 或 /16
LB 地址池LoadBalancer VIP机房网络组(必须可路由)十几个地址
带外网BMC、交换机管理口、PDU机房网络组/24

五套之间任意两套重叠都会出现极难排查的问题:包被路由到错误的地方, 而且报错信息毫无指向性。

除此之外还要避开:

  • 机房里其它系统已用的网段
  • VPN 网段(办公网连过来的地址)
  • 对端机房网段(如果有专线互联)
  • 云上 VPC 网段(如果有混合云)
  • Docker 默认的 172.17.0.0/16(这个特别容易撞)
×和 VPN 网段撞车:最隐蔽的一种

症状:在公司办公网里一切正常,在家连 VPN 之后某些服务访问不了。

原因是 VPN 下发的路由和集群某个网段重叠,客户端把本该走 VPN 的流量发给了集群, 或者反过来。

规划时的动作很简单但常被跳过:跟负责 VPN 的人要一份现有路由表, 把所有已用网段列出来再选。事后发现只能改一边,而 Service CIDR 是改不了的那一边。

Pod CIDR:反推法

Pod CIDR 的大小直接锁死节点数上限,因为它按节点切块分配。

Pod CIDR 总大小 ÷ 每节点块大小 = 节点数上限
每节点块大小 − 2 = 单节点 Pod 数上限

以 Cilium 的 cluster-pool 模式为例:

ipam:
  operator:
    clusterPoolIPv4PodCIDRList: ["10.244.0.0/16"]
    clusterPoolIPv4MaskSize: 24
10.244.0.0/16 切成 /24  →  256 个块  →  最多 256 个节点
每块 /24 = 254 个可用地址 →  单节点最多 254 个 Pod

反推表

先定"节点数上限"和"单节点 Pod 数",再选 CIDR:

目标节点数每节点块需要的 Pod CIDR单节点 Pod 上限
64/24/18254
256/24/16254
512/25/16126
1024/24/14254
2048/25/14126

实践建议:直接给 /16。 理由很简单——地址预留是零成本的, 而事后追加段会带来路由与 ACL 的复杂度。

!单节点 Pod 数还受 kubelet 限制

/24 给了 254 个地址,但 kubelet 的 maxPods 默认是 110。 两个限制取较小值,所以实际上限是 110。

反过来说:如果你把 maxPods 调到 250(大内存节点上常见), 那每节点块就必须是 /24 而不是 /25——否则 IP 先用完。

两个数字要一起定:

kubectl get node <node> -o jsonpath='{.status.allocatable.pods}'
kubectl get node <node> -o jsonpath='{.spec.podCIDR}'

用尽之后怎么办

只能追加新段,不能改已有的:

clusterPoolIPv4PodCIDRList:
  - "10.244.0.0/16"        # 原有,不能动
  - "10.245.0.0/16"        # 追加
kubectl rollout restart deployment/cilium-operator -n kube-system

代价是:两段不连续,物理网络上的路由与 ACL 都要各加一条, 监控与文档也要跟着改。这就是"宁可一开始划大"的理由。

Service CIDR:够用就好,但改不了

ClusterIP 从这里分配。它不需要很大——一个集群有几千个 Service 就算多了。 但它是 apiserver 的启动参数,改它等于重建集群。

--service-cluster-ip-range=10.96.0.0/12
大小Service 数上限评价
/24254太小,中型集群就不够
/1665534够用
/12一百多万常见默认,一劳永逸

建议直接 /12。它占的是私有地址空间,不值钱;而改不了这件事很值钱。

# 查当前配置
kubectl cluster-info dump | grep -m1 service-cluster-ip-range
# 或者从 kube-apiserver 的启动参数看
ps -ef | grep kube-apiserver | tr ' ' '\n' | grep service-cluster

LB 地址池:必须可路由

这是唯一一个必须由机房网络组分配的段(MetalLB 那节 讲过):

spec:
  addresses:
    - 172.18.15.200-172.18.15.210      # 11 个地址 = 11 个 LoadBalancer 服务

三条要求:

  1. 可路由——客户端要能访问到它
  2. L2 模式下必须与节点同二层(gARP 是广播)
  3. 数量按 LoadBalancer 类型的 Service 数算
✓用 Ingress 把 LB 地址需求压到最小

50 个 HTTP 服务不需要 50 个 VIP。给 Ingress 控制器一到两个 VIP, 其余服务靠域名区分(Ingress 那节 讲过)。

真正需要独立 VIP 的只有:非 HTTP 协议的服务(数据库、Kafka、游戏服务器)、 以及需要独立源 IP 或独立端口的服务。

按这个原则,一个中型集群的 LB 池 十几个地址通常就够。

VLAN 与网段的对应

VLAN 划分的原则是按故障域和安全域切,而不是按部门切:

VLAN用途网段说明
10节点业务网10.0.10.0/24每机架一个 VLAN 也可以
20存储网10.0.20.0/24与业务网隔离,恢复流量不影响业务
30带内管理10.0.30.0/24集群管理服务
40计算网10.104.20.0/22RoCE 场景要配 DSCP/PCP 映射
99带外(BMC)10.0.99.0/24物理隔离,不与业务网互通

两个要点:

  • 广播域别做太大。一个 /24(254 台)是舒适上限;再大 ARP 广播会成为负担 (二层与三层 讲过)。
  • 带外网真正物理隔离。它的价值就在业务网挂了的时候,共用设备等于没有。

一份可交付的地址表

产出应该长这样,直接能交给网络组执行:

【节点网】
  机架 A   10.0.10.0/24    网关 10.0.10.1    VLAN 10   预留 .1-.9 给设备
  机架 B   10.0.11.0/24    网关 10.0.11.1    VLAN 11
【存储网】
  10.0.20.0/24             VLAN 20           存储侧 .10-.50,节点侧 .100-.200
【计算网(RoCE)】
  10.104.20.0/22           VLAN 40           每节点 8 个地址,按 rail 顺序分配
【带外网】
  10.0.99.0/24             VLAN 99           物理隔离,不配路由到业务网
【K8s】
  Pod CIDR       10.244.0.0/16   每节点 /24,上限 256 节点,maxPods=110
  Service CIDR   10.96.0.0/12    不可变更
  LB 池          172.18.15.200-210(机房分配,可路由,与节点同二层)
【已避开的网段】
  172.17.0.0/16(Docker 默认)  10.8.0.0/24(VPN)  10.20.0.0/16(对端机房)
【预留】
  10.245.0.0/16 预留给 Pod CIDR 扩容
  10.0.12.0/24 - 10.0.19.0/24 预留给新增机架

最后两块——已避开的网段和预留——是这份表和"随手写的网段列表"的区别。

检查点

Checkpoint单选

集群要支持最多 300 个节点,每节点分 /24。Pod CIDR 至少要多大?

Checkpoint单选

Pod CIDR 每节点分 /24(254 个地址),但 kubectl 显示节点只能跑 110 个 Pod。为什么?

Checkpoint单选

在家连 VPN 后某些集群服务访问不了,在公司网正常。最可能的原因?

这节课的落点

  • 地址规划的特点是一次性决定:Pod CIDR 只能追加,Service CIDR 基本改不了
  • 五套地址互不重叠:节点网、Pod CIDR、Service CIDR、LB 池、带外网
  • 还要避开:机房已用段、VPN 段、对端机房、云上 VPC、Docker 默认 172.17.0.0/16
  • Pod CIDR 用反推法:总大小 ÷ 每节点块 = 节点上限;建议直接给 /16 或更大
  • maxPods 与每节点块大小要一起定,两者取较小值
  • Service CIDR 建议直接 /12——它不值钱,但改不了这件事很值钱
  • LB 池必须机房分配、可路由、L2 模式下同二层;用 Ingress 把需求压到十几个地址
  • VLAN 按故障域和安全域切;单个广播域 /24 是舒适上限;带外网必须物理隔离
  • 交付的地址表要包含已避开的网段与预留段,这是它和随手记录的区别

延伸资料

  • k8s-in-actionnetwork/cilium/README.md
  • k8s-in-actionnetwork/metallb/default-pool.yaml