让虚拟机(guest)能够访问外网的方法很多,这里介绍一个我所了解的最简单的办法:macvtap。

1. 设置libvirt的虚机配置xml文件的网络部分如下:

点击(此处)折叠或打开

  1. <!-- macvtap LAN - direct connection from host to guest -->
  2.       <interface type='direct'>
  3.         <mac address='02:00:00:12:01:02'/>
  4.         <source dev='enccw0.0.f500' mode='bridge'/>
  5.         <model type='virtio'/>
  6.         <address type='pci' domain='0x0' bus='0x00' slot='0x07' function='0x0'/>
  7.       </interface>
这里的source dev就是guest想利用来上网的host上的网卡。mac address是虚机网卡的mac地址,不和host一样就行。如果是IBM主机,那么需要把address type替换成:

点击(此处)折叠或打开

  1. <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0002'/>

2. 检查内核模块有没有包含macvtap功能:

lsmod|grep macvtap,如果有,则如下所示:

macvtap                24576  3 vhost_net
macvlan                24576  1 macvtap

如果没有,再检查内核符号表看看macvtap是不是被直接链接进内核里: grep macvtap /proc/kallsyms,如果能找到象macvtap_poll这样的函数,那么说明macvtap已经被链接到内核里。否则说明当前内核没有包含macvtap功能,需要把它加进去。方法同样有两种:

1) 通过模块加入:modprobe macvtap,如果成功,那么lsmod |grep macvtap就会找到内容。否则下载对应的内核版本(git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git),make defconfig,在.config里面加入CONFIG_MACVTAP=m和CONFIG_MACVLAN=m,make && make modules_install。新的模块应该会被安装到/lib/modules目录下,再次运行modprobe macvtap,这次应该可以成功。

2) 直接更新内核。跟1)一样下载内核,在.config里面加入CONFIG_MACVTAP=y和CONFIG_MACVLAN=y,运行make && make modules_install && make install,新的内核会被安装到/boot目录下。修改启动配置文件,让它指向新内核,重启系统。然后检查/proc/kallsyms,可以看到macvtap对应的函数已经在内核里,表示新内核已被安装使用。

3. 运行步骤1中定义的guest,如果xml文件里定义了dhcp网络方式,那么guest 网卡会自动从dhcp服务器获得ip地址,否则就需要自己设置ip地址如下: ifconfig eth0 192.168.0.100/24 up

这里的ip地址和子网掩码要设置成和host的eth0在一个网段里、并且没有使用的ip。

4. 测试网络:通过ping host网段里的其他机器可以知道guest网络是否已经连通,如果host可以连上外网,那么guest这时也应当能够连上外网。

原理如下:
如何让虚拟机访问外网-LMLPHP
这里App就是qemu。


参考文档:
http://wiki.libvirt.org/page/Networking

https://virt.kernelnewbies.org/MacVTap

12-17 05:08