- 创建者: 虚拟的现实,上次更新时间:7月 22, 2024 需要 5 分钟阅读时间
vmware ova 文件转换为 qcow2
安装 qemu 工具
apt-get install qemu-utils # yum install qemu-img
解压 ova 文件
tar -xvf appliance.ova
解压后会有对应的 vmdk 磁盘文件
转换格式
qemu-img convert -O qcow2 input.vdi output.qcow2 qemu-img convert -O qcow2 input.vmdk output.qcow2
qemu 命令启动对应的虚拟资源
emu-system-x86_64 \ -m 1024 \ -smp 2 \ -enable-kvm \ -drive if=none,id=disk00,format=qcow2,file=/var/lib/libvirt/images/Router/ROS7-6G-disk1.qcow2 \ -device "ide-hd,drive=disk00,bus=ide.0,serial=00000000000000000001,model=VMware Virtual IDE Hard Drive" \ -nic tap \ -bios /usr/share/OVMF/OVMF_CODE.fd
QEMU 虚拟机网络模拟
概述
QEMU 可以模拟多种网卡设备(例如 PCI 或者 ISA 设备),同时可将这些虚拟网卡与 host 上的虚拟网络设备(或者虚拟的 hub )连接起来。各种不同类型的网络设备既可以为虚拟机提供真实的网络访问(例如 TAP、SLiRP user 模式),也可以是同一个 host 上面的不同虚拟机之间的访问(Socket)。
常见的网络设备实现有4种:
User mode stack:用户协议栈方式,这种方式的大概原理是在 QEMU 进程中实现一个协议栈,这个协议栈可以被视为一个主机与虚拟机之间的 NAT 服务器,它负责将 QEMU 所模拟的系统网络请求转发到外部网卡上面,从而实现网络通信。但是不能将外面的请求转发到虚拟机内部,并且虚拟机 VLAN 中的每个接口必须放在 10.0.2.0 子网中。
socket: 为 VLAN 创建套接字,并把多个 VLAN 连接起来。
TAP/bridge:最重要的一种通信方式,我们想要实现 QEMU 虚拟机和外部通信就需要使用这种方式。
VDE:也是用于连接 VLAN 的,如果没有 VLAN 连接需求基本用不到。
重点解释一下 tap 模式,TAP 属于 LInux 内核支持的一种虚拟化网络设备,还有 TUN 也属于这种设备,它们完全由软件模拟实现,TUN/TAP 负责在内核协议栈和用户进程之间传送协议数据单元。TUN 工作在网络层,而 TAP 工作在数据链路层,TUN 负责与应用程序交换 IP 数据包,而 TAP 与应用程序交换以太网帧。所以 TUN 经常涉及路由,而 TAP 常用于网络桥接。
所谓桥接可以简单理解为在两张网卡之间搭一座桥,一端有数据就可以通过桥走到另一端,对于实现 QEMU 虚拟机通信正合适。桥接技术在 VMWARE 中非常常用,我们设置虚拟机网络的时候就能看见桥接选项,实际上 VMware 在物理机上虚拟化了 3 张网卡,分别负责桥接、仅主机、共享网络。
NAT方式
如图所示,NAT 方式与家里上网的方式有点类似,虚拟机在一个子网内(192.168.122.255),宿主机看做双网卡(虚拟了一个网卡),这也是 QEMU 默认就支持的。
QEMU默认的NAT (SLiRP)
首先,在我们没有为 QEMU 指定任何网络参数的情况下,我们很多时候依然可以使用网络,拓扑结构如下图所示:
这是因为通常在编译 QEMU 的时候,默认会编译模块 SLiRP (除非显式的指定--disable-slirp),这样 QEMU 在创建虚拟机的时候,即便用户不指定,也会有默认的参数-net=user。user mode的NAT网络优缺点很明显:
- 设置最为简单,不需要额外的配置就能满足虚拟机最基本的网络需求。
- 缺点是这个 NAT 网络也仅仅是“最基本“的需求。slirp 模块有许多网络协议不支持,最常见的 ICM P不支持,所以,在虚拟机中是无法使用 ping 的
通过 TAP 配置 NAT
拓扑结构跟 user 模式一模一样。
1、确保已安装libvirt-clients和libvirt-daemon
apt-get install libvirt-clients //使用virsh apt-get install libvirt-daemon libvirt-daemon-system libvirt-daemon-system-systemd //使用libvirtd apt-get install qemu-system-common //使用qemu-bridge-helper apt-get install bridge-utils //使用brctl
确保libvirt-daemon服务开启
systemctl start libvirtd systemctl enable libvirtd
如果遇到libvird启动失败,尝试一下:
brctl addbr br0 add bridge failed: Package not installed
如果出现上述错误,说明需要重新编译内核,同时需要打开 networking > 802.1d Ethernet Bridging
如果 libvirtd 启动成功的话会出现一个虚拟桥 virbr0 和 virbr0-nic:
ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether d4:5d:df:07:c1:07 brd ff:ff:ff:ff:ff:ff inet 10.239.48.54/24 brd 10.239.48.255 scope global dynamic noprefixroute eno1 valid_lft 12387sec preferred_lft 12387sec inet6 fe80::d65d:dfff:fe07:c107/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:d3:6d:2d brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000 link/ether 52:54:00:d3:6d:2d brd ff:ff:ff:ff:ff:ff
2、使用virsh配置网络
在没有进行任何网络配置之前,应该是这样的:
virsh net-list --all Name State Autostart Persistent ----------------------------------------------------------
一个比较偷懒的办法是使用现成的配置文件 /etc/libvirt/qemu/networks/autostart/default.xml,内容如下:
<network> <name>default</name> <uuid>417b7ead-6342-40a4-b29f-02fa2d4df491</uuid> <forward mode='nat'/> <bridge name='virbr0' stp='off' delay='0'/> <mac address='52:54:00:d3:6d:2d'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254'/> </dhcp> </ip> </network>
或者显示的给出 default.xml
virsh net-define default.xml virsh net-start default virsh net-list --all Name State Autostart Persistent ---------------------------------------------------------- default active yes yes
如果看到看到上面的结果,那么“虚拟桥”(virt bridge)就配置成功了。
注意STP:有些公司的IT部门可能不喜欢STP,所以,一定注意default.xml中的stp=‘off’。
或者使用在绑定网卡之前,使用命令行关掉stp
brctl stp virbr0 off brctl show bridge name bridge id STP enabled interfaces virbr0 8000.525400b98f9a no virbr0-nic
实际上虚拟机通过NAT联网的时候,各个网络设备之间的关系如图所示:
3、QEMU创建虚拟机
qemu-system-x86_64 --enable-kvm -M q35 -m 4G -smp 1 -hda /root/ubuntu1904.qcow -vnc :7 \ -device virtio-net-pci,netdev=nic0,mac=00:16:3e:0c:12:78 \ -netdev tap,id=nic0,br=br0,helper=/usr/local/libexec/qemu-bridge-helper,vhost=on
因为使用了工具qemu-bridge-helper,它需要一个配置文件:
/usr/local/etc/qemu/bridge.conf:(这个目录默认没有,创建,如果没有这个文件qemu-bridge-helper会提示的) #把我们有可能用得到的网桥名字都列在这里。 allow br0 allow br1 allow virbr0
顺利的话,虚拟机起来之后会DHCP得到一个IP例如192.168.122.177。
Bridge 方式
首先确定机器支持 TAP/TUN 虚拟设备,安装如下软件
apt-get install bridge-utils # 虚拟网桥工具 apt-get install uml-utilities # UML(User-mode linux)工具
添加网桥,大部分操作都需要 root 权限:
ifconfig <你的网卡名称(能上网的那张)> down # 首先关闭宿主机网卡接口 brctl addbr br0 # 添加名为 br0 的网桥 brctl addif br0 <你的网卡名称> # 在 br0 中添加一个接口 brctl stp br0 off # 如果只有一个网桥,则关闭生成树协议 brctl setfd br0 1 # 设置 br0 的转发延迟 brctl sethello br0 1 # 设置 br0 的 hello 时间 ifconfig br0 0.0.0.0 promisc up # 启用 br0 接口 ifconfig <你的网卡名称> 0.0.0.0 promisc up # 启用网卡接口 dhclient br0 # 从 dhcp 服务器获得 br0 的 IP 地址 brctl show br0 # 查看虚拟网桥列表 brctl showstp br0 # 查看 br0 的各接口信息
当配置完成之后执行 ifconfig 结果应该如下
此时网桥已经得到了 IP,并且能够连接网络的网卡 enp0s5 也加入了网桥,此时我们的网桥状态大致是这种情况
桥的一端连接到 enp0s5,我们只需要再把另一端接到 QEMU 虚拟机(准确的说是 VLAN )上面就可以了。
创建一个 TAP 设备,作为 QEMU 一端的接口:
tunctl -t tap0 -u root # 创建一个 tap0 接口,只允许 root 用户访问 brctl addif br0 tap0 # 在虚拟网桥中增加一个 tap0 接口 ifconfig tap0 0.0.0.0 promisc up # 启用 tap0 接口 brctl showstp br0 # 显示 br0 的各个接口
此时网桥的信息应该是:
这样就相当于把两张网卡通过网桥连起来了:
现在只需要启动镜像,指定网络连接模式是 TAP 即可。
qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -nographic -net nic -net tap,ifname=tap0,script=no,downscript=no
特别说明一下参数含义:
- -net nic 表示希望 QEMU 在虚拟机中创建一张虚拟网卡
- -net tap 表示连接类型为 TAP,并且指定了网卡接口名称(就是刚才创建的 tap0,相当于把虚拟机接入网桥。
- script 和 downscript 两个选项的作用是告诉 QEMU 在启动系统的时候是否调用脚本自动配置网络环境,如果这两个选项为空,那么 QEMU 启动和退出时会自动选择第一个不存在的 tap 接口(通常是 tap0)为参数,调用脚本 /etc/qemu-ifup 和 /etc/qemu-ifdown。
由于我们已经配置完毕,所以这两个参数设置为 no 即可。
QEMU 创建虚拟机
qemu-system-x86_64 --enable-kvm -M q35 -m 4G -smp 1 -hda /root/ubuntu1904.qcow -vnc :7 \ -device virtio-net-pci,netdev=nic0,mac=00:16:3e:0c:12:78 \ -netdev tap,id=nic0,br=br0,helper=/usr/local/libexec/qemu-bridge-helper,vhost=on
删除网桥
ip link set dev enp3s0f1 nomaster ip link set dev br0 down ip link del br0
pass-through物理网卡
这种方法的网络拓扑结构跟bridge方式是一样的,不过这次虚拟机成为货真价实的网上邻居,因为它使用的是物理网卡。如果host上恰好有一个多余的网卡,不妨试下这个方法,它拥有理论上跟host一样的网络性能,使用虚拟机的网卡驱动。
pass-through物理网卡虽然实现起来相对复杂,但用起来却比较容易:
确保host没有加载对应网卡的驱动
不过通常这都不太可能,可以参考这个脚本
# ./vfio-pci.sh -h <B:D:F>
QEMU创建虚拟机
qemu-system-x86_64 --enable-kvm -M q35 -m 4G -smp 1 -hda /root/ubuntu1904.qcow -vnc :7 \ -device vfio-pci,host=81:00.0,romfile=
相比几种方法,去掉了复杂的网络参数,仅仅加上了一个设备,并且指定其B:D:F是需要被pass-through给虚拟机的网卡对应的B:D:F的即可(例子中为81:00.0)
- 无标签
添加评论