概述

凌晨两点,某出行项目的告警群炸了。下单服务的 P99 延迟从 80ms 飙到 600ms,用户端开始大面积超时。排查了一圈,发现是 VPC 之间的对等连接(VPC Peering)成了瓶颈——两个核心业务 VPC 之间的跨 VPC 调用量在业务高峰期打满了单条 Peering 的并发连接数,而与此同时,另一个刚上线的 VPC 通过 Full Mesh 模式新建的 12 条 Peering 连接中有 3 条因为 CIDR 重叠配置失败,路由表混乱导致部分流量绕了远路。

这不是个例。当你的云上 VPC 数量超过 5 个,Full Mesh Peering 的维护成本就开始指数级增长。超过 10 个,运维团队基本就在疲于奔命了。

我曾经在某新能源物流平台主导过 120+ 微服务的 K8s 迁移,迁移之前花了很多精力做网络架构评审。当时就发现一个规律:很多团队的网络故障不是出在应用层,而是出在网络架构选型阶段埋下的坑。VPC Peering 看起来简单直接,但它有几个硬伤——不支持传递路由、Full Mesh 连接数 N*(N-1)/2 增长、无法集中管控路由策略。等你发现问题的时候,架构已经固化了,改造的代价远大于初始选型时多花两天做决策。

这篇文章不讲"VPC 是什么"这种入门概念。我假设你已经在用云、在管 VPC,遇到过多 VPC 互联的痛点。我要拆解的是:什么时候该用 VPC Peering,什么时候该切换到 Transit Gateway / CEN 转发路由器,混合组网怎么做,CIDR 规划怎么避免"网络一上线就得返工"。每个决策点我都给出生产环境的真实数据和踩坑细节,不是泛泛说"各有优劣"。

VPC Peering 的三个硬伤

VPC Peering 是两个 VPC 之间的点对点网络连接,流量走云厂商骨干网,同地域不收费,延迟低。听起来很美。但它在生产环境中有三个绕不过去的问题。

硬伤一:不支持传递路由

这是最致命的一个。假设你有 VPC-A、VPC-B、VPC-C 三个 VPC。A 和 B 建了 Peering,B 和 C 建了 Peering。你以为 A 能通过 B 访问 C?不行。AWS 官方文档明确说明:VPC Peering 不支持传递路由(transitive routing),两个没有直接 Peered 的 VPC 之间不能通过第三个 VPC 中转。

这意味着什么?如果要让 N 个 VPC 互相可达,你需要两两建立 Peering 连接——这就是所谓的 Full Mesh 模式。连接数是 N*(N-1)/2。5 个 VPC 要 10 条连接,10 个要 45 条,20 个要 190 条。

实际项目中,我在某电商平台见过 15 个 VPC 跑 Full Mesh 的场景。运维同学每次新增 VPC 都要手动配置 14 条 Peering 连接,还要在每条连接两端配置路由表、安全组规则。一次新 VPC 上线花了 3 天,其中 2 天在配网络。

硬伤二:路由配置散落,无法集中管控

Full Mesh 模式下,每条 Peering 连接的路由需要分别在两端 VPC 的路由表中手动添加。没有统一的控制面。这带来三个问题:

  1. 路由漂移:某次变更中,一个运维同学忘了在对端 VPC 的路由表加回指路由,导致单向可达——A 能 ping B,B 的响应包回不去。排查了 2 小时才发现是路由表缺一条。

  2. 无法做路由策略:你不能说"VPC-A 的生产子网可以访问 VPC-B 的数据库子网,但 VPC-A 的测试子网不行"。Peering 是 VPC 级别的连接,没有更细粒度的路由控制能力,只能靠安全组规则来打补丁。

  3. 变更无审计:谁在什么时候改了哪条路由?没有集中日志。出了故障只能翻 CloudTrail 逐条找。

硬伤三:CIDR 重叠后无法建立 Peering

VPC Peering 要求两个 VPC 的 CIDR 块不能重叠。这在初期规划不当时会变成一颗定时炸弹。

真实案例:某出行项目早期规划时,开发和测试环境的 VPC 都用了 10.0.0.0/16。后来要把两个环境打通做联调,发现 Peering 建不了。解决方案要么改一个 VPC 的 CIDR(涉及所有实例重新分配 IP,停机窗口至少 4 小时),要么用 NAT 网关做地址转换(增加延迟和成本,而且 NAT 后源 IP 变了,安全策略全部要重写)。

最后选了改 CIDR 方案。改的时候发现,VPC 内的 RDS 实例切换子网后需要重启,停机窗口从计划的 2 小时变成 6 小时。PM 的脸色当场就不好看了。

Transit Gateway / CEN 转发路由器:Hub-Spoke 的解法

VPC Peering 的三个硬伤,核心原因是点对点连接天然缺乏中心控制面。Transit Gateway(AWS)和 CEN 转发路由器(阿里云)用 Hub-Spoke 模型解决了这个问题。

