我有一堆 Linux 服务器,它们有多个(3)NIC 和相关网络接口。我遇到了一个奇怪的路由问题,本应使用默认路由的流量没有使用,因此无法路由。我的路由表如下所示:
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.31.96.1 0.0.0.0 UG 0 0 0 em3
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 em1
10.31.96.0 0.0.0.0 255.255.252.0 U 0 0 0 em3
10.31.96.0 0.0.0.0 255.255.252.0 U 0 0 0 em4
# ip route list
default via 10.31.96.1 dev em3 proto static
10.0.0.0/8 dev em1 proto kernel scope link src 10.0.0.100
10.31.96.0/22 dev em3 proto kernel scope link src 10.31.97.100
10.31.96.0/22 dev em4 proto kernel scope link src 10.31.96.61
10.31.96.1 是我的默认路由,所有流量都应该使用它(em# 是 Fedora 的东西,如果这样更容易理解,您可以放心地在脑海中将看到“em”的地方替换为“eth”)。以下是 ifconfig 输出:
em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.100 netmask 255.0.0.0 broadcast 10.255.255.255
inet6 fe80::b6b5:2fff:fe5b:9e7c prefixlen 64 scopeid 0x20<link>
ether b4:b5:2f:5b:9e:7c txqueuelen 1000 (Ethernet)
RX packets 283922868 bytes 44297545348 (41.2 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 538064680 bytes 108980632740 (101.4 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xfeb60000-feb80000
em3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.31.97.100 netmask 255.255.252.0 broadcast 10.31.99.255
inet6 fe80::b6b5:2fff:fe5b:9e7e prefixlen 64 scopeid 0x20<link>
ether b4:b5:2f:5b:9e:7e txqueuelen 1000 (Ethernet)
RX packets 3733210 bytes 1042607750 (994.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1401537 bytes 114335537 (109.0 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xfea60000-fea80000
em4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.31.96.61 netmask 255.255.252.0 broadcast 10.31.99.255
inet6 fe80::b6b5:2fff:fe5b:9e7f prefixlen 64 scopeid 0x20<link>
ether b4:b5:2f:5b:9e:7f txqueuelen 1000 (Ethernet)
RX packets 2416588 bytes 196633917 (187.5 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 205038 bytes 19363499 (18.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xfeae0000-feb00000
em1/10.0.0.100 连接到连接的交换机仅有的到同一机架中的服务器。它仅用于该机架中的服务器之间进行通信。em3 和 em4 都路由到同一子网。它们之间的唯一区别是 em3 并非始终处于运行状态(它与一个浮动 IP 地址相关联,该地址取决于当前处于“主”角色的服务器)。基本上所有流量都应通过 em3 发出,除非其目的地是本地 10.0.0.1/8 子网上的其他位置,在这种情况下它应通过 em1 发出。然而,事实并非如此。10.31.96.1/16、10.31.97.1/16 和 10.31.99.1/16 流量通过 em3,但目的地是 10.31.45.1/16 的流量试图通过 em1,并且超时,因为没有办法有效地路由该流量。
以下命令也说明了这一点:# tcptraceroute cuda-linux traceroute to cuda-linux (10.31.45.106), 30 hops max, 60 byte packets 1 cuda-fs1a-internal (10.0.0.100) 3006.650 ms !H 3006.624 ms !H 3006.619 ms !H
但是,当从与上述框位于同一网络上的系统运行时,只有一个网络接口,它可以工作:# tcptraceroute cuda-linux traceroute 到 cuda-linux (10.31.45.106),最大 30 跳,40 字节数据包 1 10.31.96.2 (10.31.96.2) 0.345 ms 0.403 ms 0.474 ms 2 cuda-linux (10.31.45.106) 0.209 ms 0.208 ms 0.201 ms
我认为可以通过为 em3 添加到 10.31.45.1 的路由来解决这个问题,但是失败了:
# route add default gw 10.31.45.1 em3
SIOCADDRT: Network is unreachable
我现在不知道还能尝试什么。帮忙吗?
答案1
路由按照从最具体的路由到最不具体的路由(又称默认路由)的顺序进行处理。
default via 10.31.96.1 dev em3 proto static
10.0.0.0/8 dev em1 proto kernel scope link src 10.0.0.100
10.31.96.0/22 dev em3 proto kernel scope link src 10.31.97.100
10.31.96.0/22 dev em4 proto kernel scope link src 10.31.96.61
你说你想要should be going out through em3 unless its destined for something else on the local 10.0.0.1/8 subnet
。这正是正在发生的事情。IP 地址10.31.45.1
在范围内10.0.0.0/8
,因此它将通过 em1 离开。10.0.0.0/8
与该地址匹配的路由比默认路由更具体。该地址与路由不匹配10.31.96.0/22
。因此选择 em1 路由。
真正的问题是,em1 接口上的子网掩码对于您可能需要的子网掩码来说太大,并且与其他网络发生冲突。发往 10.0.0.1-10.255.255.254 范围内 IP 地址的任何内容都会尝试使用 em1,就好像它是本地的一样,10.31.96.0/22 中的地址除外,这些地址将通过 em3/em4 离开。
您的解决方案是修复 em1 子网/网络,以使其不与其他网络冲突,或者添加大量路由。
类似的东西ip route add 10.31.45.0/24 via 10.31.96.1
可能会做你想做的事。