虚拟化环境中,对于网络的连接有多种方式,以KVM为例,我们平时在使用libvirt或者qemu创建虚拟机时,可以选择NAT网络连接和bridge桥接网络连接。首先来调查一下这二者的实现区别是什么。

基础虚拟网络

桥接网卡

首先来看下网卡桥接的连接方式,它相当于虚拟机和宿主机共用同一块物理网卡,虚拟机具有独立的IP地址,并且与宿主机所在网络处于同一个局域网,就相当于局域网中多了一台普通机器,可以直接访问局域网中的其他物理机,同一个局域网中的其他物理机当然也可以访问到该虚拟机。网络拓扑结构相当于下图所示:

bridge桥接

桥接时网络虚拟化的实现如下所示:
bridge实现架构

1.宿主机访问外部网络,通过eth0
2.宿主机访问虚拟机,通过bridge与VM互通
3.虚拟机访问宿主机,通过bridge与宿主机互通
4.虚拟机访问外部物理机,通过bridge转发到eth0出口
5.外部物理机访问虚拟机,数据通过NIC到eth0,利用bridge转发到对应VM
6.外部物理机访问宿主机,数据通过NIC到eth0,利用bridge转发到Host内核协议栈

这种模式下虚拟机像一个独立的主机一样拥有网络,和虚拟机处于同一个网段的其他物理机也可以直接访问到虚拟机内部。

NAT网络连接

这里介绍另外一种虚拟机的网络连接,就是NAT网络。对于NAT网络连接,虚拟网络的拓扑图如下所示:
NAT网络

NAT方式是kvm安装后的默认方式。它支持主机与虚拟机的互访,同时也支持虚拟机访问互联网,但不支持外界访问虚拟机。它在虚拟机和宿主机之间构建了一个局域网络,并且设置主机为默认网关,这样虚拟机就可以利用主机上的NAT功能,从而和主机使用同一个IP对外访问。实现如下所示:

NAT实现架构

图中可见,eth0属于物理上的一个子网,而虚拟机利用bridge组建了另外一个子网。默认情况下两个子网是互相不可达的,因此需要在宿主机上配置NAT,从而实现网络地址转换,所有虚拟机都通过eth0这一个网卡ip来访问外网。而对于外网来说,因为并不处于同一个子网内,所以是无法访问到虚拟机的,当然,如果想要访问虚拟机,也可以配置对应的NAT来让外网进行访问,不过相对于桥接方式来说,NAT操作更加麻烦。

虚拟交换机(vswitch)

Bridge

Bridge是一个虚拟网络设备,它具有网络设备的特性,可以配置IP、MAC地址,另外更关键的一点是Bridge扮演了虚拟交换机的角色。它的工作原理实际上和物理交换机一样,它具有多个端口,数据可以从任意一个端口进来,数据进来之后从哪里出去,根据端口对面的设备MAC地址来决定。通过了解上面两种网络连接方式,可以看出Bridge在虚拟网络中的重要性,它是最基础的一个vswitch实现,不管是使用NAT还是桥接,都需要创建一个Bridge来做vswitch。Bridge 还支持 VLAN 功能的,达到虚拟机之间的隔离,从而减少arp造成的泛洪。

从这里看,有了Bridge,是不是就可以部署到云上实现VPC了呢?按照以上的分析,确实可以选择 bridge+vlan+网络桥接 的方式来实现不同宿主机上虚拟机之间的互通。但这种架构并不够完美,因此各个厂商都在开发自己的vswitch,比如VMware vswitch以及 Open vSwitch等等。针对虚拟化云环境,厂商开发的vswitch更具优势,比如:

  • 支持SDN,数据平面和控制平面分离,支持可配置和监控。
  • 区分快速通道和慢速通道,实现流缓存,提高了转发效率,性能更强。
  • 支持隧道协议,比如GRE、VxLAN等,从而实现underlay和overlay网络的分离,构造更大的二层网络便于虚拟机的迁移操作。
