引言

某团队在腾讯云上新部署了一套集群,网段规划为 10.0.1.0/24。上线后发现部分服务之间网络互通正常,部分服务却完全不通。排查了安全组、子网 ACL、弹性网卡配置,均未发现问题。最终定位:10.0.1.0/24 子网的路由表里赫然躺着一条 10.0.0.0/8 的默认路由——另一个团队三个月前申请的 VPN 网关遗留配置,覆盖了整段内网地址,所有发往 10.0.1.x 的包被路由到了 VPN 隧道而非直连交换机。

路由表是数据包转发的决策中枢。理解它不仅仅是背下几个字段,而是搞清楚内核在收到一个包时,是如何从成千上万条路由规则中选出唯一一条来执行转发的。

一、路由表:数据包转发的决策依据

1.1 路由表的结构

Linux 的路由表是一张清单,列出了"发往哪些目标网络,走哪个网关,从哪个网卡出去"。用 ip route show(或废弃的 route -n)查看:

# 查看主路由表
ip route show
ip route show table main

# 输出示例
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.100 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.100
192.168.1.0/24 via 10.0.0.254 dev eth0 proto static metric 200

每条路由条目包含以下字段:

字段 含义 示例
destination 目标网络(也可为 default,即 0.0.0.0/0 10.0.0.0/24default
via gateway 下一跳网关 IP(直连网络无需指定) via 10.0.0.254
dev interface 从哪个网卡发出 dev eth0
proto 路由来源:kernel=内核自动生成,dhcp=DHCP 学习,static=手动配置 proto kernel
scope 作用范围:link=仅本链路可达,global=全局可路由 scope link
src 源 IP 选择:发往该目标时使用哪个源地址发出 src 10.0.0.100
metric 优先级:数值越小优先级越高 metric 100

直连网络不需要 via 字段。当目标网络与本机某网卡处于同一网段时,内核直接通过 ARP 获取目标 MAC 地址,将包从对应网卡发出,无需经过任何网关。

1.2 最长前缀匹配:内核如何选路

这是路由转发最核心的算法。当内核收到一个数据包,需要决定"走哪条路"时,它在路由表中执行 Longest Prefix Match(LPM)——在所有匹配目标网络的路由条目中,选择前缀最长的那一条。

待转发数据包

路由表中的条目

匹配:0位前缀

匹配:8位前缀

匹配:24位前缀

匹配:25位前缀

最长前缀 = 最佳匹配

default
0.0.0.0/0
匹配所有地址

10.0.0.0/8
匹配 10.x.x.x

10.0.1.0/24
匹配 10.0.1.x

10.0.1.128/25
匹配 10.0.1.128~191

目标 IP:10.0.1.150

LPM 查找

候选

候选

候选

候选(最优)

10.0.1.128/25
下一跳:10.0.1.129

举例说明:目标 IP 为 10.0.1.150

  • 0.0.0.0/0(default):匹配 0 位前缀 → 候选
  • 10.0.0.0/8:匹配前 8 位(10.) → 候选
  • 10.0.1.0/24:匹配前 24 位(10.0.1.) → 候选
  • 10.0.1.128/25:匹配前 25 位(10.0.1.1),完全匹配 → 最优

内核选择 /25 这条。如果路由表中没有 /24/25,则选择 /8;如果连 /8 也没有,才 fallback 到 default

这就是为什么更精确的路由可以覆盖更宽泛的路由。VPN 网关遗留配置中,10.0.0.0/8 的条目会覆盖所有 10.x.x.x 的直连路由,除非有更精确的条目明确指定了不同的下一跳。

1.3 默认网关:最后的兜底路由

default0.0.0.0/0)是兜底路由。当 LPM 找不到任何匹配条目时,数据包走默认网关。默认网关本身必须与本机处于直连可达的网络中(也就是说,本机路由表中必须有一条路由能够到达网关 IP)。

# 默认网关的作用位置
# 相当于:
ip route add default via 10.0.0.1 dev eth0

# 所有非直连流量 → 10.0.0.1 → 路由器处理

默认网关的配置通常由 DHCP 自动分配,或者在 /etc/sysconfig/network-scripts/ifcfg-eth0(CentOS/RHEL)或 /etc/netplan/01-netcfg.yaml(Ubuntu)中静态指定。

二、策略路由:Linux 的多表路由

标准路由表只能按目标地址做转发决策。但在某些场景下,需要按源地址入接口或** fwmark(防火墙标记)**选择不同的路由策略。Linux 通过 RPDB(Routing Policy Database) 实现这一能力。

2.1 为什么需要策略路由

典型场景:

  • 多出口负载均衡:服务器有两根网卡,分别接入 ISP A 和 ISP B,需要根据目标网络选择不同的出口
  • VPN 透明代理:本应访问内网的流量走 VPN 隧道,其余流量走正常网关
  • 容器网络隔离:Kubernetes Pod 的流量经 CNI 插件走专用网桥,与主机流量分开

