摘要:雖然網卡是接入RoCE網路,但其實問題本身是單純路由相關的,所以看的時候,不用關注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,所以這里監聽這個網卡):
tcpdump -i enp80s0f0 -n arp listening on enp80s0f0, link-type EN10MB (Ethernet), capture size 262144 bytes 17:02:23.720556 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 46 17:02:24.758954 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 46 17:02:25.782954 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 46 17:02:26.807063 ARP, Request who-has 29.28.195.228 tell 29.28.204.80, length 46 ^C
可以看到,報文能到B,
2.但是為什么B不給A回訊息呢?
于是我們來看看,當B要給A回訊息時,路由怎么走的?
查看路由表:
ip route default via 192.168.0.1 dev enp218s0 proto dhcp metric 104 29.28.192.0/20 dev enp137s0f1 proto kernel scope link src 29.28.201.211 metric 105 29.28.192.0/20 dev enp137s0f0 proto kernel scope link src 29.28.193.28 metric 106 29.28.192.0/20 dev enp80s0f1 proto kernel scope link src 29.28.204.230 metric 107 29.28.192.0/20 dev enp106s0f0 proto kernel scope link src 29.28.194.199 metric 108 29.28.192.0/20 dev enp106s0f1 proto kernel scope link src 29.28.195.31 metric 109 29.28.192.0/20 dev enp80s0f0 proto kernel scope link src 29.28.195.228 metric 110 29.28.192.0/20 dev enp234s0f1 proto kernel scope link src 29.28.197.165 metric 111 29.28.192.0/20 dev enp234s0f0 proto kernel scope link src 29.28.195.75 metric 112
根據以前學的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 這個檔案中,
255 local 254 main 253 default 0 unspec
我們之前學的 route -n 新手村表,就是其中的 254 這個副本號,名字叫做 main,
要增加副本,可以如下這么操作:
echo "$id $table" >> /etc/iproute2/rt_tables
就行了,
2. 如何決定使用哪個“副本”
為了確認使用哪個“副本”,在前面補了一個 rule 規則,
條件基本就是:源IP,目的地址,收到網口這些,
具體見:https://www.computerhope.com/unix/ip.htm
所以現在流程變成了:
- 新增一個副本
- 設定rule規則,指向這個新增的副本
- 往副本里面增加以前學會的route記錄
比如,我們希望某個源IP為 29.28.201.211 的報文,走獨立的“路由副本”策略:
- 新建“路由副本”
echo "200 table0" >> /etc/iproute2/rt_tables
- 增加規則,使這種報文,走該獨立副本,(from表示源ip)
ip rule add from 29.28.201.211 table table0
- 然后我們往這個“路由表副本”里面,放入以前學到的普通的路由規則:
ip route add 29.28.192.0/20 dev eth0 table table0
- 可以確認下副本中路由是否正確
ip route show table table0 29.28.192.0/20 dev eth0 scope link
這樣,我們就可以控制更復雜的路由規則了,
3. 再看“新手村”路由表
在知道路由表可以有很多“副本”之后,我們再回頭看看原來那個“新手村”,
從 /etc/iproute2/rt_tables 檔案內容可以知道,咱們“新手村”對應的那個路標表名字叫做main,
所以查詢這個表的內容:
root@tsjsdbd:/# ip route show table main default via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
這個和我們平時看到的路由,是一樣的:
root@tsjsdbd:/# ip route default via 172.17.0.1 dev eth0 172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
也就是,我們平時敲的 route -n 看到的串列,其實就是 main 這張表里面的內容,
其余表(0-local,253-default,255-local)的內容,一般不用關注,
4. rule規則匹配優先級
在rule規則表里面,很多記錄的時候,匹配優先級是怎么定的?答案是每一條記錄,它有個優先級的欄位,如下:
[root@tsjsdbd]# ip rule 0: from all lookup local 32766: from all lookup main 32767: from all lookup default
最前面的數字,就是優先級,數字越小,優先級越高,也就是會先進行匹配,同時也代表這條規則可以排的更靠前,
在 rule add 添加規則的時候,是可以指定“優先級的”,如:
ip rule add from 192.168.1.0/24 table table0 pri 333
就可以指定
在不指定優先級的情況下,會默認加到當前最小值前面(即,不指定優先值時,會加一條優先級較高的rule),
如下:
[root@tsjsdbd]# ip rule add from 192.168.1.0/24 table table0 pri 333
上面這潭訓加一條333優先級的rule
[root@tsjsdbd]# ip rule add from 192.168.2.0/24 table table0
這條沒指定優先級,就會加一條優先級332的(因為當前rule里面最小的是333),
可以查詢確認:
[root@tsjsdbd]# ip rule 0: from all lookup local 332: from 192.168.2.0/24 lookup table0 333: from 192.168.1.0/24 lookup table0 32766: from all lookup main 32767: from all lookup default
洗掉rule的話,有幾種便捷的指定方式:(優先級、條件、table)
ip rule del pri 333 ip rule del from 192.168.2.0/24 ip rule del table table0
最后注意,添加或修改了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個)
/root # cat /etc/iproute2/rt_tables 200 table0 201 table1 202 table2 203 table3 204 table4 205 table5 206 table6 207 table7
- rule表(8個)
/root # ip rule 0: from all lookup local 32758: from 29.28.197.165 lookup table7 32759: from 29.28.195.75 lookup table6 32760: from 29.28.201.211 lookup table5 32761: from 29.28.193.28 lookup table4 32762: from 29.28.195.31 lookup table3 32763: from 29.28.194.199 lookup table2 32764: from 29.28.204.230 lookup table1 32765: from 29.28.195.228 lookup table0 32766: from all lookup main 32767: from all lookup default
- 每個table表里面,1條路由規則
/root # ip route show table table5 29.28.192.0/20 dev enp137s0f1 scope link src 29.28.201.211
以上3步行為,通過一個腳本來完成,
六、最后
最后我們來看看,網路有問題的時候,與設定完「源地址路由」后的區別:
查詢“以xx為源ip,以yy為目的ip,路由選擇結果是什么”方式,
可以使用ip route get 命令,
設定前:
# ip route get 29.28.204.80 from 29.28.201.211 29.28.204.80 from 29.28.201.211 dev enp137s0f0 uid 0
設定后:
# ip route get 29.28.204.80 from 29.28.201.211 29.28.204.80 from 29.28.201.211 dev enp137s0f1 table table5 uid 0
可以看到,是按照我們的目標“哪個口來,哪個口回去”的方式運行的,
注:雖然網卡是接入RoCE網路,但其實問題本身是單純路由相關的,所以看的時候,不用關注RoCE,只當做一個獨立子網就行了,
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/553577.html
標籤:其他
上一篇:Java基本語法
下一篇:返回列表
