IP
IP 地址在系统设计里的三个实际问题:CIDR 怎么切子网、私网地址怎么经 NAT 出公网、VPC 子网为什么经常不够用。含 RFC 1918 私网段、AWS 每子网保留 5 个地址、NAT 网关 55,000 并发连接上限、公网 IPv4 计费和 IPv6 的算例与翻车表。
IP address 是用来标识 device 在 internet 或 local network 上的地址。IP 是 “Internet Protocol”,是一套规则,规定 data 在 internet / local network 上传输的格式(IPv4 见 RFC 791,IPv6 见 RFC 8200)。
在系统设计里,IP 很少作为独立题目出现,但它决定三件事:一个网络能放下多少台机器和容器、内网服务怎么访问公网和被公网访问、地址不够时从哪里扩。 这些问题在 VPC 规划和 Kubernetes 集群扩容时一定会遇到。
有约束的设计问题
在 AWS 上给一个 SaaS 后端规划网络,要求如下:
- 跨 3 个可用区(AZ),每个 AZ 有公网入口(负载均衡器)和私有应用层。
- 应用跑在 EKS 上,高峰约 3,000 个 Pod,每个 Pod 都要一个 VPC 地址(假设使用 AWS VPC CNI 的默认模式)。
- 数据库和缓存不能有公网地址。
- 私有子网里的服务要调第三方支付 API。
- 将来要和公司办公网(
10.0.0.0/16)打通。
后文每一节都回到这五条。
Versions
IPv4
最早的 Internet Protocol 是 IPv4,使用 32-bit 地址,写成点分十进制,总量 2^32 ≈ 43 亿。早期够用,但随着 internet adoption 增长就不够了,这也是后面 NAT 和私网地址普及的原因。
Example: 102.22.192.181
IPv6
IPv6 是 1998 年发布的新协议(RFC 2460,现行版本是 RFC 8200),2000 年代中期开始部署,至今仍在推进。
IPv6 使用 128-bit 地址,写成 8 组十六进制,总量 2^128 ≈ 3.4 × 10^38。连续的全零组可以用 :: 缩写一次。
Example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334,缩写为 2001:db8:85a3::8a2e:370:7334
CIDR:一个网段有多少地址
CIDR(RFC 4632)用「地址/前缀长度」表示一个网段,前缀之后的位可自由分配:
| CIDR | 可变位 | 地址总数 | AWS 子网可用数(减 5) |
|---|---|---|---|
/16 | 16 | 65,536 | 65,531 |
/20 | 12 | 4,096 | 4,091 |
/24 | 8 | 256 | 251 |
/28 | 4 | 16 | 11 |
AWS 文档规定:IPv4 子网大小在 /28 到 /16 之间,每个子网的前 4 个和最后 1 个地址保留,不能分给任何资源。以 10.0.0.0/24 为例,.0 是网络地址,.1 给 VPC 路由器,.2 给 DNS,.3 预留,.255 是广播地址。小子网被这 5 个吃掉的比例很高:/28 只剩 11 个。
Types
Public 与 Private
Public IP 在公网上唯一、可路由,由 ISP 或云厂商分配。
Private IP 只在内网有效,RFC 1918 预留了三段:
10.0.0.0/8172.16.0.0/12192.168.0.0/16
公网路由器不转发这些地址,所以不同公司可以重复使用同一段。另外 RFC 6598 预留了 100.64.0.0/10 给运营商级 NAT(CGNAT),在云上有时被用来扩 Pod 地址。
Example: 家用 router 从 ISP 拿到一个 public IP,给家里的电脑、手机分配 192.168.x.x 的 private IP。家里所有设备对外看起来都是同一个 public IP。
Static 与 Dynamic
Static IP 不会变化,手动配置或长期保留。服务端入口、对方要把你加进 IP 白名单的出口,都需要固定地址。在 AWS 上对应 Elastic IP。
Dynamic IP 会变化,由 DHCP server(RFC 2131)按租期分配。它是最常见的类型,方便在网络内复用地址,消费级宽带和普通云主机的默认公网地址通常都是动态的。
NAT:私网地址怎么访问公网
NAT(RFC 3022)把内网包的源地址改写成自己的公网地址,并记住映射,回包时再改回去。多台机器共用一个公网 IP 时还要改写源端口,所以一个公网 IP 对同一个目标能同时承载的连接数受端口数限制。
AWS NAT 网关的文档给出了具体上限:每个 IPv4 地址对每个唯一目标(目标 IP + 目标端口 + 协议)最多 55,000 个并发连接,一个 NAT 网关最多可关联 8 个 IPv4 地址来提高这个上限。
算一下场景第 4 条。假设支付 API 只有一个入口 IP:443,高峰 3,000 个 Pod 各自维持 20 条连接,就是 60,000 条,超过单个地址的 55,000,会出现连接失败(NAT 网关的 CloudWatch 指标里 ErrorPortAllocation 会增长)。修法:Pod 侧用连接池降低连接数;给 NAT 网关加辅助 IP;或按 AZ 拆多个 NAT 网关。
NAT 的另一个用途是给出口一个固定 IP:第三方要求 IP 白名单时,把 NAT 网关的 Elastic IP 报给对方,不管后面的 Pod 怎么扩缩、IP 怎么变,出口不变。
回到场景:子网规划
一个可行的规划(数字按上文 CIDR 表计算):
VPC: 10.1.0.0/16 # 避开办公网 10.0.0.0/16
├── 公有子网 x3 /24 每个 251 可用 # ALB、NAT 网关
├── 应用子网 x3 /19 每个 8,187 可用 # EKS 节点和 Pod
└── 数据子网 x3 /24 每个 251 可用 # RDS、ElastiCache,无公网路由
- 3,000 个 Pod 放得下吗:3 个
/19共约 24,500 个地址,按 AZ 平均 1,000 个 Pod 加节点自身地址,余量充足。VPC CNI 默认会给每个节点预留一整块 ENI 的空闲 IP 作为 warm pool,实际占用高于 Pod 数;如果只给/24(251 个),节点一多地址很快耗尽,新 Pod 起不来、事件里报分配不到 IP。 - 数据库无公网:数据子网的路由表里没有指向 Internet Gateway 的路由。
- 不与办公网冲突:两边都用
10.0.0.0/16的话,打通后路由不知道同一个地址该去哪边,只能 NAT 或重建 VPC。地址不够可以给 VPC 追加辅助 CIDR,但已经和别人重叠的网段靠追加解决不了,所以网段冲突要在第一天规划时避开。
IPv6 在这里能解决什么
IPv6 地址多到不必省:AWS 的 IPv6 子网前缀在 /44 到 /64 之间,最小的 /64 也有 2^64 个地址,EKS 最佳实践文档把 IPv6 列为解决 Pod IP 耗尽的首选办法。代价是依赖和客户端必须支持 IPv6,只支持 IPv4 的第三方 API 仍要经过 NAT64 之类的转换。另一个现实动力是费用:AWS 对公网 IPv4 地址按 $0.005/小时收费(使用中和闲置的都收),一个地址一个月约 0.005 × 730 = $3.65,大量实例各带公网 IP 时这笔钱不可忽略。
常见翻车
| 翻车 | 现象 | 修法 |
|---|---|---|
| 应用子网切得太小 | 扩容时 Pod 卡在 ContainerCreating,报分配不到 IP | 按峰值 Pod 数的数倍规划;追加辅助 CIDR;考虑 IPv6 |
| VPC 与办公网 / 其他 VPC 网段重叠 | 打通 VPN 或 peering 后部分地址不可达 | 公司级统一分配网段,建 VPC 前查登记表 |
| 所有 Pod 经一个 NAT IP 打同一个外部 API | 高峰连接失败,ErrorPortAllocation 增长 | 连接池;NAT 网关加 IP;按 AZ 拆 NAT 网关 |
| 服务直接用公网 IP 互相调用 | 流量绕出公网,多付 NAT 和数据传输费 | 内网调用走私有地址或内部负载均衡 |
| 把 DHCP 分配的动态 IP 写进配置 | 实例重启后换 IP,调用方全部失败 | 用 DNS 名或 Elastic IP,不写死地址 |
面试时这样回答
- 复述约束:几个 AZ、峰值多少实例或 Pod、哪些层不能有公网地址、要不要和别的网络打通。
- 给网段:VPC
/16,公有 / 应用 / 数据三层子网,每层每 AZ 一个;说明应用子网因为 Pod 占 IP 要切大。 - 说出口:私有子网经 NAT 网关出公网,NAT 的 Elastic IP 就是给第三方白名单的固定出口。
- 说一个上限:NAT 每个地址对同一目标 55,000 并发连接,超过要加地址或做连接池。
- 说一个长期问题:网段不能和办公网重叠;地址不够时追加 CIDR 或转 IPv6。
相关章节:OSI Model、TCP 与 UDP、DNS、Proxy vs Reverse Proxy、Load Balancer、N-tier architecture。
一手证据
- RFC 791:Internet Protocol
- RFC 8200:IPv6 Specification
- RFC 4632:CIDR
- RFC 1918:Address Allocation for Private Internets
- RFC 6598:Shared Address Space (100.64.0.0/10)
- RFC 3022:Traditional NAT
- RFC 2131:DHCP
- AWS VPC:Subnet sizing
- AWS VPC:VPC CIDR blocks
- AWS VPC:NAT gateway basics
- AWS VPC:NAT gateway CloudWatch metrics(
ErrorPortAllocation) - AWS VPC pricing(Public IPv4 address)
- Amazon EKS:Amazon VPC CNI
- Amazon EKS Best Practices:Optimizing IP Address Utilization