使用 vhost-user-client 和 ovs-dpdk 连接 QEMU-KVM 虚拟机
Connect QEMU-KVM VMs using vhost-user-client and ovs-dpdk
我的目标是在覆盖网络上连接两个 QEMU-KVM 虚拟机。每个 VM 运行 在单独的物理主机上,并且必须在网络 10.0.0.0/24 上具有静态 IP。为了实现这个目标,我想使用带有 DPDK 的 OVS 桥。我想使用 vhost-user-client 协议连接 OVS 网桥和虚拟机。
我的物理设置如下:两台配备 Mellanox ConnectX6-DX 的物理机,背靠背连接(无物理交换机)。我想要实现的是:
+------------------+ +------------------+
| HOST_1 | | HOST_2 |
| | | |
| +------------+ | | +------------+ |
| | VM_1 | | | | VM_2 | |
| | | | | | | |
| | +--------+ | | | | +--------+ | |
| | | ens_2 | | | | | | ens_2 | | |
| | |10.0.0.1| | | | | |10.0.0.2| | |
| +-+---+----+-+ | | +-+---+----+-+ |
| | | | | |
| vhost-client-1 | | vhost-client-1 |
| | | | | |
| +-----+------+ | | +-----+------+ |
| | bridge | | | | bridge | |
| | br0 | | | | br0 | |
| |192.168.57.1| | | |192.168.57.2| |
| +-----+------+ | | +-----+------+ |
| | | | | |
| +---+--- | | +---+---+ |
| | dpdk0 | | | | dpdk0 | |
+----+---+--+------+ +----+---+---+-----+
| |
+-------------------------------+
我成功创建了 OVS 网桥(此处为 br0)和 DPDK 端口(此处为 dpdk0)。在每台物理机器上,我都能够 ping 通另一台机器上的网桥。然后,我创建了一个 vhost-user-client 端口并将其连接到网桥。在每个guest上,我按照上图分配了静态IP,ens2接口up
但是,此时我无法从 VM1 ping VM2,反之亦然。似乎根本没有通过 vhost-client 端口交换流量。 Ping 失败并显示 目标主机无法访问 消息。
一些有用的信息:
ovs-vsctl show
Bridge br0
datapath_type: netdev
Port br0
Interface br0
type: internal
Port dpdk0
Interface dpdk0
type: dpdk
options: {dpdk-devargs="0000:01:00.0"}
Port vhost-client-1
Interface vhost-client-1
type: dpdkvhostuserclient
options: {vhost-server-path="/tmp/vhost-client-1"}
ovs_version: "2.16.1"
ovs-vsctl -- --columns=name,ofport 列表接口
name : br0
ofport : 65534
name : dpdk0
ofport : 6
name : vhost-client-1
ofport : 2
ovs-ofctl 转储流 br0
cookie=0x0, duration=104.689s, table=0, n_packets=0, n_bytes=0, in_port="vhost-client-1" actions=output:dpdk0
cookie=0x0, duration=99.573s, table=0, n_packets=4, n_bytes=924, in_port=dpdk0 actions=output:"vhost-client-1"
ovs-ofctl 显示 br0
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b8cef64def2e
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
2(vhost-client-1): addr:00:00:00:00:00:00
config: 0
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
6(dpdk0): addr:b8:ce:f6:4d:ef:2e
config: 0
state: 0
current: AUTO_NEG
speed: 0 Mbps now, 0 Mbps max
LOCAL(br0): addr:b8:ce:f6:4d:ef:2e
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
Libvirt XML配置(相关部分)
<domain type='kvm'>
<name>ubuntu-server</name>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<interface type='vhostuser'>
<mac address='52:54:00:16:a5:76'/>
<source type='unix' path='/tmp/vhost-client-1' mode='server'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</interface>
</devices>
</domain>
我缺少哪个配置选项?我已经遵循了几个指南,但我仍然无法在我的 VM 之间路由任何流量。
我怀疑问题与 ovs-ofctl 报告的 vhost-client-1 端口的 LINK_DOWN 状态有关显示 命令。我尝试使用命令 ovs-ofctl mod-port br0 vhost-client-1 up 将该状态设置为 UP。即使命令没有失败,也没有任何改变。
有什么想法吗?
suspect that the problem is related to the LINK_DOWN status of the vhost-client-1 port
[Answer] 是的,数据包未到达 VM 的原因是 OVS 发现接口已关闭。即使存在将流量从 dpdk0 转发到 vhost-client-1 的规则,数据包也会被丢弃。
link not up
的主要原因可能是由于 qemu 配置 memory backed
没有 hugepages用过的。 DPDK=OVS创建的vhost-USER端口驻留在大页内存区,需要访问大页内存
一个类似 Whosebug的地址使用viritio-client(通过cmdline)。所以请将共享设置调整为 link 到 virsh xml
模板:
<memory unit='KiB'>[VM memory size]</memory>
<currentMemory unit='KiB'>[VM memory size]</currentMemory>
<memoryBacking> <hugepages/> </memoryBacking>
[EDIT-1] 根据@ellere Vipin's answer was useful, but did not solve the issue. The configuration option I was missing was the numa option within the cpu element
.
分享的信息
根据使用的内存是否来自 NUMA-SOCKET 请添加适当的标签
最终,我设法解决了我的问题。 Vipin 的回答很有用,但没有解决问题。我缺少的配置选项是 cpu
元素中的 numa
选项。
我 post 工作配置文件以防它对其他人有用。第一部分是关于内存支持(在 domain
元素下):
<memory unit='KiB'>[VM memory size]</memory>
<currentMemory unit='KiB'>[VM memory size]</currentMemory>
<memoryBacking>
<hugepages>
<page size='2048' unit='KiB'/>
</hugepages>
<locked/>
<source type='file'/>
<access mode='shared'/>
<allocation mode='immediate'/>
<discard/>
</memoryBacking>
但我们还需要 numa
配置,即使我们的机器只有一个处理器:
<cpu mode='custom' match='exact' check='full'>
<model fallback='forbid'>qemu64</model>
<feature policy='require' name='x2apic'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='lahf_lm'/>
<feature policy='disable' name='svm'/>
<numa>
<cell id='0' cpus='0-1' memory='[VM memory size]' unit='KiB' memAccess='shared'/>
</numa>
</cpu>
我的目标是在覆盖网络上连接两个 QEMU-KVM 虚拟机。每个 VM 运行 在单独的物理主机上,并且必须在网络 10.0.0.0/24 上具有静态 IP。为了实现这个目标,我想使用带有 DPDK 的 OVS 桥。我想使用 vhost-user-client 协议连接 OVS 网桥和虚拟机。
我的物理设置如下:两台配备 Mellanox ConnectX6-DX 的物理机,背靠背连接(无物理交换机)。我想要实现的是:
+------------------+ +------------------+
| HOST_1 | | HOST_2 |
| | | |
| +------------+ | | +------------+ |
| | VM_1 | | | | VM_2 | |
| | | | | | | |
| | +--------+ | | | | +--------+ | |
| | | ens_2 | | | | | | ens_2 | | |
| | |10.0.0.1| | | | | |10.0.0.2| | |
| +-+---+----+-+ | | +-+---+----+-+ |
| | | | | |
| vhost-client-1 | | vhost-client-1 |
| | | | | |
| +-----+------+ | | +-----+------+ |
| | bridge | | | | bridge | |
| | br0 | | | | br0 | |
| |192.168.57.1| | | |192.168.57.2| |
| +-----+------+ | | +-----+------+ |
| | | | | |
| +---+--- | | +---+---+ |
| | dpdk0 | | | | dpdk0 | |
+----+---+--+------+ +----+---+---+-----+
| |
+-------------------------------+
我成功创建了 OVS 网桥(此处为 br0)和 DPDK 端口(此处为 dpdk0)。在每台物理机器上,我都能够 ping 通另一台机器上的网桥。然后,我创建了一个 vhost-user-client 端口并将其连接到网桥。在每个guest上,我按照上图分配了静态IP,ens2接口up
但是,此时我无法从 VM1 ping VM2,反之亦然。似乎根本没有通过 vhost-client 端口交换流量。 Ping 失败并显示 目标主机无法访问 消息。
一些有用的信息:
ovs-vsctl show
Bridge br0
datapath_type: netdev
Port br0
Interface br0
type: internal
Port dpdk0
Interface dpdk0
type: dpdk
options: {dpdk-devargs="0000:01:00.0"}
Port vhost-client-1
Interface vhost-client-1
type: dpdkvhostuserclient
options: {vhost-server-path="/tmp/vhost-client-1"}
ovs_version: "2.16.1"
ovs-vsctl -- --columns=name,ofport 列表接口
name : br0
ofport : 65534
name : dpdk0
ofport : 6
name : vhost-client-1
ofport : 2
ovs-ofctl 转储流 br0
cookie=0x0, duration=104.689s, table=0, n_packets=0, n_bytes=0, in_port="vhost-client-1" actions=output:dpdk0
cookie=0x0, duration=99.573s, table=0, n_packets=4, n_bytes=924, in_port=dpdk0 actions=output:"vhost-client-1"
ovs-ofctl 显示 br0
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000b8cef64def2e
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
2(vhost-client-1): addr:00:00:00:00:00:00
config: 0
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
6(dpdk0): addr:b8:ce:f6:4d:ef:2e
config: 0
state: 0
current: AUTO_NEG
speed: 0 Mbps now, 0 Mbps max
LOCAL(br0): addr:b8:ce:f6:4d:ef:2e
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
Libvirt XML配置(相关部分)
<domain type='kvm'>
<name>ubuntu-server</name>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<interface type='vhostuser'>
<mac address='52:54:00:16:a5:76'/>
<source type='unix' path='/tmp/vhost-client-1' mode='server'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</interface>
</devices>
</domain>
我缺少哪个配置选项?我已经遵循了几个指南,但我仍然无法在我的 VM 之间路由任何流量。
我怀疑问题与 ovs-ofctl 报告的 vhost-client-1 端口的 LINK_DOWN 状态有关显示 命令。我尝试使用命令 ovs-ofctl mod-port br0 vhost-client-1 up 将该状态设置为 UP。即使命令没有失败,也没有任何改变。
有什么想法吗?
suspect that the problem is related to the LINK_DOWN status of the vhost-client-1 port
[Answer] 是的,数据包未到达 VM 的原因是 OVS 发现接口已关闭。即使存在将流量从 dpdk0 转发到 vhost-client-1 的规则,数据包也会被丢弃。
link not up
的主要原因可能是由于 qemu 配置 memory backed
没有 hugepages用过的。 DPDK=OVS创建的vhost-USER端口驻留在大页内存区,需要访问大页内存
一个类似virsh xml
模板:
<memory unit='KiB'>[VM memory size]</memory>
<currentMemory unit='KiB'>[VM memory size]</currentMemory>
<memoryBacking> <hugepages/> </memoryBacking>
[EDIT-1] 根据@ellere Vipin's answer was useful, but did not solve the issue. The configuration option I was missing was the numa option within the cpu element
.
根据使用的内存是否来自 NUMA-SOCKET 请添加适当的标签
最终,我设法解决了我的问题。 Vipin 的回答很有用,但没有解决问题。我缺少的配置选项是 cpu
元素中的 numa
选项。
我 post 工作配置文件以防它对其他人有用。第一部分是关于内存支持(在 domain
元素下):
<memory unit='KiB'>[VM memory size]</memory>
<currentMemory unit='KiB'>[VM memory size]</currentMemory>
<memoryBacking>
<hugepages>
<page size='2048' unit='KiB'/>
</hugepages>
<locked/>
<source type='file'/>
<access mode='shared'/>
<allocation mode='immediate'/>
<discard/>
</memoryBacking>
但我们还需要 numa
配置,即使我们的机器只有一个处理器:
<cpu mode='custom' match='exact' check='full'>
<model fallback='forbid'>qemu64</model>
<feature policy='require' name='x2apic'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='lahf_lm'/>
<feature policy='disable' name='svm'/>
<numa>
<cell id='0' cpus='0-1' memory='[VM memory size]' unit='KiB' memAccess='shared'/>
</numa>
</cpu>