為什麼我與 multiq 的綁定介面忽略了 tc 的隊列選擇?
在 Debian Buster,核心 5.4.51 上,我有兩個介面
tap0
,並tap1
以模式加入了一個綁定介面balance-xor
以增加吞吐量。但是,有些流量必須通過tap0
. 其餘的我不在乎。從理論上講,bond 驅動程序可以使用
tc
過濾器和 multiq 來做到這一點,如驅動程序文件中所述。我可以在統計數據中看到聲稱使用了隊列,但是檢查兩個介面上的流量表明過濾器沒有得到尊重。這是我所做的:
我將每個分路介面分配給綁定上的隊列,將排隊規則設置為多隊列,然後用於
tc
覆蓋綁定的排隊決策以強制流量192.168.1.100
(例如)始終使用tap0
.# echo "tap0:1" > /sys/class/net/bond0/bonding/queue_id # echo "tap1:2" > /sys/class/net/bond0/bonding/queue_id # tc qdisc add dev bond0 handle 1 root multiq # tc filter add dev bond0 protocol ip parent 1: prio 1 u32 match ip dst \ 192.168.1.100 action skbedit queue_mapping 1
在
tc
統計資訊中,您可以看到實際使用了不同的隊列:# tc -s class show dev bond0 class multiq 1:1 parent 1: Sent 377256252 bytes 2526104 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 class multiq 1:2 parent 1: Sent 21031 bytes 2982 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 class multiq 1:3 parent 1: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0
大多數流量採用通用隊列,特殊流量採用兩個特定於介面的隊列中的第一個。如果我再次刪除
tc filter
,則特定隊列 1:2 上的數據包計數器將停止。(注意bonding driver和tc之間的queue編號偏移1,所以queue 1:1的意思是“讓driver決定”,queue 1:2的意思是“一直通過
tap0
”,queue 1:3的意思是“一直走”通過tap1
“)隊列也映射到介面:
# cat /proc/net/bonding/bond Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011) Bonding Mode: load balancing (xor) Transmit Hash Policy: layer3+4 (1) MII Status: up MII Polling Interval (ms): 1000 Up Delay (ms): 0 Down Delay (ms): 0 Peer Notification Delay (ms): 0 Slave Interface: tap0 MII Status: up Speed: 10 Mbps Duplex: full Link Failure Count: 0 Permanent HW addr: xx:xx:xx:xx:xx:89 Slave queue ID: 1 Slave Interface: tap1 MII Status: up Speed: 10 Mbps Duplex: full Link Failure Count: 0 Permanent HW addr: xx:xx:xx:xx:xx:d6 Slave queue ID: 2
如果我
tcpdump
分別在接收端的兩個tap,我可以清楚地看到無論使用哪個隊列,特殊流量實際上仍然使用balance-xor
規則使用任一介面。現在 - 我在哪裡錯過了什麼?
好的,深入探勘,文件中有這樣的評論:
此功能首次出現在綁定驅動程序版本 3.7.0 中,並且對輸出從屬選擇的支持僅限於循環和主動備份模式。
Debian Buster 有 3.7.1,顯然支持仍然僅限於這兩種模式,所以我目前正在嘗試做的事情是不可能的。您可以將模式設置為
active-backup
並立即尊重隊列。這當然違背了負載平衡的目的。我曾希望使用任何其他模式會引起某種警告,但事實並非如此。司機只是高興地忽略了你告訴它做什麼。您可能需要做的唯一一件事是允許在非活動介面上輸入數據包,否則您重定向的數據包
tc
將被丟棄:# echo 1 > /sys/class/net/bond0/bonding/all_slaves_active
我假設,如果真的想要,他們現在可以使用一些
tc
魔法來基本上重新實現balance-xor
那裡的邏輯並覆蓋每個數據包的目標隊列。然後可以離開該模式active-backup
但實現負載平衡。或者只是在綁定驅動程序中實現此功能。