子网和路由设计
深入学习如何规划和配置 VPC 的子网、路由表以及网络流量控制。
子网规划策略
子网类型详解
公有子网(Public Subnet):
特征:
├─ 路由表包含指向 Internet Gateway 的路由
├─ 实例可以分配公网 IP
├─ 可以直接访问 Internet
└─ Internet 可以主动访问(如果安全组允许)
典型路由表:
目的地 目标
10.0.0.0/16 local
0.0.0.0/0 igw-xxx
使用场景:
├─ Web 服务器
├─ 负载均衡器
├─ NAT Gateway
├─ Bastion Host(跳板机)
└─ 对外服务的 API Gateway
私有子网(Private Subnet):
特征:
├─ 路由表不包含 Internet Gateway 路由
├─ 实例只有私有 IP
├─ 不能直接访问 Internet
└─ 可通过 NAT Gateway 访问 Internet(单向)
典型路由表:
目的地 目标
10.0.0.0/16 local
0.0.0.0/0 nat-xxx
使用场景:
├─ 应用服务器
├─ 数据库服务器
├─ 缓存服务器
├─ 批处理作业
└─ 内部微服务
隔离子网(Isolated Subnet):
特征:
├─ 没有到 Internet 的路由
├─ 只能访问 VPC 内部资源
├─ 最高级别的隔离
└─ 通过 VPC Endpoints 访问 AWS 服务
典型路由表:
目的地 目标
10.0.0.0/16 local
(无其他路由)
使用场景:
├─ 高度敏感的数据库
├─ 合规要求的数据存储
├─ 内部审计系统
└─ 完全隔离的处理系统
子网大小规划
选择合适的子网大小:
子网大小对比:
/24 子网(256 IP):
├─ 总 IP:256
├─ AWS 保留:5
├─ 可用:251
└─ 适合:中型应用、单层服务
/25 子网(128 IP):
├─ 总 IP:128
├─ AWS 保留:5
├─ 可用:123
└─ 适合:小型服务、测试环境
/26 子网(64 IP):
├─ 总 IP:64
├─ AWS 保留:5
├─ 可用:59
└─ 适合:微服务、特定用途子网
/27 子网(32 IP):
├─ 总 IP:32
├─ AWS 保留:5
├─ 可用:27
└─ 适合:非常小的服务、Lambda
/28 子网(16 IP):
├─ 总 IP:16
├─ AWS 保留:5
├─ 可用:11
└─ 最小推荐大小
规划原则:
1. 预留增长空间
├─ 不要使用所有可用 CIDR
├─ 预留 50% 用于未来扩展
└─ 考虑 Auto Scaling 需求
2. 均衡分配
├─ 每个 AZ 分配相同大小的子网
├─ 简化管理和故障切换
└─ 便于负载均衡
3. 按用途分组
├─ Web 层、App 层、数据层分别规划
├─ 每层使用连续的 CIDR 范围
└─ 便于应用网络策略
实战规划示例
生产环境 3-AZ 部署:
VPC: 10.0.0.0/16 (65,536 IP)
可用区 A(us-east-1a):
├─ 公有子网: 10.0.1.0/24 (251 IP)
│ └─ 用途:负载均衡器、NAT Gateway
├─ 应用子网: 10.0.11.0/24 (251 IP)
│ └─ 用途:应用服务器、微服务
└─ 数据子网: 10.0.21.0/24 (251 IP)
└─ 用途:RDS、ElastiCache
可用区 B(us-east-1b):
├─ 公有子网: 10.0.2.0/24 (251 IP)
├─ 应用子网: 10.0.12.0/24 (251 IP)
└─ 数据子网: 10.0.22.0/24 (251 IP)
可用区 C(us-east-1c):
├─ 公有子网: 10.0.3.0/24 (251 IP)
├─ 应用子网: 10.0.13.0/24 (251 IP)
└─ 数据子网: 10.0.23.0/24 (251 IP)
预留空间:
├─ 10.0.4.0/22 - 10.0.7.0/22:未来公有子网
├─ 10.0.14.0/23 - 10.0.20.0/23:未来应用子网
└─ 10.0.24.0/21 - 10.0.31.0/21:未来数据子网
已使用:9 个子网(约 2,259 IP)
可用:56,277 IP(86% 预留)
开发/测试环境简化部署:
VPC: 10.1.0.0/16
可用区 A:
├─ 公有子网: 10.1.1.0/24
└─ 私有子网: 10.1.11.0/24
可用区 B:
├─ 公有子网: 10.1.2.0/24
└─ 私有子网: 10.1.12.0/24
特点:
├─ 仅 2 个 AZ(降低成本)
├─ 简化的网络拓扑
└─ 足够的开发测试空间
路由表设计
路由表类型
主路由表(Main Route Table):
特性:
├─ VPC 创建时自动生成
├─ 默认路由表
├─ 未显式关联子网使用此路由表
└─ 建议保持默认配置
最佳实践:
├─ 不要修改主路由表
├─ 为公有子网创建单独的路由表
├─ 主路由表用于私有子网
└─ 明确关联避免意外
自定义路由表:
用途:
├─ 公有子网路由表
├─ 私有子网路由表
├─ 特定服务路由表
└─ VPN/Direct Connect 路由表
每个子网只能关联一个路由表
一个路由表可以关联多个子网
路由配置模式
公有子网路由表:
# 创建公有路由表
PUBLIC_RTB=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-RouteTable}]' \
--query 'RouteTable.RouteTableId' \
--output text)
# 添加 Internet Gateway 路由
aws ec2 create-route \
--route-table-id $PUBLIC_RTB \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID
# 关联公有子网
aws ec2 associate-route-table \
--subnet-id $PUBLIC_SUBNET_1 \
--route-table-id $PUBLIC_RTB
aws ec2 associate-route-table \
--subnet-id $PUBLIC_SUBNET_2 \
--route-table-id $PUBLIC_RTB
路由表内容:
目的地 目标 状态
10.0.0.0/16 local active
0.0.0.0/0 igw-xxx active
解释:
├─ 10.0.0.0/16 → local:VPC 内部流量
└─ 0.0.0.0/0 → igw-xxx:Internet 流量
私有子网路由表:
# 为每个 AZ 创建独立的私有路由表
PRIVATE_RTB_A=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Private-RouteTable-A}]' \
--query 'RouteTable.RouteTableId' \
--output text)
# 添加 NAT Gateway 路由
aws ec2 create-route \
--route-table-id $PRIVATE_RTB_A \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id $NAT_GW_A
# 关联私有子网
aws ec2 associate-route-table \
--subnet-id $PRIVATE_SUBNET_A \
--route-table-id $PRIVATE_RTB_A
路由表内容:
目的地 目标 状态
10.0.0.0/16 local active
0.0.0.0/0 nat-xxx active
解释:
├─ 10.0.0.0/16 → local:VPC 内部流量
└─ 0.0.0.0/0 → nat-xxx:通过 NAT 访问 Internet
高级路由场景
多 NAT Gateway 高可用架构:
架构说明:
每个 AZ 部署独立的 NAT Gateway,避免跨 AZ 流量费用
AZ-A 私有子网路由表:
目的地 目标
10.0.0.0/16 local
0.0.0.0/0 nat-gw-a (部署在 AZ-A)
AZ-B 私有子网路由表:
目的地 目标
10.0.0.0/16 local
0.0.0.0/0 nat-gw-b (部署在 AZ-B)
优势:
├─ 高可用:单个 NAT 故障不影响其他 AZ
├─ 性能:避免跨 AZ 数据传输
├─ 成本:减少跨 AZ 流量费用
└─ 隔离:每个 AZ 独立的出口
成本:
├─ 每个 NAT Gateway:$0.045/小时
├─ 3 个 AZ:$97.2/月(仅 NAT 费用)
└─ 需要权衡可用性和成本
VPC Peering 路由:
# VPC-A 添加到 VPC-B 的路由
aws ec2 create-route \
--route-table-id $VPC_A_RTB \
--destination-cidr-block 10.1.0.0/16 \
--vpc-peering-connection-id $PEERING_ID
# VPC-B 添加到 VPC-A 的路由
aws ec2 create-route \
--route-table-id $VPC_B_RTB \
--destination-cidr-block 10.0.0.0/16 \
--vpc-peering-connection-id $PEERING_ID
路由表内容(VPC-A):
目的地 目标 用途
10.0.0.0/16 local 本地 VPC
10.1.0.0/16 pcx-xxx Peering 到 VPC-B
0.0.0.0/0 igw-xxx Internet
Transit Gateway 集中式路由:
集中式网络架构:
Transit Gateway(中心):
├─ 作为中央路由器
├─ 连接多个 VPC
├─ 简化路由管理
└─ 支持跨区域
VPC-A 路由表:
目的地 目标
10.0.0.0/16 local
10.1.0.0/16 tgw-xxx
10.2.0.0/16 tgw-xxx
0.0.0.0/0 igw-xxx
优势:
├─ 扩展性好(最多 5000 个 VPC)
├─ 简化的路由配置
├─ 集中的流量监控
└─ 支持路由传播
NAT Gateway 详解
NAT Gateway 部署
单 NAT Gateway(开发环境):
# 1. 分配弹性 IP
EIP_ALLOC=$(aws ec2 allocate-address \
--domain vpc \
--tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=NAT-Gateway-EIP}]' \
--query 'AllocationId' \
--output text)
echo "Elastic IP AllocationId: $EIP_ALLOC"
# 2. 创建 NAT Gateway(部署在公有子网)
NAT_GW=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET \
--allocation-id $EIP_ALLOC \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=Main-NAT-Gateway}]' \
--query 'NatGateway.NatGatewayId' \
--output text)
echo "NAT Gateway ID: $NAT_GW"
# 3. 等待 NAT Gateway 可用
echo "等待 NAT Gateway 变为可用状态..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW
echo "NAT Gateway 已就绪"
# 4. 更新私有子网路由表
aws ec2 create-route \
--route-table-id $PRIVATE_RTB \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id $NAT_GW
echo "路由已配置"
架构说明:
┌────────────────────────────────┐
│ VPC │
│ ┌─────────────────────────┐ │
│ │ Public Subnet │ │
│ │ ┌─────────────────┐ │ │
│ │ │ NAT Gateway │ │ │
│ │ │ (EIP attached) │ │ │
│ │ └────────┬────────┘ │ │
│ └───────────┼─────────────┘ │
│ │ │
│ ↓ │
│ ┌───────────────────────┐ │
│ │ Private Subnet │ │
│ │ ┌─────────────┐ │ │
│ │ │EC2 Instances│──────┘ │
│ │ │(Private IP) │ │
│ │ └─────────────┘ │
│ └───────────────────────────┘│
│ │ │
│ ┌────▼────┐ │
│ │ IGW │ │
│ └─────────┘ │
└────────────────────────────────┘
│
Internet
成本(单 NAT):
├─ NAT Gateway:$32.4/月
├─ 数据处理:$0.045/GB
└─ 总成本:$32.4 + 数据费用
风险:
└─ 单点故障(NAT Gateway 故障影响所有私有子网)
多 NAT Gateway 高可用(生产环境):
# 为每个 AZ 创建 NAT Gateway
# AZ-A
EIP_A=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_GW_A=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_A \
--allocation-id $EIP_A \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=NAT-GW-A}]' \
--query 'NatGateway.NatGatewayId' \
--output text)
# AZ-B
EIP_B=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_GW_B=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_B \
--allocation-id $EIP_B \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=NAT-GW-B}]' \
--query 'NatGateway.NatGatewayId' \
--output text)
# AZ-C
EIP_C=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
NAT_GW_C=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_C \
--allocation-id $EIP_C \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=NAT-GW-C}]' \
--query 'NatGateway.NatGatewayId' \
--output text)
# 等待所有 NAT Gateway 可用
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_A $NAT_GW_B $NAT_GW_C
# 配置每个 AZ 的私有路由表
aws ec2 create-route --route-table-id $PRIVATE_RTB_A \
--destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_A
aws ec2 create-route --route-table-id $PRIVATE_RTB_B \
--destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_B
aws ec2 create-route --route-table-id $PRIVATE_RTB_C \
--destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_C
架构说明:
┌──────────────────────────────────────────────────────┐
│ VPC │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ AZ-A │ │ AZ-B │ │ AZ-C │ │
│ │ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │ │
│ │ │NAT-GW-A│ │ │ │NAT-GW-B│ │ │ │NAT-GW-C│ │ │
│ │ └───┬────┘ │ │ └───┬────┘ │ │ └───┬────┘ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ ↓ │ │ ↓ │ │ ↓ │ │
│ │ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │ │
│ │ │Private │ │ │ │Private │ │ │ │Private │ │ │
│ │ │Subnet │ │ │ │Subnet │ │ │ │Subnet │ │ │
│ │ └────────┘ │ │ └────────┘ │ │ └────────┘ │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │ │
│ ┌────▼────┐ │
│ │ IGW │ │
│ └─────────┘ │
└──────────────────────────────────────────────────────┘
成本(3 NAT):
├─ 3x NAT Gateway:$97.2/月
├─ 数据处理:$0.045/GB
└─ 总成本:$97.2 + 数据费用
优势:
├─ 高可用(单个 NAT 故障仅影响一个 AZ)
├─ 无跨 AZ 流量费用
├─ 更好的性能
└─ 生产环境推荐
NAT Gateway 监控
关键指标:
CloudWatch 指标:
├─ ActiveConnectionCount:活跃连接数
├─ BytesInFromDestination:从目标接收字节数
├─ BytesInFromSource:从源接收字节数
├─ BytesOutToDestination:发送到目标字节数
├─ BytesOutToSource:发送到源字节数
├─ ConnectionAttemptCount:连接尝试次数
├─ ConnectionEstablishedCount:成功建立连接数
├─ ErrorPortAllocation:端口分配错误数
└─ PacketsDropCount:丢包数
告警设置:
├─ ErrorPortAllocation > 0:端口耗尽告警
├─ PacketsDropCount > 100:丢包告警
└─ ActiveConnectionCount > 50000:连接数告警
成本优化:
降低 NAT Gateway 成本:
1. VPC Endpoints(推荐):
├─ S3 Gateway Endpoint:免费
├─ DynamoDB Gateway Endpoint:免费
├─ Interface Endpoints:按小时计费
└─ 避免通过 NAT 访问 AWS 服务
2. 区域选择:
├─ 选择距离用户近的区域
└─ 减少跨区域流量
3. 数据传输优化:
├─ 压缩数据
├─ 缓存策略
├─ CDN(CloudFront)
└─ 批量处理
4. 开发环境策略:
├─ 仅在需要时启动 NAT
├─ 下班时间停止 NAT
└─ 使用 NAT Instance(更便宜但需管理)
IPv6 支持
IPv6 配置
启用 IPv6:
# 为 VPC 分配 IPv6 CIDR
aws ec2 associate-vpc-cidr-block \
--vpc-id $VPC_ID \
--amazon-provided-ipv6-cidr-block
# 为子网分配 IPv6 CIDR
aws ec2 associate-subnet-cidr-block \
--subnet-id $SUBNET_ID \
--ipv6-cidr-block 2600:1f14:e2f:bf00::/64
# 更新路由表支持 IPv6
aws ec2 create-route \
--route-table-id $PUBLIC_RTB \
--destination-ipv6-cidr-block ::/0 \
--gateway-id $IGW_ID
双栈架构:
同时支持 IPv4 和 IPv6:
├─ IPv4:10.0.0.0/16
└─ IPv6:2600:1f14:e2f:bf00::/56
路由表:
目的地 目标
10.0.0.0/16 local
2600:1f14:e2f:bf00::/56 local
0.0.0.0/0 igw-xxx
::/0 igw-xxx
优势:
├─ 更多的 IP 地址
├─ 无需 NAT(IPv6 原生支持)
└─ 未来兼容性
子网和路由的正确配置是构建可靠 VPC 的关键!