Mô phỏng kết nối chậm giữa hai máy chủ Ubuntu


9

Tôi muốn mô phỏng kịch bản sau: cho rằng tôi có 4 máy chủ Ubuntu, A, B, C và D. Tôi muốn giảm 20% băng thông mạng giữa máy A và máy C và 10% giữa A và B. làm điều này bằng cách sử dụng các công cụ mô phỏng / điều chỉnh mạng?


iptables có thể có khả năng điều tiết. Tôi không bao giờ sử dụng nó, nhưng đáng để xem xét.
Michael Martinez

@MichaelMartinez Không, không. tckhông khi được sử dụng với đánh dấu iptables.
Xavier Lucas

@XavierLika tốt để biết!
Michael Martinez

Câu trả lời:


15

Để làm điều này, bạn có thể sử dụng tcmột mình với u32các bộ lọc hoặc kết hợp với đánh dấu iptables (có thể đơn giản hơn nếu bạn không muốn tìm hiểu cú pháp bộ lọc phức tạp). Tôi sẽ trong bài viết sau đây chi tiết các giải pháp trước đây.


Mô phỏng thiết lập của bạn

Ví dụ, hãy xem xét A, B, C và D chạy các giao diện ảo 10 Mbit / s .

Về cơ bản bạn muốn:

  • A <==> B: 9 Mbit / s định hình cho đi ra
  • A <==> C: 8 Mbit / s định hình cho đi ra

Để mô phỏng điều này, tôi sẽ tạo 4 không gian tên mạng và giao diện ethernet ảo được cắm vào một cây cầu.

Tất nhiên, trong trường hợp của bạn, bạn sẽ làm việc với các NIC thực và cây cầu sẽ là cổng hoặc công tắc tùy thuộc vào cơ sở hạ tầng của bạn.

Vì vậy, trong mô phỏng của tôi, chúng tôi sẽ có thiết lập sau, trong mạng 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           

Đầu tiên, hệ thống thiết lập để bạn có thể hiểu nó được làm từ gì, bỏ qua nếu bạn không quen với nó, không có vấn đề gì lớn. Tuy nhiên, điều bạn phải biết là lệnh ip netns exec <namespace> <command>cho phép thực thi một lệnh trong không gian tên mạng (tức là trong một trong các ô của lần rút trước đó). Điều này cũng sẽ được sử dụng trong phần tiếp theo.

# 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

Vì vậy, tại thời điểm này chúng tôi có các thiết lập được mô tả trước đây.


Định hình giao thông

Đã đến lúc kiểm soát giao thông để có được những gì bạn muốn. Công tccụ cho phép bạn thêm các quy tắc xếp hàng:

  • Đối với đầu ra: một khi kernel cần gửi các gói và trước khi truy cập trình điều khiển NIC.
  • Đối với xâm nhập: sau khi truy cập trình điều khiển NIC và trước các thường trình kernel được chạy qua các gói nhận được.

Nó đi kèm với 3 khái niệm: qdisc , các lớpbộ lọc . Những khái niệm này có thể được sử dụng để thiết lập quản lý luồng gói phức tạp và ưu tiên lưu lượng dựa trên bất kỳ tiêu chí / tiêu chí nào bạn muốn.

Tóm lại:

  • Qdiscs là các cấu trúc trong đó các gói sẽ thực sự được xử lý / loại bỏ.
  • Các lớp là các thùng chứa cho qdiscs hành động với các hành vi cụ thể.
  • Bộ lọc là cách để định tuyến các gói giữa các lớp, nhiều trong số chúng có thể được xác định trên cùng một điểm nhập với các ưu tiên trong quá trình xử lý.

Tất cả những thứ này thường hoạt động như một cái cây trong đó lá là qdiscs và các lớp là các nút. Các gốc của cây hoặc cây con sẽ được khai báo là <id>:và các nút con sẽ được khai báo là <parent_id>:<children_id>. Hãy ghi nhớ cú pháp này.

Đối với trường hợp của bạn, hãy lấy A và kết xuất cây bạn muốn thiết lập tc:

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