简单说:所有 VPC 都连接到一个中心网关(Hub),VPC 之间不需要两两连接。网关负责路由传播、策略控制和流量转发。

工作原理

阿里云文档对转发路由器的定义是:每个地域创建一个转发路由器实例,网络实例(VPC、VBR、CCN 等)连接到转发路由器后,转发路由器自动同步路由,实现互通。

AWS Transit Gateway 的描述类似:作为区域虚拟路由器,在 VPC 和本地网络之间路由流量,基于目标 IP 地址在第 3 层转发。

两者核心机制一样:Hub-Spoke + 路由传播。

对比:VPC Peering vs Transit Gateway / 转发路由器

对比项VPC PeeringTransit Gateway / 转发路由器
连接方式Full Mesh,VPC 两两连接Hub-Spoke,VPC 只连网关
路由传播不支持,需手动配两端路由支持,自动同步路由
带宽限制同地域无带宽限制受限于网关处理能力
配置复杂度高,N*(N-1)/2 条连接低,N 条连接
支持互联 VPC 数最大约 20 个最大约 200 个
延迟最低,直连多一跳,增加约 1-2ms
路由策略不支持支持细粒度路由策略和 QoS
计费同地域免费实例费 + 流量处理费
安全审计分散,无统一视图集中监控和路由策略

这张表不是让你选"更好的那个"。两个方案各有适用场景,关键看你的 VPC 数量、流量模型和管控需求。

我的选择建议

  • VPC 数量 ≤ 5 个,且流量模型简单:用 VPC Peering。同地域免费、延迟最低、配置量可控。5 个 VPC 才 10 条连接,一个下午能配完。
  • VPC 数量 6-15 个,或有多环境隔离需求:开始考虑 Transit Gateway / 转发路由器。10 个 VPC 的 Full Mesh 是 45 条连接,维护成本已经不可接受了。
  • VPC 数量 > 15 个,或有多账号、多地域、混合云需求:必须用 Transit Gateway / 转发路由器。Full Mesh 在这个规模下已经无法运维。
  • 少数 VPC 之间有大流量直连需求:混合组网。高流量对用 Peering(免费无带宽限制),其余走转发路由器。这是阿里云官方推荐的组合方案。

5 个生产级决策

下面这 5 个决策点是我在实际项目中踩过坑、交过学费后总结的。每个决策都给出具体场景和数据,不做"看情况"式的中立罗列。

决策一:Full Mesh 到 Hub-Spoke 的迁移时机

结论:VPC 数量达到 8 个时启动迁移规划,12 个时必须完成迁移。

为什么是 8 个?因为 8 个 VPC 的 Full Mesh 是 28 条连接。按每条连接平均 15 分钟配置时间(含两端路由表和安全组),一次新增 VPC 的网络配置需要 7 项操作 × 15 分钟 = 约 2 小时。这还没算变更审批和验证时间。到 12 个 VPC(66 条连接),新增一个 VPC 的网络配置就要半天,运维团队的响应速度已经跟不上了。

迁移策略:不要一次性割接。按以下顺序分步迁移:

  1. 先建 Transit Gateway / 转发路由器实例
  2. 把非核心 VPC 先接入(开发、测试环境),验证路由传播和连通性
  3. 逐个把核心 VPC 接入,每接入一个就删除对应的 Peering 连接
  4. 最后一批核心 VPC 接入后,清理所有残留 Peering

踩坑细节:迁移过程中,新旧两种连接方式并存。如果一个 VPC 同时有 Peering 和 Transit Gateway 连接,路由表里会有两条路径指向同一目的地。AWS Transit Gateway 和阿里云转发路由器都通过路由优先级处理这种情况,但你需要确保优先级配置正确,否则流量可能走了已过期的 Peering 路径。

在某出行项目的迁移中,我就遇到过一个 VPC 的路由表里 Peering 路由的 metric 比 Transit Gateway 路由低(优先级更高),导致迁移后流量还在走旧 Peering。排查了 1 小时才发现是路由表优先级没调。

决策二:CIDR 规划——别等网络上线了才发现网段冲突

结论:在第一个 VPC 创建之前,花一天时间做全网 CIDR 规划。

CIDR 规划是云网络架构的"地基"。地基没打好,上面盖什么楼都会歪。我见过太多团队"先建 VPC 再说",结果半年后做互联时发现网段冲突。

规划原则:

  1. 按环境分层:生产用 10.1.0.0/16,预发用 10.2.0.0/16,测试用 10.3.0.0/16。不同环境天然隔离,后续做 Peering 或转发路由器时不会冲突。

  2. 按地域分大段:华北用 10.1.0.0/18,华东用 10.1.64.0/18,华南用 10.1.128.0/18。同一环境在不同地域的 VPC 网段不重叠。

  3. 预留扩展空间:不要把 10.0.0.0/8 全部分完。给未来新地域、新环境、新业务线留出至少 30% 的地址空间。

  4. 为 Transit Gateway 预留 landing 子网:阿里云官方实践建议每个 VPC 规划两个 /29 子网作为 TR-attach 的 landing 子网,用不同可用区实现容灾。这样业务流量和 TR 管理流量隔离,不占用业务网段。

