RoCE 多网卡时,报文可以过去,但是回不来
本文分享自华为云社区《<跟唐老师学习云网络> - RoCE多网卡时,报文可以过去,但是回不来》,作者: tsjsdbd 。
一、网络概要
一台机子,接入 2 个子网,一个普通通信的,一个高速通信的。并且接入高速通信子网,有 8 张网卡。如下图:
本文描述的问题,只关注高速子网这一部分。为帮助理解问题,网络可以简化为:
每个网卡,都有分配该子网的一个 IP。如下:
二、问题现象
A 只能通 B 里面的一个 IP,其余 7 个 IP 都不通。下图为 A--->B 的结果:
图示:只有 1 个 IP 能通
反过来也一样,后面只讲一个方向的(A-->B)。
三、问题定位
1. 先看报文有没有到达 B。
如果都不能到 B,说明网络接的有问题。如果到了 B,但是不回来,说明路由配置可能有问题。
Ping 不通的 ip(228)时,在主机 B 上面进行抓包分析(228 对应的网卡名是 enp80s0f0,所以这里监听这个网卡):
可以看到,报文能到 B。
2. 但是为什么 B 不给 A 回消息呢?
于是我们来看看,当 B 要给 A 回消息时,路由怎么走的?
查看路由表:
根据以前学的 router 知识,可以看到,(排除 default 路由外)应该是会匹配到 第 1 条(标红)规则。
注:metric 表示路由代价,目的子网都匹配的情况下,会选代价最低的那一条。
即 B-->A 给 A 回消息时,报文要从 网卡 enp137s0f1 发出去,并且发出去的报文源地址要设为 29.28.201.211。
难怪不通,因为答非所问了嘛(回 arp 报文,内容对不上)。
再看为什么 211 这个 ip 能通?
因为 211 是该子网路由选择,所对应的 IP,所以刚好能通。
这就解释了为什么刚好 1 个 IP 能通,另外 7 个不通。
3. 如何让报文从哪个口收到,就从哪个口回去?
往外发报文,根据源地址来选择网卡(注意这里的源是指 主机 B,因为回报文是往外发),这种场景可以称之为「源地址路由」,而要实现源地址路由,就需要用到「ip rule 路由策略」这种高级路由配置。
四、ip rule 路由策略
在配置「源地址路由」规则前,我们需要先补充一点基础知识。
1. 路由表“副本”
以前我们学的 route -n 路由表,其实属于“新手村”,即系统默认使用这张路由规则表。但就像《剑来》里面说的那样,在新手村外还有很多其他“境界”。Linux 新版本(2.x 之后)为实现更复杂的路由能力,将原来的“新手村”,复制了很多的“副本”。
Ps:这种增加“副本”的思路,在咱们 IT 领域非常常见,比如我们之前学到的各种 namespace。
当前系统总的“副本”数量,在 /etc/iproute2/rt_tables 这个文件中。
我们之前学的 route -n 新手村表,就是其中的 254 这个副本号,名字叫做 main。
要增加副本,可以如下这么操作:
就行了。
2. 如何决定使用哪个“副本”
为了确认使用哪个“副本”,在前面补了一个 rule 规则。
条件基本就是:源 IP,目的地址,收到网口这些。
具体见:https://www.computerhope.com/unix/ip.htm
所以现在流程变成了:
新增一个副本
设置 rule 规则,指向这个新增的副本
往副本里面增加以前学会的 route 记录
比如,我们希望某个源 IP 为 29.28.201.211 的报文,走独立的“路由副本”策略:
新建“路由副本”
增加规则,使这种报文,走该独立副本。(from 表示源 ip)
然后我们往这个“路由表副本”里面,放入以前学到的普通的路由规则:
可以确认下副本中路由是否正确
这样,我们就可以控制更复杂的路由规则了。
3. 再看“新手村”路由表
在知道路由表可以有很多“副本”之后,我们再回头看看原来那个“新手村”。
从 /etc/iproute2/rt_tables 文件内容可以知道,咱们“新手村”对应的那个路标表名字叫做 main。
所以查询这个表的内容:
这个和我们平时看到的路由,是一样的:
也就是,我们平时敲的 route -n 看到的列表,其实就是 main 这张表里面的内容。
其余表(0-local,253-default,255-local)的内容,一般不用关注。
4. rule 规则匹配优先级
在 rule 规则表里面,很多记录的时候,匹配优先级是怎么定的?答案是每一条记录,它有个优先级的字段。
如下:
最前面的数字,就是优先级。数字越小,优先级越高,也就是会先进行匹配,同时也代表这条规则可以排的更靠前。
在 rule add 添加规则的时候,是可以指定“优先级的”。如:
就可以指定
在不指定优先级的情况下,会默认加到当前最小值前面(即,不指定优先值时,会加一条优先级较高的 rule)。
如下:
上面这条会加一条 333 优先级的 rule
这条没指定优先级,就会加一条优先级 332 的(因为当前 rule 里面最小的是 333)。
可以查询确认:
删除 rule 的话,有几种便捷的指定方式:(优先级、条件、table)
最后注意,添加或修改了 rule 规则后,不会立即生效,需要 ip route flush cache 后才生效(官方文档是这么说的,自己验证的时候注意下就行)。
五、源地址路由
再回到问题上来,8 个网卡,哪个口收到,要求使用该口的 ip 回去。可以通过 8 个路由 table 实现(因为大家的目标网段是一样的,所以在同一个 table 表里面话,不好写规则)。
于是,可以把 8 个路由规则,分散到 8 个“世界”中,然后通过 rule 分散后,各自进行匹配。
事实上,「源地址路由」的实现,一般都是这种套路:
添加一条“源地址”的 rule
ip rule add from 192.168.1.2 table 100
在目标 table 里面,设置路由规则
ip route add 172.25.2.0/24 via 192.168.1.5 table 100
最终解决 8 个 RoCE 网卡可以互通的路由设置如下:
table 表(8 个)
rule 表(8 个)
每个 table 表里面,1 条路由规则
以上 3 步行为,通过一个脚本来完成。
六、最后
最后我们来看看,网络有问题的时候,与设置完「源地址路由」后的区别:
查询“以 xx 为源 ip,以 yy 为目的 ip,路由选择结果是什么”方式,
可以使用 ip route get 命令。
设置前:
设置后:
可以看到,是按照我们的目标“哪个口来,哪个口回去”的方式运行的。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/1454ef9592dd76e0adcf67b13】。文章转载请联系作者。
评论