摘要:如果你能理解OpenStack的网络,那么对于其他云平台的网络,应该也可以通过分析后理解掌握了。
本文分享自华为云社区《《跟唐老师学习云网络》 - OpenStack网络实现》,作者: tsjsdbd 。
整体设计
首先,OpenStack是用来管理大量的VM的“上帝”。他的目的是要像掌控物理世界一样,去管理大量的VM。即:可以给VM分组,同一个组里面的VM,在同一个网络内,可以互通通信。不同组的VM,则相当于在不同的网络中,互相不能通信。
至于为什么要分组,
1、是跟物理服务器一样,那么多机器,按照不同机房的服务器,连到不同的网络。
2、是我可以把不同组的VM,卖给不同的“用户”,这样,组1的VM属于张三,组2的VM属于李四,这样他们俩互相隔离,互不感知。于是我就可以化身成为云厂商,对外提供云平台服务了。
- 当然你作为云厂商,也肯定要允许一个用户,可以拥有2个网络嘛。万一该客户人傻钱多,就是买了一堆VM,分着玩呢,是吧。
逻辑视图
现实中,2个机房的服务器,网络要想连通,是要靠路由器来帮忙的。在虚拟世界中也是类似的。
所以,逻辑上,VM世界的网络就是长这个样。
张三的VM的网络,要想和李四VM的网络 互通,或者张三自己的2个独立网络互通。就得通过一个叫做 Router 的“虚拟路由器”来完成。
物理视图
上面的逻辑视图,在物理上,则是这个样子的:
至于如何在一根网线上面,同时跑多个虚拟网络的报文。这个就是在一根网线上的报文,有不同门派的意思。具体的可以回去看VLAN/VxLAN章节。
另外,这里你可以看到,虚拟网络里面的一个“Router”,其实不是什么具体的虚拟路由器设备,而仅仅是一个“网络namespace+转发规则”就达成了,下面会细讲。
简单模型
假设现在你来设计OpenStack的网络实现。
那从我们之前学到的OVS章节,可以知道,为了达成上面提到的OpenStack的网络虚拟化目的。最简单的实现是给每个物理服务器上增加一个OVS虚拟交换机;然后每个VM都连到OVS端口上,每个端口则按照分组,打上对应的VLAN标签。就可以达成基本要求。
但是,这个初始1.0版本的实现,有个不牛批的地方,就是没法给VM设置安全组。你作为想成为云平台伟大目标,平台怎么能没有安全组这个能力呢(虽然,在VM里面,可以设置firewell或者iptables规则,但是VM里面,那是已经卖给用户的了,你跑人家房间里面,去设置规则并不合适,可能和用户自己的业务规则冲突)。
所以第2个版本,改进之。我们要在VM的外面设置安全组:
于是,我们在每个VM大门口,增加一个Bridge网桥,任何VM的流量,都会经过这个Bridge。这样,通过在Bridge上面,增加iptables规则,就可以达到给VM设置安全组的目的了。(注意,这个时候,VM的报文还没有到OVS,所以报文还是没有打VLAN标签的原始报文,所以iptables规则也好实现)。
这就是咱们的OpenStack网络2.0版本。
但是,在实践中,你发现这个独苗OVS,要设置端口转发规则有2部分:
- 上半部分。即:给VM设置Tag标签。
每增加一台VM时,就给这个端口打标签,插拔虚拟网线等配置动作。这一部分逻辑比较固定,不怎么变化。
- 下半部分。即:通过物理网线,怎么给报文打“门派”标记。
这一部分变化很大,有时候物理网络,咱得走GRE,有时候要走VLAN,有时候又得VxLAN。还有时候,得走专用的网络设备。平台得根据部署的机房网线,定制不同的规则。
这样这2类OVS的规则不好管(都放openflow的转发表里面),本着程序员的“分库分表”(或者咱们写代码时的,“抽取函数”的逻辑)的思路,咱们把1个独苗OVS,分成多个VOS。分别做不同的事情。
于是,咱们到了3.0版本,这个版本就比较通用了。基本可以和实际OpenStack的网络比较接近了。不过在网络节点部分,还得再增强一下。就是咱们的VM,除了互访之外(流量还在几台物理服务器之间转悠),还得访问外网呀(流量跑机房外部去)。 所以,还得继续增强一下VM访问外部网络的能力:
这么一来,就到了差不多4.0版本了。后面咱们介绍的OpenStack网络,就是照着这个版本来的。在OpenStack网络里面,对各种ovs,bridge,接口的命名,有一套自己的规范。不像上面这么随意的取名。
控制节点
有了上面这些给VM设置虚拟网络用的模型,那么要搞成自动化(即:每创建一个VM,给它设置好配套的虚拟网线连接)。 你得写个主控程序,用来控制这些计算节点上面的行为吧。如下:
所以,按照OpenStack官方的架构,它需要有3种节点:管节点,计算节点,网络节点。
每个节点上面,部署了一堆agent,用来接收老大的控制命令。老大就是Master管理节点了。
注:之前章节也提过,分布式系统,可靠的控制都需要有个“代理商”,比如RabbitMQ(OpenStack选了这个),ETCD(Kubernetes选了这个),ZooKeeper(Hadoop选了这个)这种。
(1)首先是最上面红色的线,就是“主控逻辑”用来控制Agent干活的,简称管理面网络。
(2)然后是中间绿色的线,那就是VM们在这根网线上面,发送大量的“自己门派”的报文,即VM间互相通信,都要走的网络,数据量很大。简称数据面。
为了确保管理面和数据面隔离,互不影响(即:VM疯狂发包,别把管理命令的报文给冲没了)。每台物理服务器上面,得有2块网卡,一块用来走管理网线,一块用来走数据网线。
(3)接着就是左下角的墨绿色线,这个是VM们访问机房外部网络用的。只需要网络节点,有一个额外的网卡就行了。
(4)最后是紫色的线。你的主控逻辑,要不要包装成API接口,对外部暴露访问通道? 要的话,可以加上。不要的话,那就每次都登陆到主控节点里面,手动敲命令控制也行。
计算节点
这里咱们打开一个OpenStack的计算节点,看看它的网络构造,遥记当年(2013年,OpenStack版本Havana)我学OS网络的时候,看到一个资料,对我帮助很大,这里直接贴上来:
照着前文的“设计思路”,你应该可以看懂上图的网络逻辑了吧。命名上,一般内部的ovs叫 br-int。隧道的叫 br-tun。如果你有环境的话,在节点上面查询,使用各种网络命令(ip,ovs-vsctl,brctl等),你可以证实一下。
网络节点
同样,网络节点,网络组成如下:
其中,上部的红色虚线,表示一个 网络namespace。dnsmasq是一个DHCP服务器(自动分配IP的程序,用来给VM分配IP地址)。
这个节点也使用各种网络命令来查询查看确认。
ps,由于该网络节点上有很多网络namespace,所以记得使用 ip netns exec命令来进入到对应的ns查询这个虚拟空间里面的详情。
floating IP(EIP)
VM除了有自己的虚拟网络内的IP,还可以拥有一个floating IP(注:对应云厂商,一般把这个叫做 EIP)。咱们来看下这个“浮动IP”是个什么实现逻辑。
逻辑概念
首先,浮动IP,是物理网络世界的,即OpenStack的外部网络的。它是一个真实存在的IP地址(不跟VM一样,那是你虚拟出来的IP)。
如上图,对floating IP,我总结的一句话概况就是:VM对外的名号。
当你从外部网络,访问这个“浮动IP”,就等于访问这一台VM。至于为什么要叫“浮动”这个词,是因为这个名号,会漂移。
举个例子:“护国大法师”这个名号很响亮,当你一报你要找“护国大法师”这个人时,大家都知道你要找具体的谁。但是这个“护国大法师”名号,是可以从一个人身上转移到另一个人身上的。
直接对应云厂商的EIP,是不是就好理解了。
具体实现
我们关注点,直接聚焦到网络节点的一个namespace里面。(本例的浮动IP是 192.168.101.3)。如下图:
在网络节点,查询ns。
root@netnode:/# ip netns
qdhcp-a7e512cf-1ca0-4ec7-be75-46a8998cf9ca
qrouter-4cdb0354-7732-4d8f-a3d0-9fbc4b93a62d