はじめに
OVS-DPDK の検証では、物理 NIC を DPDK 対応ドライバーへ bind し、外部ネットワークとの通信や転送性能まで確認する構成を想像しがちです。ただし、OVS-DPDK と vhost-user の接続関係を確認するだけであれば、物理 NIC を使わない閉じた検証環境でも十分に意味があります。
この記事では、Ubuntu 26.04 の KVM ホスト上で、既存の Open vSwitch 環境を残したまま検証専用の OVS-DPDK bridge を追加します。その bridge に vhost-user インターフェースを持つ KVM VM を 2 台接続し、ホストから各 VM への疎通、vhost-user の接続ログ、PMD thread のパケット受信を確認します。
目的は性能評価ではありません。物理 NIC を使わない最小構成で、OVS-DPDK、QEMU / KVM、vhost-user の基本的な接続が成立することを、再現しやすい手順として確認することです。
- Ubuntu 26.04 で OVS-DPDK を有効化する
- 既存の system datapath bridge と DPDK 用の netdev bridge を共存させる
- 物理 NIC を使用しない閉じた検証ネットワークを作る
- QEMU を vhost-user server、OVS を client として接続する
- 通常の virtio-net を使用する VM との疎通を確認する
今回の検証範囲
今回確認した範囲は次のとおりです。
| 項目 | 対象 |
|---|---|
| OVS-DPDK の起動 | 対象 |
datapath_type=netdev の bridge 作成 | 対象 |
dpdkvhostuserclient の接続 | 対象 |
| KVM VM への vhost-user NIC 接続 | 対象 |
| ホストから VM への疎通 | 対象 |
| 既存 system datapath bridge との共存 | 対象 |
| 物理 NIC の DPDK bind | 対象外 |
| 異なる物理ホスト間の通信 | 対象外 |
| VM 相互間の通信 | 対象外 |
| 通常 OVS との性能比較 | 対象外 |
| OVS-DPDK の性能測定 | 対象外 |
| ゲスト内 DPDK | 対象外 |
| VPP や DPDK アプリケーションの動作 | 対象外 |
今回の VM は、ゲスト OS 内では通常の Linux virtio-net ドライバーを使用しています。
ゲスト Linux
└─ virtio-net
└─ vhost-user
└─ OVS-DPDK userspace datapathゲスト内で DPDK を動作させる構成ではありません。DPDK を使用しているのは、ホスト側の Open vSwitch です。
検証環境
対象ホストは次のとおりです。
kvm-host.example.local主なソフトウェアのバージョンは次のとおりです。
| ソフトウェア | バージョン |
|---|---|
| Ubuntu | 26.04 |
| Open vSwitch | 3.7.1 |
| DPDK | 25.11.0 |
| 仮想化基盤 | KVM/libvirt |
実際の ovs-vswitchd --version では、OVS と DPDK の両方のバージョンを確認できました。
ovs-vswitchd (Open vSwitch) 3.7.1
DPDK 25.11.0既存環境には、通常の kernel datapath を使用する bridge が存在しています。
br-int
brphys0今回、検証用として次の bridge を追加しました。
br-dpdk-test全体構成は次のとおりです。
ovs-vswitchd
├─ br-int
│ └─ datapath_type=system
│
├─ brphys0
│ └─ system datapath
│
└─ br-dpdk-test
└─ datapath_type=netdev
├─ internal port
│ └─ ホスト IP: 192.0.2.1/24
│
├─ vhost-user-test0
│ └─ ovs-dpdk-test0: 192.0.2.10/24
│
└─ vhost-user-test1
└─ ovs-dpdk-test1: 192.0.2.11/24物理 NIC は br-dpdk-test へ接続していません。また、物理 NIC を VFIO や UIO ドライバーへ bind する作業も行っていません。 なお、bridge とデータパスは分離されていますが、OVSDB と ovs-vswitchd プロセスは既存 bridge と共通です。検証用 bridge を追加したからといって、OVS の管理プレーンまで完全に分離されるわけではありません。
必要なパッケージを導入する
次のパッケージを導入しました。
apt update
apt install \
openvswitch-switch-dpdk \
dpdk \
libguestfs-toolsopenvswitch-switch-dpdk は、DPDK 対応版の ovs-vswitchd を使用するために必要です。 libguestfs-tools は OVS-DPDK 自体の必須パッケージではありません。今回は、VM を起動する前に clone したゲストディスク内の netplan などを変更するために使用しました。
DPDK 対応版の ovs-vswitchd へ切り替える
Ubuntu の Open vSwitch パッケージでは、通常版と DPDK 対応版の ovs-vswitchd を alternative で切り替えられます。
update-alternatives --config ovs-vswitchd今回選択した実体は次のファイルです。
/usr/lib/openvswitch-switch-dpdk/ovs-vswitchd-dpdk実際の状態は次のとおりです。
ovs-vswitchd - manual mode
link best version is /usr/lib/openvswitch-switch/ovs-vswitchd
link currently points to /usr/lib/openvswitch-switch-dpdk/ovs-vswitchd-dpdk通常版の ovs-vswitchd を使用したまま DPDK を有効化しようとすると、次のエラーが記録されました。
DPDK not supported in this copy of Open vSwitch.このため、OVS-DPDK を使用する前に、DPDK 対応版へ切り替わっていることを確認する必要があります。
update-alternatives --display ovs-vswitchdOVS-DPDK を有効化する
今回設定した DPDK 関連の値は次のとおりです。
ovs-vsctl --no-wait set Open_vSwitch . \
other_config:dpdk-init=true \
other_config:dpdk-lcore-mask=0x10 \
other_config:pmd-cpu-mask=0x20 \
other_config:dpdk-socket-mem=1024 \
other_config:vlan-limit=0実際の other_config は次のようになりました。
{
dpdk-init="true",
dpdk-lcore-mask="0x10",
dpdk-socket-mem="1024",
pmd-cpu-mask="0x20",
vlan-limit="0"
}各設定の意味は次のとおりです。
| 設定 | 値 | 内容 |
|---|---|---|
dpdk-init | true | OVS 起動時に DPDK を初期化する |
dpdk-lcore-mask | 0x10 | DPDK の制御用 lcore を CPU 4 へ割り当てる |
pmd-cpu-mask | 0x20 | PMD thread を CPU 5 へ割り当てる |
dpdk-socket-mem | 1024 | NUMA socket 0 で使用する DPDK memory を 1024MB 確保する |
vlan-limit | 0 | 今回の環境で設定した OVS の VLAN 関連値 |
CPU mask はビットマスクです。
0x10 = CPU 4
0x20 = CPU 5vlan-limit=0 は今回の環境で設定した値ですが、今回の untagged な vhost-user 疎通に必要な設定として一般化するものではありません。 設定後、Open vSwitch を再起動します。
systemctl restart openvswitch-switchDPDK の初期化状態を確認します。
ovs-vsctl get Open_vSwitch . dpdk_initialized
ovs-vsctl get Open_vSwitch . dpdk_version今回の結果は次のとおりです。
true"DPDK 25.11.0"–vhost-owner と –vhost-perm は使用できなかった
当初、DPDK の追加引数として次の設定も試しました。
dpdk-extra="--vhost-owner libvirt-qemu:kvm --vhost-perm 0660"しかし、DPDK 25.11.0 では次のエラーが発生しました。
ARGPARSE: unknown argument --vhost-owner!このエラーにより、 ovs-vswitchd は起動に失敗し、systemd による再起動を繰り返しました。
ovs-vswitchd.service: Start request repeated too quickly.
ovs-vswitchd.service: Failed with result 'exit-code'.--vhost-owner と --vhost-perm を削除した後、 ovs-vswitchd は正常に起動しました。 今回採用した dpdkvhostuserclient 構成では、QEMU が vhost-user socket を作成し、OVS が client として接続します。そのため、今回の構成ではこれらの引数を使用せずに接続できました。
確認できた事実は、Ubuntu 26.04 の DPDK 25.11.0 環境では、少なくとも --vhost-owner が DPDK の引数として受理されなかったということです。
検証用の OVS-DPDK bridge を作成する
検証用 bridge を datapath_type=netdev として作成します。
ovs-vsctl add-br br-dpdk-test \
-- set Bridge br-dpdk-test datapath_type=netdev状態を確認します。
ovs-vsctl list Bridge br-dpdk-test実際の結果では、次の値が確認できました。
name : br-dpdk-test
datapath_type : netdev既存 bridge はそのまま残っています。
Bridge brphys0
Bridge br-dpdk-test
datapath_type: netdev
Bridge br-int
datapath_type: systemこれにより、同じ OVS 環境内で、既存の system datapath bridge と検証用の netdev datapath bridge を共存させられることを確認しました。
vhost-user-client port を作成する
2 台の VM に対応する vhost-user port を作成します。
ovs-vsctl add-port br-dpdk-test vhost-user-test0 \
-- set Interface vhost-user-test0 \
type=dpdkvhostuserclient \
options:vhost-server-path=/run/libvirt/qemu/vhost-user-test0ovs-vsctl add-port br-dpdk-test vhost-user-test1 \
-- set Interface vhost-user-test1 \
type=dpdkvhostuserclient \
options:vhost-server-path=/run/libvirt/qemu/vhost-user-test1実際の OVSDB では次のように確認できます。
Port vhost-user-test0
Interface vhost-user-test0
type: dpdkvhostuserclient
options: {
vhost-server-path="/run/libvirt/qemu/vhost-user-test0"
}
Port vhost-user-test1
Interface vhost-user-test1
type: dpdkvhostuserclient
options: {
vhost-server-path="/run/libvirt/qemu/vhost-user-test1"
}dpdkvhostuserclient では、OVS が client として動作します。 vhost-server-path には、QEMU が server として作成する Unix domain socket のパスを指定します。
socket path 変更後に接続しない場合
検証中に vhost-server-path を変更したところ、設定値を変更しただけでは接続が回復しない状態が発生しました。 今回の環境では、該当 port を削除して再作成することで復旧しました。
ovs-vsctl del-port br-dpdk-test vhost-user-test0ovs-vsctl add-port br-dpdk-test vhost-user-test0 \
-- set Interface vhost-user-test0 \
type=dpdkvhostuserclient \
options:vhost-server-path=/run/libvirt/qemu/vhost-user-test0これは今回の OVS 3.7.1 環境で確認した挙動です。すべての環境で port の再作成が必須という意味ではありませんが、接続が回復しない場合の対処方法として有効でした。
検証用 VM を作成する
既存の Ubuntu テンプレートディスクから、2 台の linked clone を作成しました。 元のテンプレートは次のファイルです。
/var/lib/libvirt/images/ubuntu-template-40g.qcow2作成したディスクは次のとおりです。
/var/lib/libvirt/images/ovs-dpdk-test0.qcow2
/var/lib/libvirt/images/ovs-dpdk-test1.qcow2作成した VM は次の 2 台です。
ovs-dpdk-test0
ovs-dpdk-test1VM の主な条件は次のとおりです。
| 項目 | 設定 |
|---|---|
| メモリー | 1024MiB |
| vCPU | 1 |
| CPU mode | host-passthrough |
| メモリー | HugePages を使用 |
| NIC | vhost-user |
| NIC model | virtio |
| console | serial console |
| graphics | なし |
OVS-DPDK 側から QEMU のゲストメモリーへアクセスするため、VM のメモリーは共有可能な HugePages 上へ配置しました。 libvirt XML の主な設定は次のとおりです。
<memoryBacking>
<hugepages/>
<access mode='shared'/>
</memoryBacking>vhost-user インターフェースは、QEMU を server とするため mode='server' で定義します。 ovs-dpdk-test0 の例は次のとおりです。
<interface type='vhostuser'>
<mac address='52:54:00:5b:af:ad'/>
<source type='unix'
path='/run/libvirt/qemu/vhost-user-test0'
mode='server'/>
<model type='virtio'/>
</interface>ovs-dpdk-test1 では、socket path と MAC アドレスを変更します。
<interface type='vhostuser'>
<mac address='52:54:00:12:e4:26'/>
<source type='unix'
path='/run/libvirt/qemu/vhost-user-test1'
mode='server'/>
<model type='virtio'/>
</interface>実際の QEMU 起動引数では、HugePages と共有メモリーが次のように設定されていました。
-object {
"qom-type":"memory-backend-file",
"mem-path":"/dev/hugepages/libvirt/qemu/...",
"share":true,
"prealloc":true,
"size":1073741824
}vhost-user インターフェースは次の構成です。
-chardev socket,
id=charnet0,
path=/run/libvirt/qemu/vhost-user-test0,
server=on
-netdev {
"type":"vhost-user",
"chardev":"charnet0",
"id":"hostnet0"
}
-device {
"driver":"virtio-net-pci",
"netdev":"hostnet0",
"mac":"52:54:00:5b:af:ad"
}接続関係は次のとおりです。
QEMU
└─ vhost-user server
└─ Unix domain socket
└─ OVS dpdkvhostuserclientゲスト OS の IP アドレスを設定する
VM 起動前に、clone ディスク内の netplan を変更しました。 ovs-dpdk-test0 では次の設定を使用しています。
network:
version: 2
ethernets:
dpdk0:
match:
macaddress: "52:54:00:5b:af:ad"
set-name: dpdk0
addresses:
- 192.0.2.10/24
dhcp4: false
dhcp6: falseovs-dpdk-test1 では次の設定を使用しています。
network:
version: 2
ethernets:
dpdk0:
match:
macaddress: "52:54:00:12:e4:26"
set-name: dpdk0
addresses:
- 192.0.2.11/24
dhcp4: false
dhcp6: falseここで使用している dpdk0 は、ゲスト OS 上のインターフェース名です。ゲスト内で DPDK を使用しているという意味ではありません。 netplan の設定ファイルは次の権限に変更しました。
chmod 0600 /etc/netplan/00-installer-config.yamlまた、検証用 VM では systemd-networkd-wait-online.service を disable および mask しました。
systemctl disable systemd-networkd-wait-online.service
systemctl mask systemd-networkd-wait-online.serviceこれらの変更は、今回作成した検証用 clone ディスクだけに適用しています。
ホスト側に IP アドレスを設定する
ホストから VM へ疎通確認するため、 br-dpdk-test へ IP アドレスを設定しました。
ip link set br-dpdk-test up
ip address add 192.0.2.1/24 dev br-dpdk-test実際の状態は次のとおりです。
br-dpdk-test:
state UNKNOWN
mtu 1500
inet 192.0.2.1/24ルーティングテーブルには、接続ルートが追加されています。
192.0.2.0/24 dev br-dpdk-test
proto kernel
scope link
src 192.0.2.1OVS の internal port は物理インターフェースのような carrier 状態を持たないため、 state UNKNOWN と表示される場合があります。今回の疎通には問題ありませんでした。 なお、この IP アドレスは ip address add で設定した一時的な値です。OS 再起動後にも維持するには、別途永続設定が必要です。
VM を起動する
2 台の VM を起動します。
virsh start ovs-dpdk-test0
virsh start ovs-dpdk-test1実際の起動結果は次のとおりです。
Domain 'ovs-dpdk-test0' started
Domain 'ovs-dpdk-test1' startedQEMU が起動すると、次の socket が作成されます。
/run/libvirt/qemu/vhost-user-test0
/run/libvirt/qemu/vhost-user-test1OVS はこれらの socket へ client として接続します。
vhost-user の接続を確認する
VM 起動中の OVS ログでは、vhost-user 接続の成立を確認できました。
VHOST_CONFIG: (/run/libvirt/qemu/vhost-user-test0) connected
VHOST_CONFIG: (/run/libvirt/qemu/vhost-user-test0) new device続いて、vhost-user protocol feature のネゴシエーションが行われています。
VHOST_USER_GET_FEATURES
VHOST_USER_GET_PROTOCOL_FEATURES
VHOST_USER_SET_PROTOCOL_FEATURESvring も有効化されています。
VHOST_USER_SET_VRING_ENABLE
set queue enable: 1 to qp idx: 0
set queue enable: 1 to qp idx: 1さらに、ゲストメモリーの共有と virtio device の準備完了を確認できました。
VHOST_USER_SET_MEM_TABLE
guest memory region size: 0x40000000virtio is now ready for processing.
vHost Device '/run/libvirt/qemu/vhost-user-test0'
has been added on numa node 0test1 側でも同様のログを確認しています。 これにより、単に Unix domain socket へ接続しただけではなく、feature negotiation、ゲストメモリー共有、vring 設定、virtio device の処理開始まで完了したことが分かります。
VM 停止後は disconnected になる
VM を停止すると、QEMU が作成していた socket も削除されます。 OVS ログでは次のように記録されました。
vhost peer closed
connection has been destroyed
failed to connect: No such file or directory
reconnecting...VM 停止後に取得した OVS interface の状態は次のとおりです。
link_state : down
status : {
mode=client,
status=disconnected
}これは異常ではありません。 dpdkvhostuserclient では QEMU が server として socket を作成するため、VM が停止して socket が存在しなくなると、OVS 側は down および disconnected になります。 したがって、接続確認では、VM 起動中の OVS ログと、停止後の OVSDB 状態を区別して確認する必要があります。
PMD thread を確認する
今回の設定では、PMD thread を CPU 5 へ割り当てています。
pmd-cpu-mask="0x20"PMD の統計を確認します。
ovs-appctl dpif-netdev/pmd-stats-show実際の結果は次のとおりです。
pmd thread numa_id 0 core_id 5:
packets received: 119
packet recirculations: 0
avg. datapath passes per packet: 1.00
idle cycles: 9404624953260 (100.00%)
processing cycles: 17720348 (0.00%)この結果から、次のことを確認できます。
- PMD thread は NUMA node 0、CPU 5 で動作している
- PMD は実際に 119 packet を受信した
- トラフィックが非常に少ないため、累積 cycle のほぼすべてが idle として表示されている
processing cyclesも実際には記録されている
表示上は processing cycles: 0.00% ですが、実際の値はゼロではありません。全体に占める割合が極めて小さいため、小数点以下の表示で 0.00%になっています。 今回の目的は性能測定ではないため、この値を転送性能の評価には使用していません。PMD thread が指定した CPU 上で動作し、実際にパケットを処理したことの確認に使用しています。
ホストから各 VM への疎通を確認する
ホストの br-dpdk-test から、ovs-dpdk-test0 へ ping を実行しました。
ping -c 3 -W 2 192.0.2.10結果は次のとおりです。
3 packets transmitted, 3 received, 0% packet loss
rtt min/avg/max/mdev = 0.162/0.228/0.316/0.064 msovs-dpdk-test1 についても同様に確認しました。
ping -c 3 -W 2 192.0.2.11結果は次のとおりです。
3 packets transmitted, 3 received, 0% packet loss
rtt min/avg/max/mdev = 0.170/0.273/0.464/0.134 msこれにより、次の経路が成立していることを確認できました。
ホスト Linux IP stack
↓
br-dpdk-test internal port
↓
OVS-DPDK userspace datapath
↓
dpdkvhostuserclient
↓
vhost-user socket
↓
QEMU virtio-net
↓
ゲスト Linux IP stackこの ping 結果は、構成と疎通の成立を確認するためのものです。DPDK の性能を評価する数値ではありません。
検証中に発生した問題
今回の検証で発生した、OVS-DPDK と vhost-user に直接関係する問題を整理します。
| 現象 | 原因または状況 | 対処 |
|---|---|---|
DPDK not supported が出る | 通常版 ovs-vswitchd が起動していた | DPDK 対応版へ alternative を切り替えた |
--vhost-owner が unknown argument になる | DPDK 25.11.0 で引数として受理されなかった | dpdk-extra から削除した |
| socket path 変更後に接続しない | 設定変更だけでは接続が回復しなかった | OVS port を削除して再作成した |
| VM 停止後に interface が down になる | QEMU が server socket を削除するため | 正常な停止後状態として扱った |
| PMD 統計がほぼ idle になる | 疎通確認程度の少量トラフィックだった | PMD の配置と packet 受信数を確認した |
検証後の状態
疎通確認後、検証用 VM は停止しました。
virsh destroy ovs-dpdk-test0
virsh destroy ovs-dpdk-test1ホストには次の構成が残っています。
openvswitch-switch-dpdkパッケージ- DPDK 対応版
ovs-vswitchdの alternative 設定 - OVS の DPDK 関連
other_config br-dpdk-testvhost-user-test0vhost-user-test1- 検証用 VM 定義
- 検証用 VM ディスク
br-dpdk-testの192.0.2.1/24
既存の構成管理には変更を加えていません。 ただし、構成管理を変更していないことと、ホストの構成が変更されていないことは別です。現在の状態は構成管理の管理外で追加した構成であり、構成管理上はドリフトになります。 検証構成を継続して使用する場合は、今後 Ansible の管理対象へ取り込む必要があります。検証を終了する場合は、追加した bridge、port、VM、ディスク、OVS 設定、alternative 設定を元へ戻します。
まとめ
今回の検証では、Ubuntu 26.04 上で OVS-DPDK と vhost-user を使用した最小構成を作成しました。物理 NIC を DPDK へ bind せず、既存の system datapath bridge を維持したまま、検証用の netdev bridge を追加しています。
QEMU を vhost-user server、OVS を dpdkvhostuserclient として接続し、vhost-user インターフェースを持つ 2 台の KVM VM を起動しました。その上で、vhost-user socket への接続、feature negotiation、ゲストメモリー共有、vring の有効化、PMD thread によるパケット受信、ホストから VM への ping 疎通を確認しています。
実際のログでは、次の処理を確認できました。
- vhost-user socket への接続
- protocol feature のネゴシエーション
- virtio feature のネゴシエーション
- ゲストメモリー情報の共有
- vring の設定と有効化
virtio is now ready for processing- PMD thread によるパケット受信
最終的に、ホストから各 VM への ping 疎通を確認しました。今回確認した構成は次のとおりです。
既存 OVS 環境
├─ system datapath bridge
│ ├─ br-int
│ └─ brphys0
│
└─ netdev datapath bridge
└─ br-dpdk-test
├─ internal port
│ └─ ホスト Linux IP stack
│
├─ dpdkvhostuserclient
│ └─ QEMU vhost-user server
│ └─ virtio-net VM
│
└─ dpdkvhostuserclient
└─ QEMU vhost-user server
└─ virtio-net VMこの結果から、物理 NIC を使用しない閉じた環境でも、OVS-DPDK、vhost-user、QEMU / KVM を組み合わせた基本構成を作成できることを確認しました。性能比較、物理 NIC を使用した外部通信、VM 相互間の通信、ゲスト内 DPDK は今回の対象には含めていません。
この記事の結論は、Ubuntu 26.04 上で OVS-DPDK と vhost-user の基本構成を作成し、ホストと vhost-user VM 間の疎通を確認できたという範囲に限定されます。DPDK を使えば必ず速くなる、または物理 NIC を含む本番構成まで確認できた、という意味ではありません。

