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)

  • 无标签

0 评论

你还没有登录。你所做的任何更改会将作者标记为匿名用户。 如果你已经拥有帐户,请登录