qemu 对于外部网卡的配置方式

269 阅读6分钟

qemu 对于外部网卡的配置方式: 比如基于 linux bridge 或者 ovs bridge(或者 macvtap sriov 等)

qemu 设计了一种基于(启动)脚本和(清理)脚本的方式来处理外部网卡的情况



root@debian:~                                                                                                                                                                                                                 
▶ qemu-system-x86_64 --help | grep -A 30 "netdev tap"
-netdev tap,id=str[,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile]
         [,br=bridge][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off]
         [,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off][,queues=n]
         [,poll-us=n]
                configure a host TAP network backend with ID 'str'
                connected to a bridge (default=br0)
                use network scripts 'file' (default=/etc/qemu-ifup)
                to configure it and 'dfile' (default=/etc/qemu-ifdown)
                to deconfigure it
                use '[down]script=no' to disable script execution
                use network helper 'helper' (default=/usr/lib/qemu/qemu-bridge-helper) to
                configure it
                use 'fd=h' to connect to an already opened TAP interface
                use 'fds=x:y:...:z' to connect to already opened multiqueue capable TAP interfaces
                use 'sndbuf=nbytes' to limit the size of the send buffer (the
                default is disabled 'sndbuf=0' to enable flow control set 'sndbuf=1048576')
                use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag
                use vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition
                use vhost=on to enable experimental in kernel accelerator
                    (only has effect for virtio guests which use MSIX)
                use vhostforce=on to force vhost on for non-MSIX virtio guests
                use 'vhostfd=h' to connect to an already opened vhost net device
                use 'vhostfds=x:y:...:z to connect to multiple already opened vhost net devices
                use 'queues=n' to specify the number of queues to be created for multiqueue TAP
                use 'poll-us=n' to specify the maximum number of microseconds that could be
                spent on busy polling for vhost net
-netdev bridge,id=str[,br=bridge][,helper=helper]
                configure a host TAP network backend with ID 'str' that is
                connected to a bridge (default=br0)
                using the program 'helper (default=/usr/lib/qemu/qemu-bridge-helper)


在 QEMU 的网络配置中,scriptdownscript 选项允许用户指定在虚拟机网络接口创建和销毁时执行的脚本。通过这些选项,用户可以实现更复杂和灵活的网络配置,特别是在使用虚拟化和云环境时。

设计思路

  1. 自动化网络配置: script=ovs-ifupdownscript=ovs-ifdown 的使用使得虚拟机的网络接口在启动和停止时可以自动配置。通过脚本,用户可以设置虚拟网络接口的属性,绑定到 Open vSwitch(OVS)桥接,以及其他网络设置。
  2. 灵活性与可扩展性: 使用脚本提供了高度的灵活性,用户可以根据自己的需求编写脚本来实现特定的网络配置。例如,可以添加 VLAN 标签、设置 QoS 策略,或动态调整网络参数。
  3. 集成现有网络管理工具: 使用 ovs-ifupovs-ifdown 脚本可以直接与 Open vSwitch 集成,使 QEMU 虚拟机能够无缝地融入现有的网络架构中。这种集成有助于在虚拟化环境中保持网络策略的一致性。

使用场景

  • 云服务提供商: 在公有云或私有云环境中,为每个虚拟机创建和管理网络接口是常见需求。使用上述脚本,云服务商可以确保每个虚拟机在启动时能够自动获得正确的网络配置。
  • 实验和测试环境: 开发人员可以使用 scriptdownscript 来快速创建和销毁网络接口。这在测试网络应用程序或网络配置时非常有用。
  • 大规模部署: 在需要快速部署多个虚拟机并确保它们所有网络接口都符合一定配置标准的场合,使用脚本可以显著减少手动配置的工作量,从而提高效率。

示例

在一个典型的使用场景中,用户可能会编写如下的 ovs-ifupovs-ifdown 脚本:

  • ovs-ifup 脚本:

    #!/bin/bash
    # Configure the interface for Open vSwitch
    OVS_BRIDGE="br0"
    sudo ip link set "$1" up
    sudo ovs-vsctl add-port "$OVS_BRIDGE" "$1"
    
  • ovs-ifdown 脚本:

    #!/bin/bash
    # Remove the interface from Open vSwitch
    OVS_BRIDGE="br0"
    sudo ovs-vsctl del-port "$OVS_BRIDGE" "$1"
    sudo ip link set "$1" down
    