Open-vSwitch

对于虚拟机和宿主机之间的通信可以直接利用tap设备,那么对于不同主机上的虚拟机之间的通信才是要解决的难点,当然我们可以利用kernel现有机制,比如bridge来达到目的,但是上面提到它并不是很适合云环境。更优的选择是使用一个更强大的,分布式的虚拟交换机ovs。

Open-vSwitch是支持openFlow协议的虚拟交换机,所谓OpenFlow协议,是一套SDN控制协议,不同厂商使用该标准实现交换机和controller能够相互兼容,从而便于实现SDN。功能框架如下图所示:

ovs

实际上可以看出内核态就是用OVS模块替换了上面提到的bridge,来做虚拟交换机的功能,不过OVS除了内核态,还有用户态服务配合一起使用,OVS包含有三个模块:

1.ovs-vswitchd:用户态服务,是OVS的核心组件,与ovsdb-server交互,与内核模块使用netlink交互,与SDN Controller使用OpenFlow协议交互,获取配置信息。
2.ovsdb-server:用户态服务,实现了一套轻量级数据库服务,用于保存配置信息,向ovs-vswitchd提供服务。
3.kernel module:内核模块,实现了数据平面,从ovs-vswitchd获取流表规则信息,并执行最终的流量转发动作。

Open vSwitch转发网络包都是利用kernel的数据路径的。在ovs的kernel模块中由一个简单的流表来处理包转发,如果处理的包刚好命中规则,就直接通过kernel的数据路径发送,这就是快速路径

如果上一步内核处理的包没有命中的缓存的规则,就需要切换到ovs-vswitchd来处理,找到对应的流表后会把新的规则更新到内核中,经过这样的一次处理过程叫做慢速路径

通过以上OVS这3个组件,可以支持SDN的一系列功能和Overlay网络,比较适合在云环境中进行部署。因此网络虚拟化的整体部署方案(搭配vhost-net和open-vswitch),参见下图(摘自redhat):

nodpdk

vhost-net是网络虚拟化功能的一种卸载方案,它减少了用户态和内核态之间的切换次数,提升了性能。虚拟机中运行virtio-net前端驱动,宿主机中运行vhost-net内核模块作为后端,两者利用共享内存实现vring,消息通知利用eventfd,实现思想就是把一些在用户态Qemu中实现的一些功能移到内核态,以减少交互的开销。

OVS处于虚拟化Port和物理Port之间,用于包的转发,这里使用OVS来替换了Brigde,来实现更加强大的虚拟交换机功能。对于虚拟机的Port实际上还是使用tap设备,如下图所示(摘自redhat):
nodpdk1

随着技术的发展,基于DPDK的加速方案逐渐成为了主流,在上面的图中,可以看出整个OVS是分为内核态和用户态的,更极致的做法就是把内核网络功能挪到用户态,包括OVS的实现也是用户态的,因而当下更先进的技术就是搭配DPDK使用的ovs-dpdk。把网络协议栈和内核态的OVS功能全部挪到用户态实现。技术框架图如下(摘自redhat):
ovs-dpdk
在这种架构中就不使用内核的那一套机制了,OVS数据平面和控制平面都在用户态,转发策略也都存在于用户态中。因而抛弃了内核的网络协议栈实现,针对高性能场景重新开发用户态协议栈,加速了网络性能。

vhost-net与vhost-user最大的区别在于,QEMU与后端交互的方式,Vhost-net是通过QEMU与字符设备进行ioctl实现,而vhost-user则是通过unix socket来实现通信,QEMU和vhost lib是通信的双方,当然DPDK中已经对vhost-user协议进行了支持。


https://www.redhat.com/en/blog/introduction-virtio-networking-and-vhost-net
https://www.redhat.com/en/blog/deep-dive-virtio-networking-and-vhost-net
https://www.redhat.com/en/blog/how-vhost-user-came-being-virtio-networking-and-dpdk

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