众所周知在Linux系统中PID、IPC、Network等都是全局性的资源,任何的修改和删减都会对整个系统造成影响,这也是为什么KVM之类的虚拟化技术需要模拟一个完整成主机系统的原因。但是,在Linux NameSpace中这些PID、IPC、Network等都不再是全局性的资源,基于NameSpace的虚拟化技术是内核级别的虚拟化,具有敏捷、安全、资源轻消耗等优点。在云计算的信息化建设中,计算资源和存储资源的虚拟化已经做的非常好并且具有丰富的解决方案。但是网络的虚拟化的技术还在逐步成熟的过程中,在网络虚拟化技术中目前最主流的技术就是基于NameSpace网络虚拟化技术(我更觉得应该称为NFV:网络功能虚拟化)。该篇文章意在通过对Network NameSpace的解析来统一的介绍一下OpenStack网络实现原理,以期帮助需要的伙伴更好的理解网络虚拟化相关技术。
Linux NameSpace
Linux NameSpace是Linux提供的一种OS-level virtualization的方法。目前在Linux系统上实现OS-level virtualization的系统有Linux VServer、OpenVZ、LXC Linux Container、Virtuozzo等,Linux NameSpace提供了PID、IPC、UTS、Mount、Network等系统资源的完全隔离机制。这种完全隔离机制的实现是靠不同NameSpace中的进程彼此之间互不干扰,即使是同样的进程只要在不同的NameSpace中也不会产生冲突。为了更好的理解这一点,我们略加分析一个PID例子。在所有的Linux系统中都存在一个init进程(即初始化进程),其PID=1,而由于在不同的NameSpace中的进程都是彼此透明的,因此在不同的NameSpace中都有自己的PID=1的init进程,相应的NameSpace内的进程都将以该进程为父进程,当该进程被结束时该NameSpace内所有的进程都会被结束。换句话说,在同一个Linux系统中由于NameSpace的存在,可以允许n个相同的进程存在并互不干扰的运行。
Network NameSpace
一个Network NameSpace为进程提供了一个完全独立的网络协议栈的视图,包括网络设备接口、IPv4和IPv6协议栈、IP路由表、防火墙规则、Sockets等等。在这样的情况下,一个Network NameSpace可以是一个交换机、也可以是一个路由器、或者是一个防火墙等,这就相当于Network NameSpace提供了一个完全的系统环境(这也是NameSpace的基本特性)。在Network NameSpace中有两个概念是实现Network NameSpace的全部网络功能的关键,一个是虚拟接口,一个是虚拟网桥。这里先概念性的阐明两条实现规则,后面的OpenStack和docker网络实现中会具体用到并结合实例进行解释。第一条:一个虚拟接口只能属于一个Network NameSpace,但是可以从一个Network NameSpace转移到另外一个Network NameSpace中,虚拟接口都是成对出现的,发给其中一个接口的数据另外一个接口也会接到;第二条:一个虚拟网桥可以接多个虚拟接口,且网桥能使数据在这些虚拟接口上进行转发。
OpenStack的网络实现
OpenStcak从Havana版本开始将其网络项目更名为Neutron,从H版到最近发布的Kilo版本Neutron的功能和组件都进行了很多的优化和改进。在OpenStack的网络实现模式中,Neutron+OpenvSwitch是一种常见的网络实现模式,也有的是使用Neutron+Bridge模式实现的。由于最近自己研究的是Neutron+OpenvSwitch的模式,对这种模式下的Network NameSpace实现机制理解的比较好,所以就以这种模式为例解析一下OpenStack利用Network NameSpace机制的网络实现。
1. OVS、虚拟接口(veth pair)、Linux Birdge:在OVS中包含bridge和ports,在一个OVS中包含两个bridge,每个bridge上包含若干个ports。OVS中一个网桥(bridge-ethx)用于连接主机的物理网卡ethx,另一个网桥(bridge-int)用于连接Linux bridge和虚拟机的网络接口,而两个网桥之间是通过一对veth pair进行连接(可以理解为一根虚拟网线)。veth pair 都是成对出现的,发一个数据包给其中一个接口,另外一个接口也会接到。Linux bridge主要是用于连接虚拟机和OVS bridge-int以及进行安全策略的设置和安全组的实现。
2. Network NameSpace:在Neutron中创建一个虚拟网络时,Neutron都会创建一个Network NameSpace。Network NameSpace上有两个网络接口,一个是loop设备,一个用于连接OVS上的bridge-int。从此可知,Neutron创建的这个Network NameSpace通过OVS连接到虚拟机网络中。当一个虚拟机被创建时,虚拟机上的网络接口会连接到Linux bridge的接口上,同时虚拟机的网络接口会根据预配置的Network NameSpace 和虚拟机都连接到了OVS的bridge-int网桥上,从物理链路上就打通了。Neutron在Network NameSpace中会启动DHCP服务,这样当物理链路打通后在接收到新建虚拟机的DHCP请求时就会分配一个和Network NameSpace同网段的IP地址,这样虚拟机和Network NameSpace连接在bridge-int上的网络接口就具备相同的vlan id,而根据OVS的网络隔离机制同一个vlan id的网络接口是可以相互转发数据的。
3. 虚拟机间的同网络通信:每新建一个虚拟机都会通过虚拟机的网络接口连接到Linux Bridge网桥上,然后通过Linux Birdge连接到OVS bridge-int上,最终通过OVS bridge-ethx接入到虚拟机网络中。在新建虚拟机时,我们需要预先设置好该虚拟机属于哪个网络,虚拟机进行网络初始化时就会发送DHCP请求,相对应的,网络的Network NameSpace在接收到新建虚拟机的DHCP请求时都会分配一个自己所在网络的IP地址给新建的虚拟机,这样具备同样网络IP地址段的虚拟机就可以相互进行通信。在这里简要解释一个Neutron的网络隔离,在Neutron中通过设置可以使用VLAN、VXLAN、GRE等进行网络隔离与通信。不过由于使用VLAN是最符合传统网络认知的,所以我们就在OVS上使用的是通过VLAN进行网络隔离的方式。
4. 虚拟机不同网络之间的路由通信:如前面所讲,在Neutron上每创建一个网络都会新建一个Network NameSpace服务,那么现在假设有了两个网络,也就有了两个Network NameSpace,但是这两个NameSpace是相互独立的,因为他们在不同的网络中。现在如果我们想打通这两个网络,我们就需要另外一个Network NameSpace——Router Network NameSpace,Router Network NameSpace可以拥有2个以上的网络接口。在传统的网络环境中,我们知道如果要和一个网络通信,只要和其网关相通就可以了。在这里也是采用这样的原理,在Neutron中我们可以使用命令将两个需要相互连通的网络加入到Router Network NameSpace中,这时Router Network NameSpace中就会出现两个网络接口连接到OVS bridge-int上,并且这两个网络接口的IP地址就是两个网络的网关。除此以外,我们需要在Router Network NameSpace中设置net.ipv4.ip_forward参数为1,这样就可以在Router Network NameSpace内部进行不同网段数据的转发,至此两个不同网络就可以打通了。
以上就是一个OpenStack利用NameSpace进行网络实现方法的原理解析,希望可以帮助大家能够更好的理解OpenStack的网络实现。如果文中解析有错误和不到位的地方,还请大家能够不吝赐教。
SDNLAB语:OpenStack虚拟网络Neutron把部分传统网络管理的功能推到了租户上,租户通过它可以创建一个自己专属的虚拟网络及其子网、路由器等,在虚拟网络功能的帮助下,基础物理网络就可以向外提供额外的网络服务,比如租户完全可以创建一个属于自己的类似于数据中心网络的虚拟网络,也可以将隔离的不同网络之间通过Router Network NameSpace进行通信。Neutron 以及NameSpace提供了比较完善的多租户环境下的虚拟网络模型以及API。
作者简介:
赵英俊,来自于城云科技,主要研究OpenStack方向