子网和路由设计

深入学习如何规划和配置 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 的关键!