Ubuntu

模擬兩台 ubuntu 伺服器機器之間的慢速連接

  • January 2, 2015

我想模擬以下場景:假設我有 4 台 ubuntu 伺服器機器 A、B、C 和 D。我想將機器 A 和機器 C 之間的網路頻寬減少 20%,將 A 和 B 之間的網路頻寬減少 10%。如何使用網路模擬/節流工具來做到這一點?

為此,您可以tc單獨使用u32過濾器或與iptables 標記結合使用(如果您不想學習複雜的過濾器語法,可能會更直接)。我將在下面的文章中詳細介紹前一種解決方案。

模擬您的設置

例如,讓我們考慮執行 10 Mbit/s虛擬介面的 A、B、C 和 D。

你基本上想要:

  • A <==> B : 9 Mbit/s出口整形
  • A <==> C : 8 Mbit/s出口整形

為了模擬這一點,我將創建 4 個網路命名空間和插入網橋的虛擬乙太網介面。

當然,在您的情況下,您將使用真正的 NIC,而網橋將成為您的網關或交換機,具體取決於您的基礎架構。

因此,在我的模擬中,我們將在 10.0.0.0/24 網路中進行以下設置:

                                 10.0.0.254            

                                 +-------+                     
                                 |       |                     
                                 |  br0  |                     
                                 |       |                   
                                 +---+---+                     
                                     |                         
                                     | veth{A..D}.peer        
                                     |                      
                 +------------+------+-----+------------+     
                 |            |            |            |      
           vethA |      vethB |      vethC |      vethD |      
             +---+---+    +---+---+    +---+---+    +---+---+  
             |       |    |       |    |       |    |       |   
             |   A   |    |   B   |    |   C   |    |   D   |   
             |       |    |       |    |       |    |       |  
             +-------+    +-------+    +-------+    +-------+    

             10.0.0.1      10.0.0.2     10.0.0.3     10.0.0.4           

首先,設置階段,以便您了解它的構成,如果您不熟悉它,請跳過它,沒什麼大不了的。然而,您必須知道的是,該命令ip netns exec &lt;namespace&gt; &lt;command&gt;允許在網路命名空間中執行命令(即,在上一次繪製的方框之一中)。這也將在下一節中使用。

# Create the bridge
ip link add br0 type bridge

# Create network namespaces and veth interfaces and plug them into the bridge
for host in {A..D} ; do 
   ip link netns add ${host}
   ip link add veth${host} type veth peer name veth${host}.peer
   ip link set dev veth${host}.peer master br0
   ip link set dev veth${host} netns ${host}
   ip netns exec ${host} ip link set veth${host} up
done

# Assign IPs
ip addr add 10.0.0.254/24 dev br0
ip netns exec A ip addr add 10.0.0.1/24 dev vethA
ip netns exec B ip addr add 10.0.0.2/24 dev vethB
ip netns exec C ip addr add 10.0.0.3/24 dev vethC
ip netns exec D ip addr add 10.0.0.4/24 dev vethD

所以此時我們已經有了前面描述的設置。

塑造流量

是時候進入交通管制以獲得你想要的了。該tc工具允許您添加排隊規則:

  • 對於 egress :一旦核心需要發送數據包並且在訪問 NIC 驅動程序之前。
  • 對於入口:在訪問 NIC 驅動程序之後,核心常式在接收到的數據包上執行之前。

它帶有 3 個概念:qdisc過濾器。這些概念可用於設置複雜的數據包流管理,並根據您想要的任何標準/標準對流量進行優先級排序。

簡而言之 :

  • Qdiscs 是數據包最終將入隊/出隊的結構。
  • 類是具有特定行為的 qdisc 的容器。
  • 過濾器是在類之間路由數據包的方法,在處理過程中可以在同一個入口點上定義多個過濾器,並具有優先級。

所有這些通常作為一棵樹,其中葉子是 qdisc,類是節點。樹或子樹的根將被聲明為&lt;id&gt;:,子節點將被聲明為&lt;parent_id&gt;:&lt;children_id&gt;。請記住此語法。