2.2 RPDB 的工作原理

RPDB 由一系列规则(rule)组成,每条规则指向一个路由表。数据包转发时,内核按规则优先级(从小到大)逐一匹配,找到第一条匹配的规则后,使用该规则指向的路由表进行转发:

路由表

路由策略数据库(ip rule)

优先级 0
from 127.0.0.0/8
lookup local

优先级 100
from 192.168.1.0/24
lookup ISP_A

优先级 200
from 192.168.2.0/24
lookup ISP_B

优先级 32767
default
lookup main

table local
(系统保留)
本地接口路由

table ISP_A
192.168.1.0/24 直连
default via ISP_A_GW

table ISP_B
192.168.2.0/24 直连
default via ISP_B_GW

table main
普通路由表
(默认表)

核心命令

# 查看所有规则
ip rule show
# 输出示例:
# 0:      from 127.0.0.0/8 lookup local
# 100:    from 192.168.1.0/24 lookup ISP_A
# 200:    from 192.168.2.0/24 lookup ISP_B
# 32766:  from all lookup main
# 32767:  from all lookup default

# 添加一条基于源地址的策略路由
# 来自 192.168.1.0/24 的流量,走 ISP_A 路由表
ip rule add from 192.168.1.0/24 table ISP_A priority 100

# 添加后立即生效
ip route show table ISP_A
# 需要在 ISP_A 表中定义路由
ip route add default via 203.0.113.1 dev eth0 table ISP_A

# 按 fwmark 标记分流(常用于透明代理)
ip rule add fwmark 0x1 table vpn_table priority 50

# 删除规则
ip rule del from 192.168.1.0/24 table ISP_A priority 100

规则优先级ip rulepriority 数值从小到大依次匹配(数值越小越先匹配)。local 表(优先级 0)包含系统自动生成的本地接口直连路由,永远优先匹配。

2.3 Docker/Kubernetes 中的策略路由

容器网络隔离是策略路由最常见的生产应用。Kubernetes CNI 插件(如 Calico、Flannel)在节点上自动创建策略路由,确保 Pod 流量经由正确的网桥和网卡进出:

# 查看节点的策略路由规则(Kubernetes 节点示例)
ip rule show

# 示例输出:
# 0:      from all lookup local
# 32766:  from all lookup main
# 32767:  from all lookup default
# 9000:   from 10.244.1.0/24 lookup cni-plugin    # Calico 为 Pod 网段创建的规则

# 对应的 CNI 路由表
ip route show table cni-plugin
# 输出:default via 10.244.1.1 dev cali0

如果不理解这套机制,修改了节点路由表或安全组规则后,Pod 通信异常的根本原因就很难定位。

三、VPC 场景下的路由冲突

云上生产环境的高频故障之一:路由冲突导致的隐性网络分割

3.1 腾讯云 / 阿里云的路由优先级

云平台 VPC 路由表同样执行 LPM,但平台在用户可见的路由表之上还有系统路由。系统路由的优先级由平台定义,不对用户暴露,当自定义路由与系统路由冲突时,以平台规则为准。

