IP 子网划分是每个开发者和运维工程师都绕不开的基础知识。无论是配置 AWS VPC、规划公司内网,还是排查两台主机互不通的问题,子网计算都会用到。这篇文章讲清楚 CIDR 表示法、子网掩码和网络参数的计算方法,配合在线工具可以直接得出结果。
什么是子网划分?
子网(Subnet)是对 IP 网络进行的逻辑分段。把一个大的 IP 地址块分成若干小段,好处有:
- 隔离 — 子网内的流量不出子网,跨子网流量经网关转发
- 安全 — 防火墙和 ACL 可以在子网边界执行策略
- 效率 — 缩小广播域,减少不必要的广播流量
- 地址管理 — 按需分配,避免浪费
CIDR 表示法解析
CIDR(无类别域间路由)把 IP 地址和路由前缀写在一起:
192.168.1.0/24
│ │
└─ 网络地址 └─ 前缀长度(位数)
/24 表示前 24 位是网络部分,剩余 8 位是主机部分。这决定了子网内能有多少台主机。
前缀长度与主机数对照
| CIDR | 子网掩码 | 可用主机数 | 常见用途 |
|---|---|---|---|
/8 | 255.0.0.0 | 16,777,214 | 大型 ISP 地址块 |
/16 | 255.255.0.0 | 65,534 | 企业内网 |
/24 | 255.255.255.0 | 254 | 典型办公室局域网 |
/25 | 255.255.255.128 | 126 | 把 /24 对半分 |
/26 | 255.255.255.192 | 62 | 小型网段 |
/27 | 255.255.255.224 | 30 | VLAN 网段 |
/28 | 255.255.255.240 | 14 | 小团队 |
/29 | 255.255.255.248 | 6 | 点对点链路 |
/30 | 255.255.255.252 | 2 | 路由器互联 |
/31 | 255.255.255.254 | 0(特殊) | 点对点(RFC 3021) |
/32 | 255.255.255.255 | 1 | 主机路由 |
可用主机数 = 2^(32 - 前缀长度) - 2(减去网络地址和广播地址)
关键子网参数
以 192.168.10.64/26 为例:
| 参数 | 值 | 计算方法 |
|---|---|---|
| 网络地址 | 192.168.10.64 | IP 与子网掩码做 AND 运算 |
| 子网掩码 | 255.255.255.192 | 26 个 1,6 个 0(二进制) |
| 广播地址 | 192.168.10.127 | 主机位全置 1 |
| 第一个可用主机 | 192.168.10.65 | 网络地址 + 1 |
| 最后一个可用主机 | 192.168.10.126 | 广播地址 - 1 |
| 可用主机数 | 62 | 2^6 - 2 |
| 通配符掩码 | 0.0.0.63 | 子网掩码取反 |
二进制分析
IP: 11000000.10101000.00001010.01000000 (192.168.10.64)
掩码: 11111111.11111111.11111111.11000000 (255.255.255.192)
网络: 11000000.10101000.00001010.01000000 (192.168.10.64)
广播: 11000000.10101000.00001010.01111111 (192.168.10.127)
前 26 位固定(网络部分),后 6 位变化(主机空间)。
子网划分实践
AWS VPC 设计
AWS 需要为每个 VPC 和子网指定 CIDR 块,典型三层架构:
VPC: 10.0.0.0/16 (65,536 个地址)
├─ 公有子网: 10.0.1.0/24 (254 个可用 — 面向互联网)
├─ 私有子网: 10.0.2.0/24 (254 个可用 — 应用层)
└─ 数据库: 10.0.3.0/24 (254 个可用 — RDS 隔离)
AWS 每个子网保留 5 个地址(前 4 个 + 广播),每个 /24 实际可用 251 个。
Kubernetes Pod CIDR
K8s 集群要求节点、Pod 和 Service 的 CIDR 不重叠:
# kubeadm 配置片段
networking:
podSubnet: 10.244.0.0/16 # Pod IP
serviceSubnet: 10.96.0.0/12 # ClusterIP Service
确保这些地址段不与节点网络或 VPC CIDR 重叠。
Docker 自定义网络
# 创建自定义 bridge 网络
docker network create \
--driver bridge \
--subnet 172.20.0.0/24 \
--gateway 172.20.0.1 \
my-network
用 docker network ls 和 ip route 检查是否与现有网络重叠。
代码计算子网参数
Python ipaddress 模块
Python 标准库已内置完整子网计算功能:
import ipaddress
net = ipaddress.IPv4Network('192.168.10.64/26', strict=False)
print(net.network_address) # 192.168.10.64
print(net.broadcast_address) # 192.168.10.127
print(net.netmask) # 255.255.255.192
print(net.num_addresses) # 64(含网络和广播地址)
print(list(net.hosts())[:3]) # [192.168.10.65, .66, .67]
# 检查 IP 是否在子网内
ip = ipaddress.IPv4Address('192.168.10.80')
print(ip in net) # True
# 划分为 /28 子网
for subnet in net.subnets(new_prefix=28):
print(subnet)
# 192.168.10.64/28
# 192.168.10.80/28
# 192.168.10.96/28
# 192.168.10.112/28
JavaScript
// 不依赖第三方库的简单实现
function subnetInfo(cidr) {
const [ip, prefix] = cidr.split('/');
const prefixLen = parseInt(prefix);
const ipParts = ip.split('.').map(Number);
const ipInt = ipParts.reduce((acc, oct) => (acc << 8) | oct, 0) >>> 0;
const maskInt = prefixLen === 0 ? 0 : (~0 << (32 - prefixLen)) >>> 0;
const networkInt = (ipInt & maskInt) >>> 0;
const broadcastInt = (networkInt | ~maskInt) >>> 0;
const toIP = n => [24, 16, 8, 0].map(s => (n >> s) & 0xFF).join('.');
return {
network: toIP(networkInt),
broadcast: toIP(broadcastInt),
mask: toIP(maskInt),
firstHost: toIP(networkInt + 1),
lastHost: toIP(broadcastInt - 1),
usableHosts: Math.pow(2, 32 - prefixLen) - 2,
};
}
console.log(subnetInfo('192.168.10.64/26'));
// { network: '192.168.10.64', broadcast: '192.168.10.127', ... }
Go net 包
import "net"
_, ipNet, err := net.ParseCIDR("192.168.10.64/26")
if err != nil {
panic(err)
}
fmt.Println(ipNet.IP) // 192.168.10.64(网络地址)
fmt.Println(ipNet.Mask) // ffffffc0(十六进制掩码)
// 检查 IP 是否在子网内
testIP := net.ParseIP("192.168.10.80")
fmt.Println(ipNet.Contains(testIP)) // true
私有 IP 地址范围
这些范围保留给内部使用(RFC 1918):
| 范围 | CIDR | 地址数量 |
|---|---|---|
| 10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | 约 1,677 万 |
| 172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | 约 104 万 |
| 192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | 65,536 |
内部基础设施始终用私有地址段。公有 IP 在互联网上路由,私有 IP 不会。
常见子网计算错误
忘记保留地址:每个子网损失 2 个地址(网络地址 + 广播地址)。一个 /29 共 8 个地址,只有 6 个可用。
子网地址重叠:10.0.1.0/24 和 10.0.0.0/16 重叠——/24 里的每个地址也属于 /16,导致路由歧义。
主机范围差一:第一个可用主机是网络地址 +1,最后一个是广播地址 -1。/24 的主机范围是 .1 到 .254,而非 .0 到 .255。
CIDR 对齐:子网起始地址必须对齐到前缀长度对应的边界。10.0.0.1/24 不是合法 CIDR(主机位非零),正确写法是 10.0.0.0/24。
使用在线 IP 子网计算器
输入任意 IPv4 地址和 CIDR 前缀长度,立即获得:
- 网络地址和广播地址
- 子网掩码和通配符掩码
- 第一个和最后一个可用主机地址
- 总地址数和可用主机数
- 所有字段的二进制表示
免注册,无广告,浏览器本地运算。适合 VPC 规划、网络排障和架构评审时快速确认子网参数。