这个设计思路和使用场景展示了如何通过 QEMU 的网络脚本增强虚拟化环境的网络管理。

在 QEMU 的网络配置中,当你使用 scriptdownscript 选项时,默认情况下,QEMU 会查找这些脚本:

  1. 默认路径

    • script: 默认位置是 /etc/qemu-ifup
    • downscript: 默认位置是 /etc/qemu-ifdown

如果你希望使用自定义脚本,必须在 -netdev 选项中显式指定脚本的路径。例如:

-netdev tap,id=str,script=/path/to/your/ovs-ifup,downscript=/path/to/your/ovs-ifdown

自定义路径的最佳实践

  • 确保脚本具有执行权限 (chmod +x script_path)。
  • 在脚本中使用绝对路径,以确保 QEMU 能够找到依赖的命令和资源。
  • 可以将脚本放置在任何合适的目录中,只要在 -netdev 选项中指定正确的路径。

这种灵活性允许你根据系统环境和管理策略来组织你的脚本。

demo


sudo qemu-system-x86_64 -vnc :1 -gdb tcp::1234,server,nowait -m 2G -smp 2 \
  -chardev stdio,mux=on,id=stdio -mon chardev=stdio,mode=readline,default \
  -device isa-serial,chardev=stdio -drive file=osv-v0.04.qcow2,if=virtio,cache=unsafe \
  -netdev tap,id=hn0,script=qemu-ifup.sh,vhost=on -device virtio-net-pci,netdev=hn0,id=nic1 \
  -device virtio-rng-pci -enable-kvm -cpu host,+x2apic

在 QEMU 配置中,-netdev-deviceid 值并不需要一致,但它们之间有一定的关系。下面解释这两者之间的作用和如何理解它们的 id 参数。

-netdev-device 的不同

  1. -netdev:

    • 该选项定义了网络设备的类型(例如 tapuserbridge 等)及其相关的配置。
    • id=hn0 是给网络设备实例分配的唯一标识符。此 id 在 QEMU 的内部使用,用于识别特定的网络设备。
  2. -device:

    • 该选项往往用于定义与实际虚拟设备相关的更多详细信息和参数(例如网卡型号、连接方式等)。
    • 在你的例子中,-device virtio-net-pci,netdev=hn0,id=nic1 中的 netdev=hn0 指的是前面定义的 -netdevid,表明该虚拟设备与 hn0 网络设备相连接。
    • id=nic1 是为虚拟网络接口卡分配的唯一标识符,用于在 QEMU 中引用这块设备。

为什么 id 不一致

  • 唯一性与作用:

    • hn0netdev 的标识符,它指定了网络设备的类型和配置。
    • nic1device 的标识符,指定了具体的虚拟网络接口卡。它们的 id 不需要一致,因为它们的上下文不同:一个是网络设备,另一个是连接到该设备的实际网络接口。
  • 设计灵活性:

    • 这样的设计允许用户在 QEMU 中灵活地配置不同类型的网络设备,同时与多个设备连接。用户可以为不同的网络设备和虚拟设备分配更具描述性的 id,方便管理和调试。

示例

以下是如何使用这些标识符的一个简单示例:

-netdev tap,id=hn0,script=qemu-ifup.sh             # 创建一个 tap 网络设备
-device virtio-net-pci,netdev=hn0,id=nic1          # 创建一个 VirtIO 网卡连接到 hn0
-device virtio-net-pci,netdev=hn0,id=nic2          # 再创建一个 VirtIO 网卡连接到同一个 hn0

在这个例子中,两个网卡 nic1nic2 都连接到同一个 netdev (hn0),但它们的 id 不同,这样便于在 QEMU 中进行追踪和控制。

总结

在 QEMU 中,-netdev-deviceid 不一致是设计上的考虑,通过这种方式,QEMU 可以更灵活地管理网络设备和虚拟接口。在配置时,关注适当的连接关系和标识符的清晰性,可以确保网络配置正常。

参考:

  1. github.com/cloudius-sy…
  2. gist.github.com/hisaki/3791…