地址与 VLAN 规划:给集群划地盘
地址规划是一次性决定、长期后悔的事。Pod CIDR 划小了以后加不了节点。
学完这节你能做到
- 按节点数与单节点 Pod 数上限反推 Pod CIDR 大小
- 规划节点网、Service CIDR、LB 地址池不重叠
- 给出一份可交给网络组执行的 VLAN 与网段表
建议先学
跳过这几节会看不懂本节的部分推导
一次性决定,长期后悔
地址规划的特点是错了几乎改不回来:
| 项 | 能改吗 |
|---|---|
| 节点网段 | 能,但要停机改配置 |
| Pod CIDR | 只能追加新段,已有段不能改 |
| Service CIDR | 基本改不了,要改就是重建集群 |
| LB 地址池 | 能追加 |
| VLAN 划分 | 能改,但涉及交换机配置变更 |
所以这一节的核心不是"怎么算",而是怎么一次算够。
五套地址,互不重叠
K8s 网络模型 讲了三套,加上 LB 池和带外网,实际是五套:
| 地址空间 | 谁用 | 谁分配 | 典型大小 |
|---|---|---|---|
| 节点网 | 物理机 / 虚机 | 机房网络组 | /24 每机架 |
| Pod CIDR | 每个 Pod 一个 IP | CNI 的 IPAM | /16 |
| Service CIDR | ClusterIP | apiserver 启动参数 | /12 或 /16 |
| LB 地址池 | LoadBalancer VIP | 机房网络组(必须可路由) | 十几个地址 |
| 带外网 | BMC、交换机管理口、PDU | 机房网络组 | /24 |
五套之间任意两套重叠都会出现极难排查的问题:包被路由到错误的地方, 而且报错信息毫无指向性。
除此之外还要避开:
- 机房里其它系统已用的网段
- VPN 网段(办公网连过来的地址)
- 对端机房网段(如果有专线互联)
- 云上 VPC 网段(如果有混合云)
- Docker 默认的
172.17.0.0/16(这个特别容易撞)
症状:在公司办公网里一切正常,在家连 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 | /18 | 254 |
| 256 | /24 | /16 | 254 |
| 512 | /25 | /16 | 126 |
| 1024 | /24 | /14 | 254 |
| 2048 | /25 | /14 | 126 |
实践建议:直接给 /16。 理由很简单——地址预留是零成本的,
而事后追加段会带来路由与 ACL 的复杂度。
/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 数上限 | 评价 |
|---|---|---|
/24 | 254 | 太小,中型集群就不够 |
/16 | 65534 | 够用 |
/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 服务
三条要求:
- 可路由——客户端要能访问到它
- L2 模式下必须与节点同二层(gARP 是广播)
- 数量按 LoadBalancer 类型的 Service 数算
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/22 | RoCE 场景要配 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 预留给新增机架
最后两块——已避开的网段和预留——是这份表和"随手写的网段列表"的区别。
检查点
集群要支持最多 300 个节点,每节点分 /24。Pod CIDR 至少要多大?
Pod CIDR 每节点分 /24(254 个地址),但 kubectl 显示节点只能跑 110 个 Pod。为什么?
在家连 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-action
network/cilium/README.md - k8s-in-action
network/metallb/default-pool.yaml