反面案例:某团队 3 个 VPC 分别用了 10.0.0.0/16、10.0.0.0/16、10.0.1.0/24。第二个 VPC 的 CIDR 和第一个完全重叠,根本没法建 Peering。最后只能删掉第二个 VPC 重建,丢了 2 天。

CIDR 规划参考表:

环境地域VPC CIDR子网划分备注
生产华北10.1.0.0/18Web:10.1.0.0/22, App:10.1.4.0/22, DB:10.1.8.0/22预留 10.1.12.0/22
生产华东10.1.64.0/18Web:10.1.64.0/22, App:10.1.68.0/22, DB:10.1.72.0/22预留 10.1.76.0/22
预发华北10.2.0.0/18Web:10.2.0.0/22, App:10.2.4.0/22, DB:10.2.8.0/22预留 10.2.12.0/22
测试华北10.3.0.0/18混合部署:10.3.0.0/22不分三层
TR landing每个 VPC/29 × 2不同可用区不占业务网段

决策三:混合组网——Peering 和转发路由器的组合策略

结论:高流量 VPC 对用 Peering,其余走转发路由器。用共享服务账号承载转发路由器费用。

这是阿里云在自动驾驶企业 X 的案例中推荐的方案,也是我在实际项目中最常用的组合策略。

场景:假设你有 8 个 VPC,其中 VPC-1 和 VPC-2 之间有大数据同步需求(日均 TB 级流量),其余 VPC 之间是小流量互访。

方案:

  • VPC-1 和 VPC-2 之间建 VPC Peering(同地域免费,无带宽限制)
  • 其余 6 个 VPC 全部接入转发路由器
  • VPC-1 和 VPC-2 也接入转发路由器,用于和其他 VPC 通信
  • 转发路由器部署在共享服务账号,费用分摊

收益:VPC-1 和 VPC-2 之间的大流量走 Peering 不产生流量处理费,其余小流量走转发路由器享受集中管控。

踩坑细节:混合组网中,VPC-1 同时有 Peering(到 VPC-2)和转发路由器连接(到其余 VPC)。路由表里同一目的 CIDR 可能同时存在 Peering 和转发路由器两条路径。你需要在路由表中设置正确的优先级:

# 阿里云:查看转发路由器路由表
aliyun cen describe-transit-route-table-attributes \
  --transit-route-table-id rtb-xxx \
  --region cn-hangzhou

# AWS:查看 Transit Gateway 路由表
aws ec2 search-transit-gateway-routes \
  --transit-gateway-route-table-id tgw-rtb-xxx \
  --filters "Name=type,Values=propagated"

路由优先级规则:更具体的前缀优先。如果 Peering 路由是 10.2.0.0/16,转发路由器路由是 10.2.0.0/18,后者更具体,流量走转发路由器。如果你想流量走 Peering,需要确保 Peering 路由的前缀不比转发路由器的更宽泛。

某次我在排查一个路由问题时就发现,转发路由器自动传播的路由把 10.2.0.0/16 整段都广播了,覆盖了手动配置的 Peering 路由 10.2.0.0/16(同前缀,传播路由优先级高于手动路由)。最后通过在转发路由器路由表中加一条更精确的黑洞路由解决了——但这属于 trick,不是规范做法。正规做法是在转发路由器的路由策略中配置前缀过滤,不让传播路由覆盖 Peering 路径。

决策四:跨地域互联——带宽包 vs 按流量付费

结论:稳态流量用带宽包,突发流量用按流量付费,混合使用最优。

跨地域互联是云网络的高频需求——生产在北京,灾备在上海,两个地域的 VPC 需要互通。这时候你需要跨地域连接。

阿里云 CEN 跨地域连接提供两种计费方式:

计费方式适用场景计费规则链路质量
从带宽包分配流量峰值平稳,长期运行带宽包实例费 + 流量传输费金线
按流量付费流量峰值波动大,不可预估按 GB 计费,CDT 统一计费金线/铂金

AWS Transit Gateway 的跨地域连接则按连接小时费 + 数据处理费计费。

我的决策模型:

  1. 先统计过去 30 天的跨地域流量数据,算出日均流量和峰值流量
  2. 如果日均流量 > 500GB/天,用带宽包更划算(固定带宽,流量费封顶)
  3. 如果日均流量 < 100GB/天且波动大,用按流量付费(用多少算多少,不浪费)
  4. 100-500GB/天之间,两个方案都算一遍总成本,选低的

