
我在 Ubuntu 18.04 LTS 主機上使用 Firecracker 設定了兩個 microVM,並為每個虛擬機器附加了一個 tun/tap 裝置。現在,我嘗試在兩台虛擬機器之間設定延遲(例如 100 毫秒),tc
以便在它們之間獲得 200 毫秒的 RTT,但我似乎無法使其正常工作。
理想情況下,我想直接指定兩個設備,tc
但似乎我必須指定它們的網路才能使其工作。
以下是水龍頭的設定方式(根據鞭炮文檔),每台機器 A 和 B 一台:
# create a tap device
sudo ip tuntap add tapA mode tap
sudo ip tuntap add tapB mode tap
# set up tap device ip address
sudo ip addr add 10.0.0.29/30 dev tapA
sudo ip addr add 10.0.0.33/30 dev tapB
# set up tap device
sudo ip link set tapA up
sudo ip link set tapB up
# enable forwarding
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
# add iptables config
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i tapA -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i tapB -o eth0 -j ACCEPT
正如您所看到的,我為每台機器提供了一個小型專用網路(10.0.0.28/30
用於 A 和10.0.0.32/30
B),並指定分接頭將在主機端取得的 IP 位址。我正在使用10.0.0.30/30
A 和B 的地址(啟動時設置的配置)啟動計算機10.0.0.34/30
,並且可以成功地從彼此和主機對它們執行 ping 操作。
根據我的研究,我發現了tc
我期望的命令:
# create a qdisc for tapA
tc qdisc add dev tapA root handle 1: htb default 1
tc class add dev tapA parent 1: classid 1:1 htb rate 10.0Gbit
tc class add dev tapA parent 1: classid 1:2 htb rate 10.0Gbit ceil 10.0Gbit
# add a delay of 100ms
tc qdisc add dev tapA parent 1:2 handle 2: netem delay 100.0ms
# only apply that delay when the packet comes from A's network and goes to B's network
tc filter add dev tapA protocol ip parent 1: prio 5 u32 match ip dst 10.0.0.32/30 match ip src 10.0.0.28/30 flowid 1:2
# do the same for tapB
tc qdisc add dev tapB root handle 1: htb default 1
tc class add dev tapB parent 1: classid 1:1 htb rate 10.0Gbit
tc class add dev tapB parent 1: classid 1:2 htb rate 10.0Gbit ceil 10.0Gbit
tc filter qdisc add dev tapB parent 1:2 handle 2: netem delay 100.0ms
# but this time going from B's network to A's network
tc filter add dev tapB protocol ip parent 1: prio 5 u32 match ip dst 10.0.0.28/30 match ip src 10.0.0.32/30 flowid 1:2
我希望這會增加從 A 到 B 的所有傳出資料包的延遲,反之亦然,但什麼都沒有發生。奇怪的是,設定這些過濾器是有效的:
# matching destination of A on A's tap
# this should match incoming packets from B to A on tapA
tc filter add dev tapA protocol ip parent 1: prio 5 u32 match ip dst 10.0.0.28/30 match ip src 10.0.0.32/30 flowid 1:2
# and vice versa for tapB
tc filter add dev tapB protocol ip parent 1: prio 5 u32 match ip dst 10.0.0.32/30 match ip src 10.0.0.28/30 flowid 1:2
如果我理解正確的話,這意味著tc
檢查傳入的資料包並應用正確的過濾器。但這並不是我真正期望發生的情況,我希望過濾和延遲傳出的資料包。還是我錯過了什麼?
答案1
我做了一些進一步的研究,我想我開始了解這裡發生的事情。如果有人對細節有把握,請在下面留下答案,但對於可能遇到此問題的人,我也會在這裡留下我的解釋。
我認為水龍頭對於 microVM 和主機來說看起來是一樣的,但我認為這不太正確。如圖所示(顯示了一個簡單ping
命令的步驟),當我從機器 A 向機器 B 發送 ping 時,封包從 A 的角度發出,但從主機的角度傳入,因為主機tapA
設備連接到eth0
A 中的設備tun/tap
。因此,資料包也在「tapB」上傳出,並且(這是有道理的)在 B 上傳入。
由於tc
只能管理傳出資料包而無法管理傳入資料包(至少如果您不透過其他虛擬介面重新導向它們),我只能在tapB
(資料包傳出到 B 的位置)和 B上應用A-> B 延遲-> 延遲tapA
。
目前我保留這個解決方法,直到有更好的方法出現。