在以下两篇文章中我们介绍了虚拟网卡技术以及虚拟交换机技术,今天我们再来详细说说在在kvm网络模式下这两种技术的具体应用情况。
网络虚拟化之 tun/tap 网络设备
linux网桥简单理解和持久化配置
以下是常见的kvm网络桥接模式的结构示意图,vnet就是虚拟网卡,br0就虚拟交换机,整体如下图所示:
以下是我们测试环境中运行的4台虚拟机,以及桥接模型下网络连接关系,如下图所示:
从上面的结构图中我们可以看出,虚拟机和物理机之间通信需要依赖vnet虚拟网卡才可以通信,网络上大部分资料都未明确说明具体使用的是tun设备还是tap设备,下面就揭开神秘的面纱。
由于我们虚拟机是使用kvm技术创建的,因此我们可以从qemu-kvm进程中查找相关信息,我们执行命令:
# ps -ef | grep kvm | grep tap
结果返回值(kvm创建虚拟机参数):
• 从HOST角度:
-netdev tap,fd=29,id=hostnet0,vhost=on
• 从GUEST角度:
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:55:77:e3
可以看到,host上使用tap类型的网卡,开启了vhost-net技术。
因此我们可以明确在kvm网络桥接模式中使用的虚拟网卡是tap设备。
Tun/Tap虚拟网络设备的原理比较简单,它都是在Linux内核中添加了一个Tun/Tap虚拟网络设备的驱动程序和一个与之相关连的字符设备/dev/net/tun,字符设备tun作为用户空间和内核空间交换数据的接口。
用户空间的应用程序可以通过这个设备文件来和内核中的驱动程序进行交互,其操作方式和普通的文件操作无异。当内核将数据包发送到虚拟网络设备时,数据包被保存在设备相关的一个队列中,直到用户空间程序通过打开的字符设备tun的描述符读取时,它才会被拷贝到用户空间的缓冲区中,其效果就相当于,数据包直接发送到了用户空间。通过系统调用write发送数据包时其原理与此类似。
从结构上来说,Tun/tap驱动并不单纯是实现网卡驱动,同时它还实现了字符设备驱动部分。以字符设备的方式连接用户态和核心态,下面是示意图:
我们从kvm创建虚拟机参数截图中可以看出,当前有一个fd=29的文件描述符,这个就是读写/dev/net/tun文件的文件描述符。
我们使用lsof -p 4519 | grep tun
验证下:
可以看到,PID 为 4519 的进程打开了文件 /dev/net/tun,分配的文件描述符 fd 为 29
因此,我们可以得出以下结论:在 kvm 虚机启动时,会向内核注册 tap 虚拟网卡,同时打开设备文件 /dev/net/tun,拿到文件描述符 fd,然后将 fd 和 tap 关联,tap 就成了一端连接着用户空间的 qemu-kvm,一端连着主机上的 bridge 的端口,促使两者完成通信
在我们测试环境下,我们已经运行了4台虚拟机,此时我们在主机上用ifconfig命令,可以看到会多出几个vnet开头的虚拟网卡,如下所示:
vnet这几个虚拟网卡没有ip信息,在/etc/sysconfig/network-scripts目录下也没有对应的配置文件,因此这个几个设备是虚拟的。
若我们把虚拟机1给关机,对应vnet0虚拟网卡也不在显示,因为tap设备是一个点对点的设备,同虚拟机的一起创建和消失。
如果我们有权限的话,可以对某一台虚拟机的xml配置文件查看的话,在interface段会有如下的相关信息。(说明:这里查看的是另外台服务器上的虚拟机xml配置文件)
从以上配置中可以看出,当前虚拟机采用桥接模式并且与网桥设备br0进行关联。
在当前服务器上虚拟网桥设备名称为mgmtnet,目前从属4个虚拟网卡以及一个物理网卡en01,如下图所示:
几点说明:
1、虚拟网卡vnet#是创建虚拟机的时候自动创建的。我们要做的就是将网桥设备关联到虚拟网卡vnet#上。
2、虚拟网卡vnet#,#代表数字序号,比如0,1,2,3…这个顺序是你先后创建虚拟机的次序排出来的,从0开始计数。
3、一般上,我们创建虚拟机好之后,无需关心vnet#虚拟网卡。你只要在虚拟机里面配置网卡eth0即可,这样就可以上网了。
以上就是对KVM网络桥接模式底层网络原理进行解说,综合了虚拟网卡设备和虚拟交换机在实际当中的应用。
参考文档:
1、https://blog.csdn.net/xiakewudi/article/details/76851076
2、https://www.cnblogs.com/FengGeBlog/p/10452700.html
3、https://cloud.tencent.com/developer/article/1432484