实测数据(阿里云,华东到华北,2026 年):

  • 按流量付费:0.8 元/GB,日均 200GB → 160 元/天 → 4800 元/月
  • 10Mbps 带宽包:约 3500 元/月,日均跑满约 105GB → 不够用
  • 50Mbps 带宽包:约 12000 元/月,日均跑满约 527GB → 跑不满,浪费
  • 混合方案:20Mbps 带宽包(5000 元/月)+ 超出部分按流量付费 → 月均 6500 元,刚好覆盖 200GB/天的稳定流量 + 偶尔 400GB 的突发

结论:混合方案最优,省了约 30% 成本。但混合方案需要配合限速策略,避免突发流量把带宽包跑满后按流量计费的部分失控。

决策五:安全与合规——零信任网络下的 VPC 隔离

结论:用转发路由器的路由策略做网络隔离,用安全组做主机级隔离,两层防御。

在等保 2.0 合规场景下,不同安全域之间的网络隔离是硬性要求。VPC Peering 无法做到细粒度的路由隔离——Peering 是 VPC 级别全通的,你无法在路由层面控制"只有 VPC-A 的生产子网可以访问 VPC-B 的数据库子网"。

转发路由器支持路由策略和 VRF 隔离。AWS Transit Gateway Connect通过 GRE 隧道和 VRF 实现本地网络的分段隔离,每个 VRF 对应一个独立的路由域。

阿里云转发路由器支持路由策略,可以基于前缀、source/destination CIDR 做过滤:

# 阿里云:创建路由策略,禁止测试环境访问生产数据库子网
aliyun cen create-route-policy \
  --cen-id cen-xxx \
  --transit-router-route-table-id rtb-xxx \
  --route-policy-name "block-test-to-prod-db" \
  --route-policy-priority 10 \
  --route-policy-type "drop" \
  --source-cidr "10.3.0.0/18" \
  --destination-cidr "10.1.8.0/22"

# 验证路由策略生效
aliyun cen list-route-policy \
  --cen-id cen-xxx \
  --transit-router-route-table-id rtb-xxx

安全分层模型:

防御层控制手段粒度适用场景
L3 路由隔离转发路由器路由策略子网级环境隔离、安全域隔离
L4 访问控制安全组规则端口/协议级精细化流量控制
L7 应用防护WAF / API 网关URL/Header 级外部流量入口

在某次等保 2.0 审计中,审计员要求证明"测试环境无法访问生产数据库"。用转发路由器的路由策略 drop 规则 + 抓包验证,一次性通过。如果用 Peering + 安全组,审计员会质疑"安全组规则是否被修改过",而路由策略是声明式配置,变更可审计,可信度更高。

架构决策权衡分析

前面讲了 5 个决策点,这里做一个完整的架构权衡对比。不是给你一个"最优方案",而是让你根据实际条件选择。

方案 A:纯 VPC Peering(Full Mesh)

适用条件:VPC ≤ 5 个,无多账号,无跨地域,无合规隔离需求

优势:

  • 同地域免费,零网络成本
  • 延迟最低(直连,无中间跳)
  • 配置简单,不需要额外服务

劣势:

  • 连接数 N*(N-1)/2 增长,不可扩展
  • 无集中路由管控
  • 无路由策略能力
  • CIDR 重叠后无法建立

总成本(5 个 VPC,运行 12 个月):

  • 网络费:0 元
  • 运维人力:约 20 人天/年(路由表维护 + 故障排查)
  • 风险成本:中(路由漂移概率 30%/年)

方案 B:纯 Transit Gateway / 转发路由器

适用条件:VPC > 5 个,或有多账号/跨地域/合规需求

优势:

  • 连接数 = N,线性增长
  • 路由自动传播
  • 支持路由策略和 QoS
  • 集中监控和审计

劣势:

  • 有实例费和流量处理费
  • 多一跳延迟(约 1-2ms)
  • 需要学习成本

总成本(10 个 VPC,运行 12 个月,阿里云华东):

  • 转发路由器实例费:约 0.5 元/小时 × 24 × 365 = 4380 元/年
  • 流量处理费:约 0.143 元/GB × 日均 500GB × 365 = 26098 元/年
  • 运维人力:约 5 人天/年
  • 风险成本:低(集中管控降低路由漂移概率)

方案 C:混合组网(Peering + 转发路由器)

适用条件:少数 VPC 对有大流量,其余小流量

优势:

  • 高流量对走 Peering 省钱
  • 其余走转发路由器享受集中管控
  • 灵活性最高

劣势:

  • 路由优先级管理复杂
  • 需要维护两套网络连接
  • 排障时需要同时看两种路径

总成本(10 个 VPC,其中 2 对大流量,运行 12 个月):

  • Peering 费用:0 元(同地域免费)
  • 转发路由器费用:约 30000 元/年
  • 大流量省下的流量处理费:约 15000 元/年
  • 净成本:约 15000 元/年
  • 运维人力:约 8 人天/年(比纯转发路由器多,因为要管两套)

三方案对比

