网络架构规划

整体网络设计

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
   └─ 数据库使用本地读副本

下一步: 继续学习 安全组和访问控制 章节,了解点对点安全组策略设计。