腾讯云路由优先级(从高到低):

  1. 用户自定义路由(精确匹配)
  2. 系统路由(含 NAT 网关、VPN 网关、对等连接的下一跳)
  3. 默认路由(0.0.0.0/0

当两个自定义路由条目前缀长度相同时,平台按路由创建时间排序(先创建优先)。这个行为是隐式的,不会主动告警

3.2 CIDR 重叠:最隐蔽的路由杀手

CIDR 重叠指的是:两个不同业务的 VPC 网段在规划时没有协调,导致地址段交叉或包含。

对等连接

业务 B VPC
(半年前部署)

业务 A VPC

业务 A 认为
10.0.1.128/25 在本 VPC

业务 B 认为
10.0.1.128/25 在本 VPC

对等连接建立后
路由表冲突

CIDR: 10.0.0.0/16
子网: 10.0.1.0/24
新增需求: 10.0.1.128/25

CIDR: 10.0.1.0/24
已运行半年

VPC 对等连接
A ↔ B

路由无效
对等连接无法互通

排查方法

# 腾讯云 CLI:检查 VPC 路由表中的冲突条目
tccli vpc DescribeRouteTables --VpcId vpc-xxxxxxxx

# 阿里云 CLI:检查 CEN 路由冲突
aliyun cen DescribeCenRouteEntries --CenId cen-xxxxxxxx

# 本地诊断:用 ip route 确认本机实际生效路由
ip route get from 10.0.1.150 to 10.0.2.50
# 如果输出显示走了意外的网关,说明路由匹配有问题

解决方案

  • 事前:VPC 网段规划时建立统一的 CIDR 分配表,新业务申请网段前先查询已有分配
  • 事后:缩小冲突子网的掩码(从 /24 缩小到 /26/27),将未被使用的地址段腾出来重新分配

3.3 NAT 网关路由陷阱

在腾讯云中,VPC 内实例访问公网时,如果走 NAT 网关(而非公网 IP 直通),需要在路由表中添加一条 0.0.0.0/0 下一跳指向 NAT 网关的路由。

一个常见失误:手动添加 0.0.0.0/0 路由后,没有删除原有的"默认路由通过 DHCP 分配的公网 IP 直通"配置,导致同一条目标网络同时匹配两条路由。此时云平台按内部权重策略选择一条(行为不可预测),表现为"有时通有时不通"的间歇性故障。

# 腾讯云确认 NAT 网关是否生效
# 查看路由表中是否有多条 default 路由
tccli vpc DescribeRouteTables --VpcId vpc-xxxxxxxx --Filters.0.Name=route-table-id --Filters.0.Values=rtb-xxxxxxxx

# 确保只有一个 default 下一跳指向 NAT 网关

四、traceroute 解读:每跳的含义

traceroute 的输出是理解路由路径的最直接工具。traceroutemtr 显示的每一跳代表一个路由器或三层交换机,每跳的 RTT 反映该设备的处理延迟和链路质量。

4.1 traceroute 输出解读

traceroute to 93.184.216.34 (93.184.216.34), 30 hops max, 60 byte packets
 1  gateway (10.0.0.1)                         0.421 ms  0.385 ms  0.372 ms
 2  183.60.83.1                                1.203 ms  1.189 ms  1.195 ms
 3  10.128.80.1                                2.451 ms  2.389 ms  2.510 ms
 4  72.14.215.85                               5.123 ms  5.089 ms  5.104 ms
 5  *  *  *                                   5.712 ms  5.698 ms  5.723 ms
 6  93.184.216.34                              8.234 ms  8.201 ms  8.189 ms

每列含义

  • 第 1 列:TTL 值,即跳数
  • 第 2 列:路由器 IP(有些路由器关闭了反向 DNS 解析,显示为 IP)
  • 后 3 列:3 次探测的 RTT(毫秒),探测了 3 次取均值

常见模式分析

  • 第 4 跳 RTT 突然从 2ms 跳到 5ms:该路由器或链路开始出现拥塞
  • 第 5 跳全是 *:该路由器关闭了 ICMP 回复(traceroute -T -p 80 改用 TCP 探测可以绕过部分限制)
  • 内网 traceroute 全为 *:中间交换机配置了 ACL,屏蔽了 UDP 探测包,改用 traceroute -I(ICMP)尝试

4.2 用 ip route get 验证本地路由决策

traceroute 查看的是端到端路径,如果问题出在本机出口,可以用 ip route get 直接验证本机对特定目标的路由决策:

# 查询本机对 93.184.216.34 的路由决策
ip route get 93.184.216.34

# 输出示例:
# 93.184.216.34 via 10.0.0.1 dev eth0 src 10.0.0.100 uid 0
#
# 含义:目标 93.184.216.34
#       下一跳网关 10.0.0.1
#       从 eth0 发出
#       源 IP 10.0.0.100

# 查询内网同网段
ip route get 10.0.1.150

# 10.0.1.150 dev eth0 src 10.0.0.100 uid 0
# 直连网络,不需要网关,直接从 eth0 发出

# 如果返回 "Network is unreachable"
# 说明路由表中没有匹配 10.0.1.150 的条目,也没有默认网关

ip route get 是排查"包从哪个网卡出去、源 IP 是什么"的精确工具,比 ping + route -n 的组合快得多。

五、生产路由故障的排查框架

Network is unreachable

默认网关缺失

默认网关存在
但仍不可达

成功返回下一跳

不可达

可达

怀疑策略路由

策略路由覆盖了
本应匹配的路由

无策略路由干扰

不一致

一致

目标 IP 不通

ip route get 目标 IP 成功?

检查路由表
ip route show

默认网关是否存在?

添加默认网关
ip route add default via

检查网关 IP 的 ARP 解析
ip neigh show

下一跳 IP 是否可达?

ping 网关 IP
检查物理链路/交换机配置

策略路由是否干扰?

ip rule show
确认源地址匹配规则

调整 ip rule 优先级
或删除多余规则

VPC 平台路由表
与本地路由表一致?

检查云平台控制台
VPC 路由表条目
确认 CIDR 无重叠

继续排查:安全组/
ACL/连接跟踪/
应用层服务状态

六、总结:路由是分层的

路由决策不是一个扁平的查表过程,而是一个分层决策体系

  • Linux 主机层:RPDB 按 ip rule 优先级 → 选中路由表 → 执行 LPM → 选出转发路径
  • VPC 平台层:平台路由表(含系统路由)→ 用户自定义路由 → LPM → 选出下一跳类型(NAT 网关/VPN/对等连接)
  • 运营商骨干网层:BGP 路由协议 → AS 路径选择 → 选出 ISP 出口

任何一层出错,包就走不到目的地。理解每层的决策机制,才能在故障发生时准确定位"是哪一层的哪条规则出了问题",而不是对着 traceroute 干瞪眼。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