我们之前说的,是用原生的VLAN和Linux网桥去管理云平台,会在灵活性和隔离性都显得不足,整个网络都缺少统一的管理
就好比大家在一起的小区,在高峰的时候,需要物业的管理人员来帮忙管理出入门人员,可以让大家直接横穿小区,避免过度拥挤,等待高峰过去,在将其修改会去
这就好比传统的网络设备和普通的Linux网桥的模式,配置整个平台的网络通路,需要我们登陆到这个机器上配置这个,登陆到另一个机器配置那个,才能成功
如果有一个中心智能控制系统,可以在其中配置每个单元的入口的方向,调节大小,就好了
这就是软件定义SDN,主要有以下三个特点
1.控制和转发分离,转发平面就好比是一个个虚拟的或者物理的网络设备,就好比小区里面的一条路,控制平面就是统一的控制中心,就好比小区物业的监控室,是一起的,物业管理员要从监控室出来,去门口管理,现在统一在监控室
2.控制平面和转发平面的开放接口,控制器向上提供接口,被应用层调用,向下调用接口,控制网络设备,前面的接口被称为北向接口,后面的被称为南向接口
3.逻辑上的集中控制,逻辑上的集中控制平面可以控制多个转发面设备,可以说是整个物理网络,从而获取全局的网络状态视图,并根据视图实现网络的优化控制
SDN的实现方式
SDN有很多种实现方式,我们看一种开源的实现方式
OpenFlow是SDN控制器和网络设备之间互通的南北接口协议,OpenSwitch用于创建软件的虚拟交换机,OpenSwittch支持OpenFlow,对于一些硬件交换机,同样也支持OpenFlow协议,但无论是物理机还是虚拟机,都是可以被统一的SDN控制器管理的,从而实现了物理机和虚拟机的网络连通
SDN控制器如何通过OpenFlow协议控制的网络的呢?
在OpenSwitch中,存在一个流表规则,任何通过这个交换机的包,都会经过这些规则处理,然后接收,转发,放弃
这里面有多个表格,每个表格里面有多个行,每个行都是一条规则,每个规则都有优先级,看高优先级规则符合,不行再去看低优先级的规则
只要符合了规则,如果满足了匹配条件,这些条件包含了从哪个端口进来,网络头里面有什么,满足了条件的网络包,就可以对这个包进行修改,可以跳到任何一个表格,转发到某个网口出去,或者直接丢弃
上面会说明了我们各个层能够做什么事情
对于物理层
可以匹配从网卡哪个口进来
可以修改从哪个口出去
对于MAC层
匹配规则包含,源MAC地址是多少,目标MAC是多少,所属的VLAN是多少
执行动作是,修改源MAC,修改目标MAC,修改VLAN,删除VLAN,MAC地址学习
对于网络层
匹配规则包含,源IP是多少,目标IP是多少
执行动作包含,修改源IP,修改目标IP地址
对于传输层,
匹配规则包含,源端口是多少,目标端口是多少
执行动作包含,修改源端口,修改目标端口
总结下来,如果一个网络包匹配了规则,那么想怎么改就怎么改
OpenvSwitch具有本地的命令行可以直接配置,可以实验一些功能,可以通过OpenvSwitch的命令创建一个虚拟交换机,然后将多个虚拟端口port添加到这个虚拟机交换机上
ovs-vsctl add-br ubuntu_br
那么如何利用OpenvSwitch来模拟实现出VLAN的功能
在OpenvSwitch中端口分为了两种
1.access port:
这个端口配置了tag,从这个端口进来的包会打上这个tag
如果网络包本身带有的VLAN ID等于tag,则从这个port发出
从access port发出的包不带VLAN ID,也就是会把VLAN ID去掉
2.trunk port
这个配置trunks,不配置tag
如果trunks为空,那么所有的VLAN都可以trunk,对于所有的vlan的包,本身带什么VLAN ID,就带着什么VLAN ID,如果没有设置VLAN ID,认为是VLAN 0,也可以通过
如果trunks不为空,则只允许带着trunks中配置的VLAN ID的包可以通过
假设我们有一个如下的环境
ovs-vsctl add-port ubuntu_br first_br
ovs-vsctl add-port ubuntu_br second_br ovs-vsctl add-port ubuntu_br third_br ovs-vsctl set Port vnet0 tag=101 ovs-vsctl set Port vnet1 tag=102 ovs-vsctl set Port vnet2 tag=103 ovs-vsctl set Port first_br tag=103 ovs-vsctl clear Port second_br tag ovs-vsctl set Port third_br trunks=101,102 ovs-vsctl set bridge ubuntu_br flood-vlans=101,102,103 |
环境具体图如下:
创建好了环境之后,我们来做下实验
1.从192.168.100.102来ping 192.168.100.103,并利用tcpdump进行抓包
first_if收到包,从first_br中,发现从tag103发过来的,可以过去,并且去掉了VLAN ID,
于此同时 second_br是truck port,所以可以直接放行,而third_br则被过滤掉了
2.192.168.100.100来ping 192.168.100.105,而second_if和third_if可以收到包,但是ping不通,因为third_if不属于任何的vlan,second_if能够收到包,包里面说明是 VLAN ID =101,third_if也能够收到包,包里面是vlan ID=101
3.从192.168.100.101来ping 192.168.100.104,则second_if和third_if可以收到包,而且都会携带者vlan id=102
然后尝试,用OpenvSwitch模拟网卡绑定,连接交换机
OpenSwitch里面,有一个bond_mode,可以设置为以下的三个值
active-backup,一个连接是active,其他的是backup,当active失效的时候,backup顶上,
balance-slb,流量按照原Mac和output vlan进行负载均衡
balance-tcp,必须在支持LACP协议下可以使用,可以根据L2,L3,L4来负载均衡
我们使用下面的命令,建立bond连接
ovs-vsctl add-bond br0 bond0 first_br second_br
ovs-vsctl add-bond br1 bond1 first_if second_if ovs-vsctl set Port bond0 lacp=active ovs-vsctl set Port bond1 lacp=active |
bond_mode的默认是active-backup模式,一开始active是first_br和first_if
这时候我们从192.168.100.100 ping 192.168.100.102,以及从192.168.100.101到192.168.100.103的时候,可以看到,所有的包都是从first_if通过
如果将first_if设置为down的状态,包的走向会改变,发现second_if开始有了流量
但是对于上面的192.168.100.100和192.168.100.101来说,好像没有感知到什么改变?
如果,我们通过下面的命令,将bond mode设置为balance-slb,我们同时进行,
192.168.100.100 去ping 192.168.100.102
192.168.100.101 去ping 192.168.100.103
会发现tcpdump的包已经被分流了
那么OpenvSwitch是怎么做到的呢?如下是OpenvSwitch的架构图
OpenvSwitch中有两个重要的进城,对应着有两个重要的命令行工具
1.第一个进城是OVSDB进程,ovs-vsctl命令行会和这个进程通信,创建虚拟的交换机,创建端口,将端口添加到虚拟交换机上,OVSDB会将这些拓补信息保存在一个本地的问题件汇总
2.第二个进程是vswitchd进程,ovs-ofctl命令行会和这个进程通信,去下发流表规则,规定如何去对网络包处理,vswitchd会将流表放在用户态Flow Table中
内核态,OpenvSwith中有内核模块 OpenvSwtich.ko,对应着图内的Datapath部分,在网卡上注册一个函数,每当有包到达网卡的时候,函数都会被调用
内核的这个函数中,会拿到网络包,将各个层次的重要信息拿出来
物理层,拿到网口的ID
Mac层,拿到了源和目的Mac地址
在Ip层,源和目的ip地址
在传输层,源和目的端口号
在内核中,有一个内核态Flow Table,接下来在内核模块在这个内核的流表中匹配规则,匹配上了,就需要执行操作,修改包,或者转发,如果没有匹配上,先进入用户态,在用户态和内核台之间,利用netlink进行通信
内核通过upcall,告知用户态进程vswitchd在用户态Flow Table的匹配规则,这里面保留了全部的内核,这是为了内核中的规则可以快速的查询,并且,内核中的规则过一阵就会过期
当用户态匹配到了流表规则,现在用户态执行操作,并且下发规则到内核中,方便回来能查找到这个规则
这里可以调用openflow协议,去控制SDN的工具,是OpenDaylight
下面我们看到的图就是OpenDaylight的拓补图
我们可以在OpenDaylight中,将两台交换机中配置通路,也可以配置不通,可以配置一个虚拟的IP地址VIP,在不同的机器之间实现负载均衡等,所有的策略都可以灵活配置
如何在云计算中使用OpenvSwtich呢?
在OpenvSwitch中本身就支持VLAN,所有的虚拟机可以放在一个网桥br0上,不同的用户配置不同的tag,来实现隔离,例如上面的图,用户A的虚拟机都在br0上,用户B的虚拟机都在br1上,有了OpenvSwitch,可以都放在br0上,只是设置了不同的tag,另外,还可以创建一个虚拟交换机br1,将物理网络和虚拟网络进行隔离,物理网络有物理网络的vlan规划,虚拟网络有自己的规划,虚拟机的vlan都是从1开始的,一台机器上的虚拟机不会超过4096个,所以vlan在一台物理机上从1开始,肯定够用了
而假如一个用户A被分配了vlan id 101,而在一个物理机里面,用户A分配的tag是1,B分配的tag是2,在下面的物理机里面,用户A被分配的tag是7,用户B分配的tag是6
如果物理机之间的通信还是通过vlan的话,需要将虚拟机vlan和物理机的vlan对应起来,为了灵活性,不一定一直,但是可以利用OpenSwitch进行转发映射,匹配dl_vlan,并执行mod_vlan_vid来修改进进出出的物理机的网络包
尽管租户多了,物理环境的VLAN还是不够用,但是有了OpenvSwitch的映射,将物理和虚拟解耦,从而让物理环境使用别的技术,不影响虚拟机环境
本章小结:
1.用SDN控制整个云中的网络,就好比小区保安从整个总控室管理整个物业一样的,将控制面和数据面进行了分离
2.开源的虚拟交换机实现了OpenvSwitch,可以对自己的包进行任意的修改,使得云对网络的控制十分灵活
3.将OpenSwitch引入云之后,可以让配置变得简单而且灵活,并且解耦物理网络和虚拟网络
课后思考:
1.提到了VIP可以通过流表在不同的机器之间实现复杂均衡
2.虽然OpenvSwitch可以解耦物理网络和虚拟网络,但是物理网络里面使用VLAN,数目还是不够,怎么办?
SDN最大的意义在于让网络的功能可编程
在VIP之中,可以通过ovs-ofctl下发流标规则,创建一个group,并把端口加入group中,所有发现某个地址的包在两个端口之间进行负载均衡
sudo ovs-ofctl -O openflow11 add-group br-lb “group_id=100 type=select selection_method=dp_hash bucket=output:1 bucket=output:2”
sudo ovs-ofctl -O openflow11 add-flow br-lb “table=0,ip,nw_dst=192.168.2.0/24,actions=group:100” |
SDN控制器到底为何为
大规模环境中的SDN控制器是一个独立实例还是一个独立集群来实现的呢?主流控制器又是哪些
流表在每一台宿主机保存吗,大小的限制如何控制,能否独立集中存放流表
SDN控制器是一个独立的集群,因为是在网络的控制面的,所以需要一定的高可用性
主流的开源控制器有OpenContrail,OpenDaylight,每个网络硬件厂商有着自己的控制器,和自己的私有协议,进行更加细粒度的控制
流表自然是保存在宿主机上的,大小取决于内存,而且集中存储会导致获取的速度很慢