华为云 VPC 对等连接跨网段访问不通的一次完整排查:路由、安全组与网络 ACL 三层比对
华为云 VPC 对等连接跨网段访问不通的一次完整排查:路由、安全组与网络 ACL 三层比对
一、问题现场
我们生产环境有两个 VPC:VPC-A(10.0.0.0/16)跑业务服务,VPC-B(10.1.0.0/16)放数据库和缓存,两者之间用一条 VPC 对等连接打通,已经稳定运行了大半年。上周做了一次扩容,在 VPC-A 下新增子网 A2(10.0.2.0/24),把一批新部署的订单服务放进去。
上线当天下午,监控开始报「订单库连接超时」。奇怪的是同一个应用,老节点(在 A1,10.0.1.0/24)连数据库完全正常,只有 A2 里的新节点连不上 B1(10.1.1.0/24)的 3306 端口。先在应用侧确认配置:连接串、账号、连接池参数都是从同一份配置中心下发的,A1 和 A2 没有差异。telnet 测试也很直白:
A1 节点 telnet 10.1.1.12 3306 → Connected
A2 节点 telnet 10.1.1.12 3306 → Trying... 超时
所以不是应用问题,是网络路径。
二、第一层:先确定包在哪一跳消失
这类问题最怕一上来就猜配置,我习惯先在两端同时抓包,把「发出去了没」「回来了没」这两件事分开。
在数据库节点上开 tcpdump 抓 3306:从 A1 来的 SYN 能抓到,SYN-ACK 也正常回;从 A2 来的 SYN 一个都没有。也就是说 A2 的包根本没到达数据库网卡,问题出在去程,或者 VPC-B 侧对 A2 的回程路由。
这里有个容易误判的点:ping 测的是 ICMP,telnet 测的是 TCP。当时 ping 网关是通的,一度以为链路没问题。实际上 VPC 内网关的 ICMP 响应跟跨对等连接的转发路径不是一回事,两者不能互相替代。遇到「部分子网不通」,一定要用目标端口去测,不要拿网关连通性当结论。
三、第二层:路由表——按 /24 加路由,扩容后必然漏
登录 VPC 控制台看 VPC-B 的路由表,对等连接那几条目的地址写得很清楚:
10.0.1.0/24 → peering-xxx
10.0.0.0/16 → local
当初建对等连接时,路由是按「当时已有的子网」一条条 /24 加的,扩容新增的 10.0.2.0/24 从来没补进去。A2 的 SYN 到了 VPC-B 之后,回程包查不到去 10.0.2.0/24 的路由,直接被丢弃。
修复方式不是再加一条 /24,而是把目的地址改成整个对端 CIDR:
10.0.0.0/16 → peering-xxx
两端路由表都要这么改(VPC-A 侧同样指向 10.1.0.0/16)。按聚合网段写,以后再扩子网就不用回头改路由。这一步做完,A2 的 SYN 终于出现在数据库网卡上,但连接仍然超时。
四、第三层:安全组——作用域也要跟着扩容
继续抓包,这次看到 A2 的 SYN 到了,但数据库没有回 SYN-ACK。这就排除了路由,指向访问控制。
B1 上挂的数据库安全组,入方向 3306 规则写的是:
允许 10.0.1.0/24 TCP:3306
同样是按老子网硬编码的 IP 段,A2 不在授权范围里,包在实例网卡前就被丢了。把规则改成引用整个 VPC-A 的 CIDR,或者更稳妥一点——引用业务服务所在的安全组 ID 作为源,这样节点扩到哪个子网都不用动规则。
改完再测,数据库回了 SYN-ACK,但 A2 依然收不到。
五、第四层:网络 ACL 是无状态的,回程临时端口要单独放行
剩下的嫌疑就是子网级别的 ACL。A2 是新建子网,关联的是一份从模板复制来的 ACL,入方向只放行了几个业务端口,出方向倒是全放。
关键点在于:安全组是有状态的(放行入方向就自动允许对应回程),而网络 ACL 是无状态的,进和出都要显式匹配规则。A2 发起连接时用的是随机临时端口(比如 45210),数据库回包的目的端口就是这个 45210。如果 ACL 入方向没有放行临时端口段,回包会在子网边界被丢掉,表现恰好就是「服务端发了 SYN-ACK,客户端收不到」。
在 A2 关联的 ACL 入方向补一条:
允许 10.1.0.0/16 TCP:1024-65535
保存后立即生效,telnet 秒连,应用报错清零。
六、根因与修复清单
这次是三个独立配置叠加造成的,而且都源于同一个动作:扩容新子网时只改了「计算资源」,没有同步改「网络策略」。
- VPC-B 对等连接路由按 /24 硬编码,漏 10.0.2.0/24 → 改为按对端整段 CIDR 聚合,两端都要配。
- 2. 数据库安全组入方向按 /24 硬编码 → 改为引用对端 VPC CIDR 或源安全组 ID。
- 3. 新子网 ACL 入方向缺少临时端口放行 → 补 1024-65535,并注意 ACL 无状态、进出都要管。
七、复盘
把排查顺序固化成一张清单,后来又用上了两次:先两端抓包确认是去程断还是回程断 → 查两端路由表(看是不是按子网硬编码,优先改成聚合 CIDR)→ 查安全组规则的作用域 → 查网络 ACL 的无状态回程规则。每一步都用「改完立刻 telnet + 抓包」验证,不要在改完配置后靠猜。
另一个教训是:任何按 IP 段硬编码的访问控制,在弹性扩容场景里都是隐性债务。能用 CIDR 聚合就用聚合,能引用安全组 ID 就引用 ID,把「新增子网需要同步改哪些地方」这件事从人肉记忆里挪出去。这次三个根因,本质上是同一个习惯问题在三个不同层面各犯了一次。
- 点赞
- 收藏
- 关注作者
评论(0)