网络架构规划
整体网络设计
Multi-VPC 架构
架构理念:环境隔离 + 安全边界
┌─────────────────────────────────────────────────────────┐
│ Transit Gateway Hub │
│ (中心化路由和连接管理) │
└─────────┬──────────────┬──────────────┬────────────────┘
│ │ │
┌─────▼─────┐ ┌─────▼─────┐ ┌────▼──────┐
│ Prod VPC │ │NonProd VPC│ │Shared VPC │
│10.0.0.0/16│ │10.1.0.0/16│ │10.2.0.0/16│
└───────────┘ └───────────┘ └───────────┘
│ │ │
生产环境 开发/测试 CI/CD/监控
VPC 职责划分
生产 VPC(10.0.0.0/16)
用途:
├─ 生产应用运行环境
├─ 生产数据库
├─ 生产缓存
└─ 对外服务
特点:
├─ 最高安全等级
├─ 完整监控和日志
├─ 严格访问控制
├─ 多可用区高可用
└─ 自动备份和容灾
子网规划:
├─ 公有子网(3个AZ):负载均衡器
├─ 私有应用子网(3个AZ):EKS Worker Nodes
└─ 私有数据子网(3个AZ):数据库、缓存
非生产 VPC(10.1.0.0/16)
用途:
├─ 开发环境
├─ 测试环境
├─ 预发布环境(Staging)
└─ 性能测试
特点:
├─ 成本优化配置
├─ 与生产环境隔离
├─ 可以使用 Spot 实例
├─ 较低的资源配置
└─ 定时关闭策略
子网规划:
├─ 公有子网(2个AZ):简化配置
├─ 私有应用子网(2个AZ):应用服务
└─ 私有数据子网(2个AZ):数据库
共享服务 VPC(10.2.0.0/16)
用途:
├─ CI/CD 工具(Jenkins、ArgoCD)
├─ 日志聚合系统(ELK)
├─ 监控系统(Prometheus、Grafana)
├─ 镜像仓库(ECR 代理)
└─ 内部工具
特点:
├─ 所有环境共享
├─ 中等安全等级
├─ 稳定性要求高
└─ 按需访问控制
子网规划:
├─ 公有子网(2个AZ):工具 UI
└─ 私有应用子网(2个AZ):后台服务
生产 VPC 详细设计
CIDR 规划
VPC CIDR:10.0.0.0/16(65,536 个 IP)
子网划分原则:
1. 预留足够的扩展空间
2. 每个 AZ 使用独立的 CIDR 块
3. 按层次分配(公有、应用、数据)
4. 避免地址浪费
子网详细规划
公有子网(Public Subnets)
用途:互联网可访问的资源
├─ Application Load Balancer
├─ Network Load Balancer
├─ NAT Gateway
└─ Bastion Host(跳板机)
子网分配:
├─ us-east-1a: 10.0.1.0/24 (251 可用 IP)
├─ us-east-1b: 10.0.2.0/24 (251 可用 IP)
└─ us-east-1c: 10.0.3.0/24 (251 可用 IP)
路由特点:
├─ 默认路由 → Internet Gateway
├─ 自动分配公网 IP
└─ 直接访问互联网
资源估算:
├─ ALB:每个 AZ 2-3 个 ENI
├─ NAT Gateway:每个 AZ 1 个
├─ Bastion:1-2 个实例
└─ 预留:约 200 IP/AZ
私有应用子网(Private App Subnets)
用途:运行应用服务
├─ EKS Worker Nodes
├─ 容器 Pods
├─ 应用服务器
└─ 内部工具
子网分配:
├─ us-east-1a: 10.0.11.0/24 (251 可用 IP)
├─ us-east-1b: 10.0.12.0/24 (251 可用 IP)
└─ us-east-1c: 10.0.13.0/24 (251 可用 IP)
路由特点:
├─ 默认路由 → NAT Gateway(本 AZ)
├─ 无公网 IP
├─ 通过 NAT 访问互联网
└─ VPC Endpoints 访问 AWS 服务
IP 地址规划:
每个 EKS 节点需要:
├─ 主网卡 IP:1 个
├─ Pod IPs:取决于实例类型
│ ├─ t3.medium:最多 17 个 Pod
│ ├─ t3.large:最多 35 个 Pod
│ ├─ m5.xlarge:最多 58 个 Pod
│ └─ m5.2xlarge:最多 118 个 Pod
容量计算(以 m5.xlarge 为例):
├─ 每个 AZ:6 个节点
├─ 每节点:1 + 58 = 59 IP
├─ 总需求:6 × 59 = 354 IP
└─ 子网容量:251 IP(需要扩展!)
⚠️ 优化方案:
方案 1:使用 /23 子网
├─ us-east-1a: 10.0.10.0/23 (507 可用 IP)
├─ us-east-1b: 10.0.12.0/23 (507 可用 IP)
└─ us-east-1c: 10.0.14.0/23 (507 可用 IP)
方案 2:Secondary CIDR(推荐)
├─ 保持现有 /24
├─ 添加 Secondary CIDR:100.64.0.0/16
└─ 用于 Pod 网络
私有数据子网(Private Data Subnets)
用途:数据存储层
├─ RDS 数据库
├─ ElastiCache Redis
├─ 其他数据存储
└─ 完全隔离,无互联网访问
子网分配:
├─ us-east-1a: 10.0.21.0/24 (251 可用 IP)
├─ us-east-1b: 10.0.22.0/24 (251 可用 IP)
└─ us-east-1c: 10.0.23.0/24 (251 可用 IP)
路由特点:
├─ 无默认路由
├─ 仅 VPC 内部路由
├─ 通过 VPC Endpoints 访问 S3
└─ 完全隔离互联网
安全加固:
├─ Network ACL 严格限制
├─ 安全组白名单
├─ 无 NAT Gateway 访问
└─ 仅应用层可访问
创建脚本
完整 VPC 创建脚本
#!/bin/bash
# create-production-vpc.sh
# 创建生产 VPC 和所有子网
set -e
REGION="us-east-1"
VPC_NAME="production-vpc"
VPC_CIDR="10.0.0.0/16"
ENVIRONMENT="production"
echo "================================================"
echo "创建生产 VPC: $VPC_NAME"
echo "CIDR: $VPC_CIDR"
echo "区域: $REGION"
echo "================================================"
# 1. 创建 VPC
echo ""
echo "1. 创建 VPC..."
VPC_ID=$(aws ec2 create-vpc \
--cidr-block $VPC_CIDR \
--region $REGION \
--tag-specifications "ResourceType=vpc,Tags=[
{Key=Name,Value=$VPC_NAME},
{Key=Environment,Value=$ENVIRONMENT},
{Key=ManagedBy,Value=script}
]" \
--query 'Vpc.VpcId' \
--output text)
echo " VPC ID: $VPC_ID"
# 启用 DNS 主机名
aws ec2 modify-vpc-attribute \
--vpc-id $VPC_ID \
--enable-dns-hostnames \
--region $REGION
echo " DNS 主机名已启用"
# 2. 创建 Internet Gateway
echo ""
echo "2. 创建 Internet Gateway..."
IGW_ID=$(aws ec2 create-internet-gateway \
--region $REGION \
--tag-specifications "ResourceType=internet-gateway,Tags=[
{Key=Name,Value=$VPC_NAME-igw},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'InternetGateway.InternetGatewayId' \
--output text)
echo " IGW ID: $IGW_ID"
# 附加到 VPC
aws ec2 attach-internet-gateway \
--vpc-id $VPC_ID \
--internet-gateway-id $IGW_ID \
--region $REGION
echo " Internet Gateway 已附加到 VPC"
# 3. 创建公有子网
echo ""
echo "3. 创建公有子网(3个AZ)..."
declare -A PUBLIC_SUBNETS
AZS=("us-east-1a" "us-east-1b" "us-east-1c")
PUBLIC_CIDRS=("10.0.1.0/24" "10.0.2.0/24" "10.0.3.0/24")
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
CIDR="${PUBLIC_CIDRS[$i]}"
echo " 创建公有子网: $AZ ($CIDR)"
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block $CIDR \
--availability-zone $AZ \
--region $REGION \
--tag-specifications "ResourceType=subnet,Tags=[
{Key=Name,Value=$VPC_NAME-public-$AZ},
{Key=Environment,Value=$ENVIRONMENT},
{Key=Type,Value=public},
{Key=kubernetes.io/role/elb,Value=1}
]" \
--query 'Subnet.SubnetId' \
--output text)
PUBLIC_SUBNETS[$AZ]=$SUBNET_ID
echo " 子网 ID: $SUBNET_ID"
# 启用自动分配公网 IP
aws ec2 modify-subnet-attribute \
--subnet-id $SUBNET_ID \
--map-public-ip-on-launch \
--region $REGION
echo " 已启用自动分配公网 IP"
done
# 4. 创建私有应用子网
echo ""
echo "4. 创建私有应用子网(3个AZ)..."
declare -A PRIVATE_APP_SUBNETS
PRIVATE_APP_CIDRS=("10.0.11.0/24" "10.0.12.0/24" "10.0.13.0/24")
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
CIDR="${PRIVATE_APP_CIDRS[$i]}"
echo " 创建私有应用子网: $AZ ($CIDR)"
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block $CIDR \
--availability-zone $AZ \
--region $REGION \
--tag-specifications "ResourceType=subnet,Tags=[
{Key=Name,Value=$VPC_NAME-private-app-$AZ},
{Key=Environment,Value=$ENVIRONMENT},
{Key=Type,Value=private-app},
{Key=kubernetes.io/role/internal-elb,Value=1}
]" \
--query 'Subnet.SubnetId' \
--output text)
PRIVATE_APP_SUBNETS[$AZ]=$SUBNET_ID
echo " 子网 ID: $SUBNET_ID"
done
# 5. 创建私有数据子网
echo ""
echo "5. 创建私有数据子网(3个AZ)..."
declare -A PRIVATE_DATA_SUBNETS
PRIVATE_DATA_CIDRS=("10.0.21.0/24" "10.0.22.0/24" "10.0.23.0/24")
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
CIDR="${PRIVATE_DATA_CIDRS[$i]}"
echo " 创建私有数据子网: $AZ ($CIDR)"
SUBNET_ID=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block $CIDR \
--availability-zone $AZ \
--region $REGION \
--tag-specifications "ResourceType=subnet,Tags=[
{Key=Name,Value=$VPC_NAME-private-data-$AZ},
{Key=Environment,Value=$ENVIRONMENT},
{Key=Type,Value=private-data}
]" \
--query 'Subnet.SubnetId' \
--output text)
PRIVATE_DATA_SUBNETS[$AZ]=$SUBNET_ID
echo " 子网 ID: $SUBNET_ID"
done
# 6. 创建 NAT Gateway(每个 AZ 一个)
echo ""
echo "6. 创建 NAT Gateway(3个AZ,高可用)..."
declare -A NAT_GATEWAYS
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
PUBLIC_SUBNET_ID="${PUBLIC_SUBNETS[$AZ]}"
echo " 在 $AZ 创建 NAT Gateway..."
# 分配 Elastic IP
EIP_ALLOC_ID=$(aws ec2 allocate-address \
--domain vpc \
--region $REGION \
--tag-specifications "ResourceType=elastic-ip,Tags=[
{Key=Name,Value=$VPC_NAME-nat-$AZ},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'AllocationId' \
--output text)
echo " EIP Allocation ID: $EIP_ALLOC_ID"
# 创建 NAT Gateway
NAT_GW_ID=$(aws ec2 create-nat-gateway \
--subnet-id $PUBLIC_SUBNET_ID \
--allocation-id $EIP_ALLOC_ID \
--region $REGION \
--tag-specifications "ResourceType=natgateway,Tags=[
{Key=Name,Value=$VPC_NAME-nat-$AZ},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'NatGateway.NatGatewayId' \
--output text)
NAT_GATEWAYS[$AZ]=$NAT_GW_ID
echo " NAT Gateway ID: $NAT_GW_ID"
done
# 等待 NAT Gateway 可用
echo ""
echo " 等待所有 NAT Gateway 变为可用状态..."
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
NAT_GW_ID="${NAT_GATEWAYS[$AZ]}"
echo " 等待 $AZ 的 NAT Gateway ($NAT_GW_ID)..."
aws ec2 wait nat-gateway-available \
--nat-gateway-ids $NAT_GW_ID \
--region $REGION
echo " ✓ NAT Gateway 已就绪"
done
# 7. 创建路由表
echo ""
echo "7. 创建路由表..."
# 公有路由表(所有公有子网共享)
echo " 创建公有路由表..."
PUBLIC_RT_ID=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--region $REGION \
--tag-specifications "ResourceType=route-table,Tags=[
{Key=Name,Value=$VPC_NAME-public-rt},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'RouteTable.RouteTableId' \
--output text)
echo " 路由表 ID: $PUBLIC_RT_ID"
# 添加默认路由到 Internet Gateway
aws ec2 create-route \
--route-table-id $PUBLIC_RT_ID \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID \
--region $REGION
echo " 已添加默认路由 → Internet Gateway"
# 关联所有公有子网
for AZ in "${AZS[@]}"; do
SUBNET_ID="${PUBLIC_SUBNETS[$AZ]}"
aws ec2 associate-route-table \
--route-table-id $PUBLIC_RT_ID \
--subnet-id $SUBNET_ID \
--region $REGION
echo " 已关联公有子网: $AZ"
done
# 私有应用路由表(每个 AZ 一个)
echo ""
echo " 创建私有应用路由表(每AZ独立)..."
declare -A PRIVATE_APP_RTS
for i in "${!AZS[@]}"; do
AZ="${AZS[$i]}"
NAT_GW_ID="${NAT_GATEWAYS[$AZ]}"
# 创建路由表
RT_ID=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--region $REGION \
--tag-specifications "ResourceType=route-table,Tags=[
{Key=Name,Value=$VPC_NAME-private-app-$AZ-rt},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'RouteTable.RouteTableId' \
--output text)
PRIVATE_APP_RTS[$AZ]=$RT_ID
echo " $AZ 路由表 ID: $RT_ID"
# 添加默认路由到本 AZ 的 NAT Gateway
aws ec2 create-route \
--route-table-id $RT_ID \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id $NAT_GW_ID \
--region $REGION
echo " 已添加默认路由 → NAT Gateway ($AZ)"
# 关联私有应用子网
SUBNET_ID="${PRIVATE_APP_SUBNETS[$AZ]}"
aws ec2 associate-route-table \
--route-table-id $RT_ID \
--subnet-id $SUBNET_ID \
--region $REGION
echo " 已关联私有应用子网: $AZ"
done
# 私有数据路由表(所有数据子网共享,无 NAT)
echo ""
echo " 创建私有数据路由表(无互联网访问)..."
PRIVATE_DATA_RT_ID=$(aws ec2 create-route-table \
--vpc-id $VPC_ID \
--region $REGION \
--tag-specifications "ResourceType=route-table,Tags=[
{Key=Name,Value=$VPC_NAME-private-data-rt},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'RouteTable.RouteTableId' \
--output text)
echo " 路由表 ID: $PRIVATE_DATA_RT_ID"
echo " 无默认路由(完全隔离)"
# 关联所有私有数据子网
for AZ in "${AZS[@]}"; do
SUBNET_ID="${PRIVATE_DATA_SUBNETS[$AZ]}"
aws ec2 associate-route-table \
--route-table-id $PRIVATE_DATA_RT_ID \
--subnet-id $SUBNET_ID \
--region $REGION
echo " 已关联私有数据子网: $AZ"
done
# 8. 创建 VPC Endpoints
echo ""
echo "8. 创建 VPC Endpoints..."
# S3 Gateway Endpoint(免费)
echo " 创建 S3 Gateway Endpoint..."
S3_ENDPOINT_ID=$(aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.$REGION.s3 \
--route-table-ids $PUBLIC_RT_ID ${PRIVATE_APP_RTS[@]} $PRIVATE_DATA_RT_ID \
--region $REGION \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-s3-endpoint},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'VpcEndpoint.VpcEndpointId' \
--output text)
echo " S3 Endpoint ID: $S3_ENDPOINT_ID"
# DynamoDB Gateway Endpoint(免费)
echo " 创建 DynamoDB Gateway Endpoint..."
DDB_ENDPOINT_ID=$(aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--service-name com.amazonaws.$REGION.dynamodb \
--route-table-ids $PUBLIC_RT_ID ${PRIVATE_APP_RTS[@]} \
--region $REGION \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-dynamodb-endpoint},
{Key=Environment,Value=$ENVIRONMENT}
]" \
--query 'VpcEndpoint.VpcEndpointId' \
--output text)
echo " DynamoDB Endpoint ID: $DDB_ENDPOINT_ID"
# 9. 输出摘要
echo ""
echo "================================================"
echo "VPC 创建完成!"
echo "================================================"
echo ""
echo "VPC 信息:"
echo " VPC ID: $VPC_ID"
echo " CIDR: $VPC_CIDR"
echo " Internet Gateway: $IGW_ID"
echo ""
echo "公有子网:"
for AZ in "${AZS[@]}"; do
echo " $AZ: ${PUBLIC_SUBNETS[$AZ]}"
done
echo ""
echo "私有应用子网:"
for AZ in "${AZS[@]}"; do
echo " $AZ: ${PRIVATE_APP_SUBNETS[$AZ]}"
done
echo ""
echo "私有数据子网:"
for AZ in "${AZS[@]}"; do
echo " $AZ: ${PRIVATE_DATA_SUBNETS[$AZ]}"
done
echo ""
echo "NAT Gateway:"
for AZ in "${AZS[@]}"; do
echo " $AZ: ${NAT_GATEWAYS[$AZ]}"
done
echo ""
echo "VPC Endpoints:"
echo " S3: $S3_ENDPOINT_ID"
echo " DynamoDB: $DDB_ENDPOINT_ID"
echo ""
echo "================================================"
# 保存配置到文件
cat > vpc-config.sh << EOF
# VPC 配置变量
export VPC_ID="$VPC_ID"
export IGW_ID="$IGW_ID"
# 公有子网
export PUBLIC_SUBNET_1A="${PUBLIC_SUBNETS[us-east-1a]}"
export PUBLIC_SUBNET_1B="${PUBLIC_SUBNETS[us-east-1b]}"
export PUBLIC_SUBNET_1C="${PUBLIC_SUBNETS[us-east-1c]}"
# 私有应用子网
export PRIVATE_APP_SUBNET_1A="${PRIVATE_APP_SUBNETS[us-east-1a]}"
export PRIVATE_APP_SUBNET_1B="${PRIVATE_APP_SUBNETS[us-east-1b]}"
export PRIVATE_APP_SUBNET_1C="${PRIVATE_APP_SUBNETS[us-east-1c]}"
# 私有数据子网
export PRIVATE_DATA_SUBNET_1A="${PRIVATE_DATA_SUBNETS[us-east-1a]}"
export PRIVATE_DATA_SUBNET_1B="${PRIVATE_DATA_SUBNETS[us-east-1b]}"
export PRIVATE_DATA_SUBNET_1C="${PRIVATE_DATA_SUBNETS[us-east-1c]}"
# NAT Gateway
export NAT_GW_1A="${NAT_GATEWAYS[us-east-1a]}"
export NAT_GW_1B="${NAT_GATEWAYS[us-east-1b]}"
export NAT_GW_1C="${NAT_GATEWAYS[us-east-1c]}"
EOF
echo "配置已保存到 vpc-config.sh"
echo "使用方法: source vpc-config.sh"
路由表设计
公有路由表
路由规则:
目标 CIDR 下一跳 说明
---------------------------------------------------------
10.0.0.0/16 local VPC 内部通信
0.0.0.0/0 igw-xxx 所有外网流量 → IGW
关联的子网:
├─ 10.0.1.0/24(us-east-1a 公有子网)
├─ 10.0.2.0/24(us-east-1b 公有子网)
└─ 10.0.3.0/24(us-east-1c 公有子网)
私有应用路由表(每 AZ 独立)
us-east-1a 路由表:
目标 CIDR 下一跳 说明
---------------------------------------------------------
10.0.0.0/16 local VPC 内部通信
0.0.0.0/0 nat-1a 外网流量 → NAT GW (1a)
s3-prefix-list vpce-s3 S3 流量 → VPC Endpoint
ddb-prefix-list vpce-ddb DynamoDB → VPC Endpoint
us-east-1b 路由表:
目标 CIDR 下一跳 说明
---------------------------------------------------------
10.0.0.0/16 local VPC 内部通信
0.0.0.0/0 nat-1b 外网流量 → NAT GW (1b)
s3-prefix-list vpce-s3 S3 流量 → VPC Endpoint
ddb-prefix-list vpce-ddb DynamoDB → VPC Endpoint
us-east-1c 路由表:
目标 CIDR 下一跳 说明
---------------------------------------------------------
10.0.0.0/16 local VPC 内部通信
0.0.0.0/0 nat-1c 外网流量 → NAT GW (1c)
s3-prefix-list vpce-s3 S3 流量 → VPC Endpoint
ddb-prefix-list vpce-ddb DynamoDB → VPC Endpoint
为什么每 AZ 独立路由表?
优点:
✓ AZ 故障隔离:一个 AZ 的 NAT 故障不影响其他 AZ
✓ 避免跨 AZ 流量:降低数据传输成本
✓ 性能优化:本 AZ 流量本地处理
缺点:
✗ 管理复杂度增加
✗ NAT Gateway 成本(3个)
决策:高可用 > 成本,采用每 AZ 独立路由
私有数据路由表
路由规则:
目标 CIDR 下一跳 说明
---------------------------------------------------------
10.0.0.0/16 local VPC 内部通信
s3-prefix-list vpce-s3 S3 流量 → VPC Endpoint
特点:
✓ 无默认路由(0.0.0.0/0)
✓ 完全隔离互联网
✓ 仅能访问 VPC 内部资源
✓ 通过 VPC Endpoint 访问 S3(备份)
VPC Endpoints
Gateway Endpoints(免费)
S3 Gateway Endpoint
用途:
├─ 访问 S3 存储桶
├─ 下载/上传文件
├─ 数据库备份到 S3
└─ 日志归档
优势:
✓ 完全免费
✓ 不占用 NAT 带宽
✓ 降低数据传输成本
✓ 更低延迟
配置:
├─ 服务名:com.amazonaws.us-east-1.s3
├─ 类型:Gateway
├─ 路由表:所有私有路由表
└─ 策略:Full Access
DynamoDB Gateway Endpoint
用途:
├─ 访问 DynamoDB 表
├─ 读写数据
└─ 流式处理
配置:
├─ 服务名:com.amazonaws.us-east-1.dynamodb
├─ 类型:Gateway
├─ 路由表:应用路由表
└─ 策略:Full Access
Interface Endpoints(按小时计费)
ECR Endpoints(容器镜像)
必需的 Endpoints(3个):
├─ com.amazonaws.us-east-1.ecr.api
├─ com.amazonaws.us-east-1.ecr.dkr
└─ com.amazonaws.us-east-1.s3(Gateway,免费)
用途:
├─ EKS 拉取容器镜像
├─ 避免通过 NAT Gateway
└─ 降低镜像拉取时间
成本:
├─ 每个 Endpoint:$0.01/小时 × 3AZ = $21.6/月
├─ 数据传输:$0.01/GB
└─ 总计:约 $22-30/月
节省:
├─ NAT 数据传输:$0.045/GB
├─ 每月镜像流量:约 1TB
├─ 节省:1000GB × ($0.045 - $0.01) = $35/月
└─ 净节省:约 $5-13/月 + 性能提升
其他常用 Endpoints
CloudWatch Logs:
├─ com.amazonaws.us-east-1.logs
├─ 用途:日志上传
└─ 成本:$21.6/月
Secrets Manager:
├─ com.amazonaws.us-east-1.secretsmanager
├─ 用途:应用获取密钥
└─ 成本:$21.6/月
STS(临时凭证):
├─ com.amazonaws.us-east-1.sts
├─ 用途:IRSA 获取临时凭证
└─ 成本:$21.6/月
总成本:约 $65-90/月
决策:核心服务使用,降低 NAT 依赖
创建 Interface Endpoints 脚本
#!/bin/bash
# create-vpc-endpoints.sh
# 创建 VPC Interface Endpoints
# 加载配置
source vpc-config.sh
REGION="us-east-1"
VPC_NAME="production-vpc"
# 获取私有应用子网 IDs
PRIVATE_SUBNETS="$PRIVATE_APP_SUBNET_1A $PRIVATE_APP_SUBNET_1B $PRIVATE_APP_SUBNET_1C"
# 创建 VPC Endpoint 安全组(后续章节会创建)
# 暂时使用默认安全组
SG_ID=$(aws ec2 describe-security-groups \
--filters "Name=vpc-id,Values=$VPC_ID" "Name=group-name,Values=default" \
--query 'SecurityGroups[0].GroupId' \
--output text)
echo "使用安全组: $SG_ID"
# 创建 ECR API Endpoint
echo "创建 ECR API Endpoint..."
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.$REGION.ecr.api \
--subnet-ids $PRIVATE_SUBNETS \
--security-group-ids $SG_ID \
--private-dns-enabled \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-ecr-api-endpoint}
]"
# 创建 ECR Docker Endpoint
echo "创建 ECR Docker Endpoint..."
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.$REGION.ecr.dkr \
--subnet-ids $PRIVATE_SUBNETS \
--security-group-ids $SG_ID \
--private-dns-enabled \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-ecr-dkr-endpoint}
]"
# 创建 CloudWatch Logs Endpoint
echo "创建 CloudWatch Logs Endpoint..."
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.$REGION.logs \
--subnet-ids $PRIVATE_SUBNETS \
--security-group-ids $SG_ID \
--private-dns-enabled \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-logs-endpoint}
]"
# 创建 STS Endpoint
echo "创建 STS Endpoint..."
aws ec2 create-vpc-endpoint \
--vpc-id $VPC_ID \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.$REGION.sts \
--subnet-ids $PRIVATE_SUBNETS \
--security-group-ids $SG_ID \
--private-dns-enabled \
--tag-specifications "ResourceType=vpc-endpoint,Tags=[
{Key=Name,Value=$VPC_NAME-sts-endpoint}
]"
echo "所有 VPC Endpoints 已创建!"
Transit Gateway 配置
架构设计
连接拓扑:
Transit Gateway
(Hub)
│
┌────────────┼────────────┐
│ │ │
Prod VPC NonProd VPC Shared VPC
10.0.0.0/16 10.1.0.0/16 10.2.0.0/16
路由策略
生产 VPC 路由:
允许访问:
├─ Shared VPC(监控、日志)
└─ NonProd VPC(受限,仅测试时)
拒绝访问:
└─ 其他 VPC
非生产 VPC 路由:
允许访问:
├─ Shared VPC(监控、日志、CI/CD)
└─ Prod VPC(受限,仅调试时)
共享服务 VPC 路由:
允许访问:
├─ Prod VPC(监控数据采集)
└─ NonProd VPC(日志采集)
创建 Transit Gateway 脚本
#!/bin/bash
# create-transit-gateway.sh
REGION="us-east-1"
TGW_NAME="multi-vpc-tgw"
# 创建 Transit Gateway
echo "创建 Transit Gateway..."
TGW_ID=$(aws ec2 create-transit-gateway \
--description "Multi-VPC Transit Gateway" \
--options AmazonSideAsn=64512,AutoAcceptSharedAttachments=disable,DefaultRouteTableAssociation=disable,DefaultRouteTablePropagation=disable,DnsSupport=enable,VpnEcmpSupport=enable \
--region $REGION \
--tag-specifications "ResourceType=transit-gateway,Tags=[
{Key=Name,Value=$TGW_NAME}
]" \
--query 'TransitGateway.TransitGatewayId' \
--output text)
echo "Transit Gateway ID: $TGW_ID"
# 等待可用
echo "等待 Transit Gateway 可用..."
aws ec2 wait transit-gateway-available \
--transit-gateway-ids $TGW_ID \
--region $REGION
# 创建路由表
echo "创建生产路由表..."
PROD_RT_ID=$(aws ec2 create-transit-gateway-route-table \
--transit-gateway-id $TGW_ID \
--region $REGION \
--tag-specifications "ResourceType=transit-gateway-route-table,Tags=[
{Key=Name,Value=$TGW_NAME-prod-rt}
]" \
--query 'TransitGatewayRouteTable.TransitGatewayRouteTableId' \
--output text)
echo "生产路由表 ID: $PROD_RT_ID"
# 附加 VPC(需要先创建 VPC)
# 附加操作在 VPC 创建后执行
echo "Transit Gateway 创建完成!"
echo "TGW_ID=$TGW_ID"
网络验证
连通性测试
测试脚本:
#!/bin/bash
# verify-network.sh
# 验证网络配置
source vpc-config.sh
echo "================================================"
echo "网络连通性测试"
echo "================================================"
# 1. 测试公有子网 → 互联网
echo ""
echo "1. 测试公有子网互联网连接..."
echo " 在公有子网启动临时实例并测试..."
# 需要手动在 EC2 上执行: curl https://www.google.com
# 2. 测试私有应用子网 → 互联网(通过 NAT)
echo ""
echo "2. 测试私有应用子网互联网连接(NAT)..."
# 需要手动在 EC2 上执行: curl https://www.google.com
# 3. 测试 VPC Endpoint
echo ""
echo "3. 测试 S3 VPC Endpoint..."
aws s3 ls --region us-east-1 --debug 2>&1 | grep -i "endpoint"
# 4. 测试私有数据子网隔离
echo ""
echo "4. 验证私有数据子网无互联网访问..."
# 应该失败
# curl https://www.google.com (timeout)
# 5. 测试跨 AZ 通信
echo ""
echo "5. 测试跨 AZ 子网通信..."
# ping 不同 AZ 的实例
echo ""
echo "================================================"
echo "网络验证完成"
echo "================================================"
成本分析
月度网络成本
NAT Gateway
配置:3 个 NAT Gateway(每 AZ 一个)
├─ 小时费用:$0.045/小时 × 3 = $0.135/小时
├─ 月费用:$0.135 × 730 = $98.55/月
├─ 数据处理:$0.045/GB
└─ 预估数据:500GB/月 × $0.045 = $22.5/月
总计:约 $121/月
VPC Endpoints(Interface)
ECR Endpoints(3个服务 × 3 AZ):
├─ ecr.api: $0.01/小时 × 3 AZ × 730 = $21.9/月
├─ ecr.dkr: $0.01/小时 × 3 AZ × 730 = $21.9/月
└─ 数据传输:$0.01/GB × 100GB = $1/月
CloudWatch Logs:
└─ $0.01/小时 × 3 AZ × 730 = $21.9/月
STS:
└─ $0.01/小时 × 3 AZ × 730 = $21.9/月
总计:约 $88.6/月
数据传输
跨 AZ 数据传输:
├─ 入站:免费
├─ 出站:$0.01/GB(同区域跨 AZ)
└─ 预估:200GB/月 × $0.01 = $2/月
互联网出站:
├─ 前 10TB:$0.09/GB
├─ 预估:1TB/月 × $0.09 = $90/月
└─ CloudFront 可降低成本
总计月度网络成本:约 $300-350/月
成本优化建议
1. NAT Gateway 优化
├─ 使用 VPC Endpoints 减少 NAT 流量
├─ 非生产环境共享 NAT
└─ 定时关闭非生产环境
2. 数据传输优化
├─ 使用 CloudFront CDN
├─ 压缩响应数据
└─ 缓存静态资源
3. VPC Endpoints
├─ 仅生产环境使用 Interface Endpoints
├─ 非生产环境使用 NAT Gateway
└─ 评估流量确定 ROI
4. 跨 AZ 流量优化
├─ 尽量本 AZ 处理
├─ 使用 Pod Topology Spread
└─ 数据库使用本地读副本
下一步: 继续学习 安全组和访问控制 章节,了解点对点安全组策略设计。