4.2. 診断
このセクションでは、タップ (カーネルパス) インターフェイスでのパケットドロップについて説明します。ユーザーデータパスの vhost ユーザーインターフェイスでのパケットドロップについては、https://access.redhat.com/solutions/3381011 を参照してください。
TX ドロップは、インスタンスの vCPU とハイパーバイザー上の他のプロセス間の干渉が原因で発生します。タップインターフェイスの TX キューは、インスタンスがパケットを取得できない場合に備えて、パケットを短時間保存できるバッファーです。これは、インスタンスの CPU が十分な時間実行されない (またはフリーズする) 場合に発生します。
TUN/TAP デバイスは、一方の端がカーネルネットワークインターフェイスで、もう一方の端がユーザー空間ファイル記述子である仮想デバイスです。
TUN/TAP インターフェイスは、次の 2 つのモードのいずれかで実行できます。
- Tap mode は、L2 ヘッダー付きの L2 イーサネットフレームをデバイスにフィードし、ユーザー空間から同じものを受信することを期待します。このモードは VM に使用されます。
- Tun mode は、L3 ヘッダー付きの L3 IP パケットをデバイスにフィードし、ユーザー空間から同じものを受信することを期待します。このモードは主に VPN クライアントに使用されます。
KVM ネットワーキングでは、ユーザー空間ファイル記述子は qemu-kvm プロセスによって所有されます。タップに送信されたフレーム (ハイパーバイザーの観点からは TX) は、最終的に qemu-kvm 内の L2 フレームになり、仮想ネットワークインターフェイスに受信されたネットワークパケットとして VM 内の仮想ネットワークデバイスにそれらのフレームをフィードできます (RX VM の観点)。
TUN/TAP の重要な概念は、ハイパーバイザーからの送信方向が仮想マシンの受信方向であるということです。これは反対方向にも当てはまります。ハイパーバイザーの受信は、仮想マシンからの送信と同じです。
virtio-net デバイスにはパケットのリングバッファーはありません。これは、VM が (十分に高速で、またはまったく) 受信していないために TUN/TAP デバイスの TX キューがいっぱいになった場合、新しいパケットを送信する場所がなく、ハイパーバイザーが tap で TX 損失を確認することを意味します。
TUN/TAP で TX 損失に気付いた場合は、それを回避するために tap txqueuelen を増やします。これは、物理 NIC での受信損失を停止するために RX リングバッファーを増やすのと同様です。
ただし、これは、VM が受信時に低速でバーストしていることを前提としています。VM が常に十分な速度で実行されていない場合、またはまったく受信していない場合は、TX キューの長さを調整しても効果がありません。VM が実行または受信されていない理由を確認する必要があります。
仮想マシンのパケット処理のパフォーマンスを向上させる必要がある場合は、以下の手順を実行します。
-
ハイパーバイザーで
virtio-net マルチキューを有効にします。 - 複数の仮想デバイス割り込みを、仮想マシン内の差異コアに分散します。
これは、KVM の libvirt ドメイン仕様に記載されています。RHEL KVM ハイパーバイザーで virsh edit を使用して実行できます。
Red Hat OpenStack Platform で virtio-net のマルチ キューを設定することができない場合は、仮想マシン内で RPS を設定して、複数の CPU コア間で受信の負荷とソフトウェアのバランスを取ることを検討してください。詳細は、kernel-doc パッケージの scaling.txt か、RHEL 製品ドキュメントの RPS セクションを参照してください。
4.2.1. 回避策 リンクのコピーリンクがクリップボードにコピーされました!
レイテンシーの増加やその他の欠点を犠牲にして小さなフリーズを軽減するには、TX キューを増やします。
txqueuelen を一時的に増やすには、次のコマンドを使用します。
/sbin/ip link set tap<uuid> txqueuelen <new queue length>
txqueulen を永続的に増やすには、udev ルールを作成します。
cat <<'EOF'>/etc/udev/rules.d/71-net-txqueuelen.rules
SUBSYSTEM=="net", ACTION=="add", KERNEL=="tap*", ATTR{tx_queue_len}="10000"
EOF
udev を再読み込みするか、システムを再起動すると、新しい tap インターフェースはキューの長さ 10000 とともに起動します。以下に例を示します。
[root@overcloud-compute-0 ~]# ip link ls | grep tap
29: tap122be807-cd: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 5505
qdisc pfifo_fast master qbr122be807-cd state UNKNOWN mode DEFAULT
group default qlen 10000