同じホスト上の Firecracker microVM タップデバイス間の遅延を設定する

同じホスト上の Firecracker microVM タップデバイス間の遅延を設定する

Ubuntu 18.04 LTS ホストで Firecracker を使用して 2 つの microVM をセットアップし、それぞれに tun/tap デバイスを接続しました。現在、2 つの VM 間の遅延 (たとえば 100 ミリ秒) を設定して、tcそれらの間の RTT を 200 ミリ秒にしようとしていますが、正常に動作しないようです。

理想的には、2 つのデバイスを直接指定したいのですtcが、それが機能するにはネットワークを指定する必要があるようです。

蛇口の設置方法は次のとおりです(爆竹のドキュメント)、マシン A と B ごとに 1 つずつ:

# 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/30A 用と10.0.0.32/30B 用) を割り当て、タップがホスト側で取得する IP アドレスを指定しています。マシンを10.0.0.30/30A 用と10.0.0.34/30B 用のアドレス (起動時に設定) で起動すると、マシン同士およびホストから正常に 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

さらに調査を進め、ここで何が起こっているのか理解し始めていると思います。詳細について確信がある方は、以下に回答を残してください。ただし、これに遭遇する可能性のある人のために、私の説明もここに残しておきます。

ping コマンドのパケットの概要

私は、タップはホストだけでなく microVM にとっても同じに見えると思っていましたが、それは正しくないと思います。図 (簡単なコマンドの手順を表示) でわかるように、マシン A からマシン B に ping を送信すると、ホストのデバイスが A のデバイスに接続pingされているため、パケットは A の観点からは送信されますが、ホストの観点からは受信されます。両方のデバイスが一緒になって、実際には を形成します。したがって、パケットは `tapB`` でも送信され、(これは理にかなっています) B で受信されます。tapAeth0tun/tap

は送信パケットのみを管理でき、受信パケットは管理できないためtc(少なくとも他の仮想インターフェイス経由でパケットをリダイレクトしない限り)、 には A->B 遅延tapB(パケットが B に送信される場合) のみを適用でき、 には B->A 遅延のみを適用できますtapA

今のところ、もっと良い方法が見つかるまでは、この回避策を維持します。

関連情報