Giải trình :

  • 1:là qdisc gốc được gắn vào thiết bị vethA, nó sẽ được lấy một cách rõ ràng như htbđối với Phân cấp mã thông báo phân cấp (qdisc mặc định của thiết bị là pfifohoặc pfifo_fasttùy thuộc vào HĐH). Nó đặc biệt thích hợp để quản lý bandwith. Các gói không khớp với các bộ lọc được xác định ở cấp độ này sẽ đến 1:30lớp.
  • 1:1sẽ là một htblớp giới hạn toàn bộ lưu lượng của thiết bị ở mức 10 Mbit / s.
  • 1:10sẽ là một htblớp giới hạn lưu lượng đầu ra ở mức 9 Mbit / s (90% của 10 Mbit / s).
  • 1:20sẽ là một htblớp giới hạn lưu lượng đầu ra ở mức 8 Mbit / s (80% của 10 Mbit / s).
  • 1:30sẽ là một htblớp giới hạn lưu lượng đến 10 Mbit / s (dự phòng).
  • :10, :20, :30sfqqdisc cho xếp hàng công bằng Stochastic. Nói cách khác, các qdiscs này sẽ đảm bảo sự công bằng trong lịch trình truyền phát dựa trên các luồng.

Toàn bộ điều này được thiết lập bởi các lệnh sau:

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

Điều cuối cùng chúng ta cần là thêm các bộ lọc để các gói IP có IP đích bằng B sẽ chuyển đến 1:10lớp và các gói IP có IP đích bằng C sẽ đến 1:20lớp:

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

Bây giờ bạn đã có ý tưởng, bạn sẽ cần thêm các tcquy tắc tương tự vào B và C để việc truyền tới A từ các giàn khoan này cũng được định hình.


Kiểm tra

Bây giờ hãy kiểm tra nó. Đối với điều này, cá nhân tôi thường sử dụng để chơi iperf, nó chỉ bao gồm một nhị phân duy nhất có thể chạy như một máy khách hoặc máy chủ và sẽ tự động gửi càng nhiều lưu lượng càng tốt giữa cả hai máy chủ.

Giữa A và 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

Chúng tôi nhận giới hạn băng thông 9 Mbit / s .

Giữa A và 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

Chúng tôi nhận được giới hạn băng thông 8 Mbit / s của chúng tôi .

Giữa A và 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

Ở đây chúng tôi có giao diện ảo tốc độ tối đa 10 Mbit / s đạt được.

Lưu ý rằng sự bùng nổ của số đo đầu tiên của mỗi lần chạy có thể được xử lý tốt hơn trong htbcác lớp bằng cách điều chỉnh tham số thích hợp.


Dọn dẹp

Để xóa:

  • Bộ lọc ưu tiên 1 trên 1:: tc filter del dev vethA parent 1: prio 1 u32.
  • Tất cả các bộ lọc trên 1:: tc filter del dev vethA parent 1:.
  • Lớp 1:20và con của nó : tc class del dev vethA parent 1:1 classid 1:20.
  • Toàn cây : tc qdisc del dev vethA.

Để dọn dẹp bộ mô phỏng:

# 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

1
Cảm ơn rất nhiều cho câu trả lời tuyệt vời của bạn. Nếu có thể, bạn có thể vui lòng thêm các lệnh để loại bỏ các bộ lọc? chỉ trong trường hợp bất cứ ai muốn quay lại thiết lập này một cách an toàn sau khi mô phỏng.
Yehia Elshater

1
@YahiaZakaria Tôi vừa thêm thông tin này vào phần sau của bài viết.
Xavier Lucas

0

Ubuntu có IPFW được chuyển từ FreeBSD và IPFW có DUMMYNET cho phép quản lý các tham số mạng khác nhau - băng thông, độ trễ, tốc độ mất gói, v.v.


0

Cách tốt nhất là sử dụng các công cụ tc với mô đun netem hiện được tích hợp (ít nhất là trong máy chủ Ubuntu). Bạn có thể tìm thêm thông tin trong bài viết này từ Stackoverflow .


Netem là về mô phỏng rtt và tắc nghẽn, không phải về bandwith.
Xavier Lucas

1
@XavierLucas, bạn nói đúng, đối với băng thông bạn chỉ cần tc, thậm chí không cần netem.
Luc Stepniewski

0

Trickle hoạt động tốt.

Thảo luận này cho thấy một số hạn chế: /unix/109973/how-to-change-speed-limit-of-ricky-trickle-instance


Trickle được sử dụng để mô phỏng băng thông mạng cho một chương trình cụ thể. OP dường như tìm kiếm một giải pháp trong phạm vi của máy chủ lưu trữ.
Xavier Lucas

Trickled có thể được sử dụng để mô phỏng một nhóm các kết nối (không chỉ là một kết nối). Thật vậy, câu hỏi có thể được hiểu là "tất cả các kết nối từ máy chủ đến máy chủ".
Mathew
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.