维度方案 A(纯 Peering)方案 B(纯 TGW/TR)方案 C(混合)
年成本(10 VPC)0 元~30000 元~15000 元
可扩展性差(N² 增长)好(线性增长)好
运维复杂度高低中
路由策略不支持支持部分(仅 TR 连接)
延迟最低+1-2ms混合
合规支持弱强中

我的推荐:

  • 小型团队 / 初创期(≤5 VPC):方案 A。够用,免费,别过早优化。
  • 中型团队 / 成长期(6-15 VPC):方案 B。可扩展性是核心考量,别等 Full Mesh 维护不下去再迁移。
  • 大型团队 / 成熟期(>15 VPC 或有特殊流量模型):方案 C。大流量对用 Peering 省钱,其余用转发路由器管控。但要配好路由策略,别让路由优先级混乱。

生产环境实操

用 Terraform 管理网络架构

手工建 Peering 和转发路由器连接在大规模环境下不可维护。用 IaC(Terraform 管理基础设施)是必选项。

# AWS Transit Gateway + VPC Attachment 示例

# 创建 Transit Gateway
resource "aws_ec2_transit_gateway" "main" {
  description                     = "Production Transit Gateway"
  default_route_table_association = "enable"
  default_route_table_propagation = "enable"
  dns_support                     = "enable"
  multicast_support               = "disable"

  tags = {
    Name        = "prod-tgw"
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

# VPC Attachment(将 VPC 连接到 Transit Gateway)
resource "aws_ec2_transit_gateway_vpc_attachment" "vpc_a" {
  transit_gateway_id = aws_ec2_transit_gateway.main.id
  vpc_id             = var.vpc_a_id
  subnet_ids         = var.vpc_a_subnet_ids
  dns_support        = "enable"

  tags = {
    Name = "vpc-a-tgw-attachment"
  }
}

# 跨地域 Transit Gateway Peering
resource "aws_ec2_transit_gateway_peering_attachment" "cross_region" {
  transit_gateway_id      = aws_ec2_transit_gateway.main.id
  peer_transit_gateway_id = var.peer_tgw_id
  peer_region             = var.peer_region

  tags = {
    Name = "cross-region-tgw-peering"
  }
}

# 接受跨地域 Peering(在 peer region 执行)
resource "aws_ec2_transit_gateway_peering_attachment_accepter" "cross_region" {
  transit_gateway_attachment_id = aws_ec2_transit_gateway_peering_attachment.cross_region.id

  tags = {
    Name = "cross-region-tgw-peering-accepter"
  }
}
# 阿里云:用 Terraform 创建 CEN 转发路由器连接
# 需要 aliyun/terraform-provider-alicloud

# 定义 CEN 实例
resource "alicloud_cen_instance" "main" {
  name        = "prod-cen"
  description = "Production CEN for multi-VPC networking"
}

# 创建转发路由器(自动创建,通过 CEN 实例关联)
resource "alicloud_cen_transit_router" "main" {
  cidr        = "172.17.0.0/16"
  cen_id      = alicloud_cen_instance.main.id
  description = "Production Transit Router"
}

# 将 VPC 连接到转发路由器
resource "alicloud_cen_transit_router_vpc_attachment" "vpc_a" {
  transit_router_id                    = alicloud_cen_transit_router.main.id
  cen_id                               = alicloud_cen_instance.main.id
  vpc_id                               = var.vpc_a_id
  zone                                 = var.vpc_a_zone
  vpc_owner_id                         = "account-id"
  transit_router_attachment_name       = "vpc-a-tr-attachment"
  transit_router_attachment_description = "VPC A to Transit Router"

  # 指定 landing 子网
  vpc_id   = var.vpc_a_id
  zone     = var.vpc_a_zone
}

Terraform 管理的好处:

  • 网络变更可审计(terraform plan 预览变更,terraform apply 执行)
  • 环境可复制(一份代码创建相同架构的 dev/staging 环境)
  • 变更可回滚(terraform state 记录所有资源状态)

想深入了解 Terraform State 管理?可以看相关文章:状态文件丢了怎么办。

路由策略配置实例

以下是一个生产环境的路由策略配置,实现环境隔离:

#!/usr/bin/env python3
"""
VPC 路由策略自动检查脚本
检查转发路由器路由表中是否存在违规路由
"""

import boto3
import json
from datetime import datetime

class TransitGatewayRouteChecker:
    def __init__(self, region="cn-hangzhou"):
        self.ec2 = boto3.client("ec2", region_name=region)
        # 违规路由规则定义
        self.violation_rules = [
            # 测试环境不能访问生产数据库
            {"source": "10.3.0.0/18", "dest": "10.1.8.0/22", "action": "should_not_exist"},
            # 开发环境不能访问生产任何子网
            {"source": "10.3.64.0/18", "dest": "10.1.0.0/18", "action": "should_not_exist"},
        ]

    def get_tgw_route_tables(self, tgw_id):
        """获取 Transit Gateway 所有路由表"""
        response = self.ec2.describe_transit_gateway_route_tables(
            Filters=[{"Name": "transit-gateway-id", "Values": [tgw_id]}]
        )
        return response.get("TransitGatewayRouteTables", [])

    def get_routes(self, route_table_id):
        """获取路由表中的所有路由"""
        response = self.ec2.search_transit_gateway_routes(
            TransitGatewayRouteTableId=route_table_id,
            Filters=[{"Name": "state", "Values": ["active", "pending"]}],
        )
        return response.get("Routes", [])

    def check_violations(self, tgw_id):
        """检查是否存在违规路由"""
        route_tables = self.get_tgw_route_tables(tgw_id)
        violations = []

        for rt in route_tables:
            routes = self.get_routes(rt["TransitGatewayRouteTableId"])
            for route in routes:
                for rule in self.violation_rules:
                    if (route.get("DestinationCidr") == rule["dest"] and
                        route.get("Source"):
                        violations.append({
                            "route_table": rt["TransitGatewayRouteTableId"],
                            "destination": route.get("DestinationCidr"),
                            "rule": rule,
                            "timestamp": datetime.now().isoformat(),
                        })

        return violations

    def report(self, tgw_id):
        """生成检查报告"""
        violations = self.check_violations(tgw_id)
        if violations:
            print(f"[ALERT] 发现 {len(violations)} 条违规路由:")
            for v in violations:
                print(f"  - 路由表 {v['route_table']}: "
                      f"dest={v['destination']} "
                      f"violates rule={v['rule']}")
            # 发送告警
            self._send_alert(violations)
        else:
            print("[OK] 路由策略检查通过,无违规路由")

    def _send_alert(self, violations):
        """发送告警到飞书/钉钉(简化示例)"""
        # 实际项目中对接飞书 webhook
        print(f"  -> 已发送告警,{len(violations)} 条违规")


if __name__ == "__main__":
    checker = TransitGatewayRouteChecker(region="cn-hangzhou")
    checker.report("tgw-xxx")

网络连通性验证

迁移或变更后,必须验证网络连通性。不要只测 ping——ICMP 通不代表 TCP 通,TCP 通不代表应用层通。

#!/bin/bash
# VPC 间连通性验证脚本
# 用法: ./vpc_connectivity_check.sh <source_ip> <target_ip> <target_port>

SOURCE_IP=$1
TARGET_IP=$2
TARGET_PORT=${3:-80}

echo "=== VPC 连通性验证 ==="
echo "源: $SOURCE_IP"
echo "目标: $TARGET_IP:$TARGET_PORT"
echo ""

# Layer 3: ICMP 连通性
echo -n "[L3] ICMP ping... "
if ping -c 3 -W 2 "$TARGET_IP" > /dev/null 2>&1; then
    echo "OK"
else
    echo "FAILED"
    echo "  -> 检查路由表是否有回指路由"
    echo "  -> 检查安全组是否放通 ICMP"
    exit 1
fi

# Layer 4: TCP 端口连通性
echo -n "[L4] TCP $TARGET_PORT... "
if timeout 3 bash -c "echo > /dev/tcp/$TARGET_IP/$TARGET_PORT" 2>/dev/null; then
    echo "OK"
else
    echo "FAILED"
    echo "  -> 检查安全组入站规则是否放通 $TARGET_PORT"
    echo "  -> 检查目标实例防火墙 (iptables/firewalld)"
    exit 1
fi

# Layer 7: HTTP 响应
echo -n "[L7] HTTP 请求... "
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 3 \
    "http://$TARGET_IP:$TARGET_PORT/" 2>/dev/null)
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 500 ]; then
    echo "OK ($HTTP_CODE)"
else
    echo "FAILED ($HTTP_CODE)"
    echo "  -> 检查应用服务是否正常运行"
    echo "  -> 检查应用日志"
    exit 1
fi

echo ""
echo "=== 全部检查通过 ==="

分层验证的重要性:某次迁移后,ping 通了,运维同学就报告"网络通了"。结果业务一跑就报超时。排查发现路由表只配了 ICMP 的回指路由,TCP 的路由指向了旧的 Peering。分层验证能避免这种"看起来通了实际没通"的问题。

监控与告警

VPC 网络监控要关注几个核心指标:

指标采集方式告警阈值说明
跨 VPC 流量VPC Flow Log + 聚合>基线 200%突增可能是异常或攻击
Peering 连接丢包CloudWatch / 云监控>0.1%Peering 质量下降
TGW/TR 包丢弃TGW 指标 / TR 指标>0.01%网关过载信号
跨地域延迟拨测监控>基线 +50ms骨干网质量下降
路由表变更CloudTrail / 操作审计任何变更路由变更需审计

在监控系统建设方面,可以参考相关文章:告警策略设计的经验。告警触达 5 秒、故障定位从 30 分钟降到 8 分钟,这套体系同样适用于网络监控。

Prometheus 采集 VPC 网络指标

用 Prometheus + CloudWatch Exporter(或阿里云云监控 Exporter)可以统一采集跨 VPC 网络指标。以下是核心 PromQL 告警规则:

# Prometheus 告警规则:VPC 网络异常
groups:
  - name: vpc-network-alerts
    rules:
      # Peering 连接丢包率超阈值
      - alert: VpcPeeringPacketLoss
        expr: |
          rate(aws_vpc_peering_packets_drop_total[5m])
          / rate(aws_vpc_peering_packets_total[5m]) > 0.001          
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "VPC Peering 丢包率超阈值"
          description: "Peering {{ $labels.peering_id }} 丢包率: {{ $value }}"

      # Transit Gateway 包丢弃
      - alert: TgwPacketDrop
        expr: rate(aws_tgw_packets_drop_total[5m]) > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Transit Gateway 包丢弃"
          description: "TGW {{ $labels.tgw_id }} 持续丢弃包超过 5 分钟"

      # 跨 VPC 延迟突增
      - alert: CrossVpcLatencySpike
        expr: |
          histogram_quantile(0.99,
            rate(vpc_cross_latency_seconds_bucket[5m])) > 0.1          
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "跨 VPC P99 延迟超 100ms"
          description: "{{ $labels.source }} -> {{ $labels.target }}: {{ $value }}s"

指标采集延迟问题:CloudWatch 指标默认有 1-5 分钟延迟。对于网络故障来说,5 分钟延迟意味着用户已经报障了你才看到指标异常。解决方案是在关键链路上部署自定义拨测——用一台实例每 10 秒 ping 目标 VPC 的实例,结果写入 Prometheus。这样延迟降到 10-15 秒。

在某出行项目中,我用这个方案把跨 VPC 通信故障的发现时间从 5 分钟(CloudWatch 延迟)降到 15 秒(自定义拨测),给故障定位争取了 4 分 45 秒。别小看这几分钟,对一个日订单百万级的出行平台来说,4 分钟的故障暴露窗口意味着约 2800 笔订单可能受影响。

常见故障场景与排查

以下是三个真实故障场景的排查过程,每个给出根因和修复方式。

场景一:迁移后部分 VPC 不可达

现象:VPC-A 迁移到 Transit Gateway 后,VPC-A 可以访问 VPC-B,但 VPC-B 无法访问 VPC-A。

根因:VPC-A 的路由表中,回指路由指向了旧的 Peering(已在 TGW 迁移中删除),导致 VPC-A 的响应包无法路由到 VPC-B。

# 检查 VPC-A 路由表中的回指路由
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-a-id" \
  --query 'RouteTables[0].Routes[?DestinationCidrBlock==`10.2.0.0/16`]'
# 输出:GatewayId 指向已删除的 pcx-xxx

# 修复:将回指路由指向 Transit Gateway
aws ec2 replace-route \
  --route-table-id rtb-xxx \
  --destination-cidr-block 10.2.0.0/16 \
  --transit-gateway-id tgw-xxx

场景二:Peering 和 TGW 路由冲突

现象:VPC-A 和 VPC-B 之间同时存在 Peering 和 TGW 连接,流量间歇性走错路径。

根因:TGW 路由传播自动添加了 10.2.0.0/16 路由,与手动配置的 Peering 路由(同样指向 10.2.0.0/16)冲突。AWS 规则是传播路由优先于手动路由。

修复:在 TGW 路由表中配置前缀过滤,不让 10.2.0.0/16 通过 TGG 传播,强制流量走 Peering。

场景三:CIDR 重叠导致 Peering 建立失败

现象:新 VPC 使用了 10.1.0.0/16,与已有 VPC 的 10.1.0.0/18 重叠,Peering 建立失败。

根因:CIDR 包含关系。虽然不是完全重叠,但 10.1.0.0/18 是 10.1.0.0/16 的子网,AWS Peering 要求 CIDR 不能有包含关系。

修复:将新 VPC 的 CIDR 改为 10.5.0.0/16,与现有所有 VPC 无重叠。这个问题的教训是——CIDR 规划必须提前做,不能等建 VPC 时才发现冲突。

故障排查 checklist

当跨 VPC 通信不通时,按以下顺序排查:

# Step 1: 检查 VPC Peering 连接状态
aws ec2 describe-vpc-peering-connections \
  --filters "Name=requester-vpc-info.vpc-id,Values=vpc-xxx" \
  --query 'VpcPeeringConnections[*].[Id,Status.Code]' \
  --output table

# Step 2: 检查路由表是否有 Peering 路由
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-xxx" \
  --query 'RouteTables[*].Routes[?GatewayId!=`null` && contains(GatewayId, `pcx`)]' \
  --output table

# Step 3: 检查安全组规则
aws ec2 describe-security-groups \
  --filters "Name=vpc-id,Values=vpc-xxx" \
  --query 'SecurityGroups[*].IpPermissions[*].[IpProtocol,FromPort,IpRanges[*].CidrIp]' \
  --output table

# Step 4: 检查 Transit Gateway 路由传播
aws ec2 search-transit-gateway-routes \
  --transit-gateway-route-table-id tgw-rtb-xxx \
  --filters "Name=state,Values=active" \
  --output table

# Step 5: 检查网络 ACL
aws ec2 describe-network-acls \
  --filters "Name=vpc-id,Values=vpc-xxx" \
  --query 'NetworkAcls[*].Entries[?Egress==`false`]' \
  --output table

排查口诀:一查连接状态,二查路由表,三查安全组,四查 TGW 路由,五查 NACL。80% 的 VPC 网络问题出在前三步。

容灾与回滚

网络架构容灾设计

转发路由器虽然比 Peering 多了一个中心节点,但这个节点本身也有高可用设计。AWS Transit Gateway 在每个可用区部署弹性网络接口,阿里云转发路由器要求至少两个可用区的子网。但仍然存在单 Region 故障风险。

跨 Region 容灾方案:

  1. 在两个 Region 各部署一个 Transit Gateway / 转发路由器
  2. 通过跨地域 Peering 连接两个网关
  3. 每个 VPC 接入本 Region 的网关
  4. 跨 Region 流量通过网关 Peering 中转
  5. DNS 层面做流量切换——主 Region 故障时切到备 Region

回滚方案:

如果从 Peering 迁移到 Transit Gateway 后出现问题,需要回滚:

  1. 确保旧 Peering 连接没有删除(迁移期间保留 30 天)
  2. 在路由表中恢复 Peering 路由的优先级
  3. 验证流量恢复走 Peering
  4. 删除 Transit Gateway Attachment(不影响 Peering)

关键:迁移期间不要删除旧 Peering 连接。保留 30 天作为回滚窗口。只有在确认新架构稳定运行 30 天后才清理旧连接。这个经验来自相关文章:变更管理灰度发布与回滚策略——变更管理的关键不是"变更能不能成功",而是"变更失败后能不能回滚"。

总结

回顾一下 5 个生产级决策:

  1. 迁移时机:VPC 达到 8 个开始规划从 Full Mesh 到 Hub-Spoke 的迁移,12 个必须完成。不要等维护不下去才动手,那时候变更风险已经很大了。

  2. CIDR 规划:第一个 VPC 创建前花一天做全网规划。按环境分大段、按地域分小段、预留 30% 扩展空间、为 TR 预留 landing 子网。地基不打好,后面全是返工。

  3. 混合组网:高流量对用 Peering(免费无限制),其余走转发路由器。用共享服务账号承载转发路由器费用,分摊到各业务线。路由优先级要配好,别让传播路由覆盖 Peering 路径。

  4. 跨地域计费:稳态流量用带宽包,突发流量用按流量付费。算 30 天历史数据做决策,混合方案通常最优。配限速策略防止突发流量失控。

  5. 安全隔离:转发路由器路由策略做 L3 隔离,安全组做 L4 控制,WAF 做 L7 防护。两层防御比单层安全组可靠。等保审计认声明式路由策略,不认临时改的安全组规则。

云原生网络架构选型的核心不是选"最好的方案",而是在 VPC 数量、流量模型、管控需求和成本之间找到当前阶段的最优解。方案 A 到方案 C 不是非此即彼,而是随业务规模演进的升级路径。关键是知道什么时候该切换——别等架构固化了才后悔没早做决策。

最后说一句关于多云网络的观点:如果你不是被迫做多云(合规要求、客户要求),别主动搞多云。跨云网络互联的复杂度是单云的 3 倍以上,故障域也更宽。在单云把网络架构理顺,比在多云之间疲于奔命要务实得多。

参考资料与致谢

本文在撰写过程中参考了以下资料,感谢原作者的贡献:

  1. VPC peering - AWS Whitepapers — AWS,VPC Peering 的官方文档,明确说明不支持传递路由
  2. Amazon Transit Gateway — AWS,Transit Gateway 官方产品页,Hub-Spoke 模型说明
  3. Amazon Transit Gateway pricing — AWS,Transit Gateway 计费规则
  4. 什么是云企业网? — 阿里云,CEN 转发路由器核心概念
  5. 基于VPC对等连接与转发路由器组合实现多VPC互通方案 — 阿里云,混合组网方案与 Peering vs 转发路由器对比表
  6. CEN转发路由器企业级云上组网场景化实践 — 阿里云,转发路由器 landing 子网规划实践
  7. 跨地域连接 — 阿里云,跨地域连接的带宽包与按流量付费对比
  8. Segmenting hybrid networks with AWS Transit Gateway connect — AWS,用 Transit Gateway Connect 和 VRF 实现混合网络分段隔离
  9. 同地域多VPC网络设计 — 阿里云,Well-Architected 框架下的多 VPC 设计
  10. 企业SD-WAN 组网与公有云打通:多云接入架构设计与踩坑记录 — 腾讯云开发者社区,多云接入场景的路由冲突与 QoS 踩坑经验