對於您的情況,讓我們採用 A 並渲染您想要設置的樹tc

                                    1:
                                     |
                                     |
                                     |
                                    1:1
                                  /  |  \
                                 /   |   \
                                /    |    \
                              1:10  1:20  1:30
                               |     |     |
                               |     |     |
                              :10   :20   :30

解釋 :

  • 1:是附加到設備 vethA 的根 qdisc,它將被明確地htb用於 Hierarchy Token Bucket(設備的預設 qdisc 是pfifopfifo_fast取決於作業系統)。它特別適用於頻寬管理。與此級別定義的過濾器不匹配的數據包將被1:30分類。
  • 1:1將是一個htb將設備的整個流量限制為 10 Mbit/s 的類。
  • 1:10將是一個htb將輸出流量限制為 9 Mbit/s(10 Mbit/s 的 90%)的類。
  • 1:20htb輸出流量限制為 8 Mbit/s(10 Mbit/s 的 80%)的類。
  • 1:30將是一個htb將流量限制為 10 Mbit/s(回退)的類。
  • :10, :20, :30sfq隨機公平隊列的 qdisc。換句話說,這些 qdisc 將確保基於流的傳輸調度的公平性。

整個事情是通過以下命令設置的:

ip netns exec A tc qdisc add dev vethA root handle 1: htb default 30
ip netns exec A tc class add dev vethA parent 1: classid 1:1 htb rate 10mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:10 htb rate 9mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:20 htb rate 8mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:30 htb rate 10mbit burst 15k
ip netns exec A tc qdsic add dev vethA parent 1:10 handle 10: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:20 handle 20: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:30 handle 30: sfq perturb 10

我們需要的最後一件事是添加過濾器,以便目標 IP 等於 B 的1:10IP 數據包進入類別,而目標 IP 等於 C 的 IP 數據包將進入1:20類別:

ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 1 u32 match ip dst 10.0.0.2/32 flowid 1:10
ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 2 u32 match ip dst 10.0.0.3/32 flowid 1:20

現在你明白了,你需要向tcB 和 C 添加類似的規則,這樣從這些鑽機到 A 的傳輸也被塑造了。

測試

現在讓我們測試一下。為此,我個人習慣使用iperf它,它只包含一個二進製文件,可以作為客戶端或伺服器執行,並且會在兩個主機之間自動發送盡可能多的流量。

在 A 和 B 之間:

$ ip netns exec B iperf -s -p 8001
 ...
$ ip netns exec A iperf -c 10.0.0.2 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.2, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58191 connected with 10.0.0.2 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  2.0- 4.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  4.0- 6.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  6.0- 8.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  8.0-10.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  0.0-10.1 sec  10.8 MBytes  8.91 Mbits/sec

我們得到了9 Mbit/s 的頻寬限制。

在 A 和 C 之間:

$ ip netns exec C iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.3 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.3, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58522 connected with 10.0.0.3 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  2.0- 4.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  4.0- 6.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  6.0- 8.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  8.0-10.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  0.0-10.1 sec  9.62 MBytes  7.98 Mbits/sec

我們得到了8 Mbit/s 的頻寬限制。

在 A 和 D 之間:

$ ip netns exec D iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.4 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.4, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 40614 connected with 10.0.0.4 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.62 MBytes  11.0 Mbits/sec
[  5]  2.0- 4.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  4.0- 6.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  6.0- 8.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  8.0-10.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  0.0-10.2 sec  12.0 MBytes  9.89 Mbits/sec

在這裡,我們達到了10 Mbit/s的虛擬介面全速。

請注意,htb通過調整適當的參數,可以在類中更好地處理每次執行的第一個測量的突發。

打掃乾淨

去除 :

  • 優先級為 1 的過濾器在1::上tc filter del dev vethA parent 1: prio 1 u32
  • 所有過濾器1:tc filter del dev vethA parent 1:
  • 班級1:20及其孩子:tc class del dev vethA parent 1:1 classid 1:20
  • 整棵樹:tc qdisc del dev vethA

清理模擬集:

# Remove veth pairs and network namespaces
for host in {A..D} ; do
   ip link del dev veth${host}.peer
   ip netns del ${host}
done

# Remove the bridge
ip link del dev br0

引用自:https://serverfault.com/questions/655317