部署OVN网络拓扑
OVN-安装软件包
/etc/yum.repos.d/CentOS-OpenStack-ocata.repo
# yum list installed | grep openvswitch
openvswitch.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-devel.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-ovn-central.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-ovn-common.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-ovn-docker.x86_64 1:2.6.1-10.1.git20161206.el7
openvswitch-ovn-host.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-ovn-vtep.x86_64 1:2.9.0-3.el7 @centos-openstack-ocata
openvswitch-test.noarch 1:2.9.0-3.el7 @centos-openstack-ocata
python2-openvswitch.noarch 1:2.9.0-3.el7 @centos-openstack-ocata
### 关闭防火墙和SELINUX
# systemctl stop firewalld
# systemctl disable firewalld
### Central节点
# yum install -y openvswitch-ovn-central.x86_64 openvswitch-ovn-host.x86_64
# systemctl enable ovn-northd openvswitch ovn-controller
# systemctl start ovn-northd ovn-controller
### Node节点
# yum install -y openvswitch.x86_64 openvswitch-ovn-host.x86_64
# systemctl enable openvswitch ovn-controller
# systemctl start ovn-controller
配置OVN
export Centralip=10.33.46.182
export Nodeip=10.33.46.68
### Central节点
# ovn-nbctl set-connection ptcp:6641:$Centralip
# ovn-sbctl set-connection ptcp:6642:$Centralip
# ovs-vsctl set open . external-ids:ovn-remote=tcp:$Centralip:6642
# ovs-vsctl set open . external-ids:ovn-encap-type=geneve
# ovs-vsctl set open . external-ids:ovn-encap-ip=$Centralip
### Node节点
# ovs-vsctl set open . external-ids:ovn-remote=tcp:$Centralip:6642
# ovs-vsctl set open . external-ids:ovn-encap-type=geneve
# ovs-vsctl set open . external-ids:ovn-encap-ip=$Nodeip
system-id是ovn-sbctl中的Chassis的ID
OVN-L2网络
定义逻辑网络:创建一个逻辑交换机,然后添加两个交换机端口,并为端口设置物理地址
# $FQDN|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/‘
### Central节点
# ovn-nbctl ls-add ls1
# ovn-nbctl lsp-add ls1 ls1-vm1
# ovn-nbctl lsp-set-addresses ls1-vm1 $vm1mac
# ovn-nbctl lsp-set-port-security ls1-vm1 $vm1mac
# ovn-nbctl lsp-add ls1 ls1-vm2
# ovn-nbctl lsp-set-addresses ls1-vm2 $vm2mac
# ovn-nbctl lsp-set-port-security ls1-vm2 $vm2mac
伪造虚拟机:创建网络命名空间,并在br-int上添加端口,然后将端口添加到命名空间,最后通过设置端口的MAC地址和网卡名完成和交换机端口的映射
### Central节点
# ip netns add vm1
# ovs-vsctl add-port br-int vm1 -- set interface vm1 type=internal
# ip link set vm1 netns vm1
# ip netns exec vm1 ip link set vm1 address $vm1mac
# ip netns exec vm1 ip addr add $vm1ip/24 dev vm1
# ip netns exec vm1 ip link set vm1 up
# ovs-vsctl set Interface vm1 external_ids:iface-id=ls1-vm1
# ip netns exec vm1 ip addr show
### Node节点
# ip netns add vm2
# ovs-vsctl add-port br-int vm2 -- set interface vm2 type=internal
# ip link set vm2 netns vm2
# ip netns exec vm2 ip link set vm2 address $vm2mac
# ip netns exec vm2 ip addr add $vm2ip/24 dev vm2
# ip netns exec vm2 ip link set vm2 up
# ovs-vsctl set Interface vm2 external_ids:iface-id=ls1-vm2
# ip netns exec vm2 ip addr show
vm互ping,可ping通
OVN- L3网络
添加L3网关
### 创建逻辑路由
# ovn-nbctl lr-add edge1
### 创建逻辑交换机用于连接edge1和tenant1
# ovn-nbctl ls-add transit
### 连接edge1到逻辑交换机上
# ovn-nbctl lrp-add edge1 edge1-transit 02:d4:1d:8c:d9:ae 192.168.0.1/24
# ovn-nbctl lsp-add transit transit-edge1
# ovn-nbctl lsp-set-type transit-edge1 router
# ovn-nbctl lsp-set-addresses transit-edge1 02:d4:1d:8c:d9:ae
# ovn-nbctl lsp-set-options transit-edge1 router-port=edge1-transit
### 连接tenant1到逻辑交换机上
# ovn-nbctl lrp-add tenant1 tenant1-transit 02:d4:1d:8c:d9:af 192.168.0.2/24
# ovn-nbctl lsp-add transit transit-tenant1
# ovn-nbctl lsp-set-type transit-tenant1 router
# ovn-nbctl lsp-set-addresses transit-tenant1 02:d4:1d:8c:d9:af
# ovn-nbctl lsp-set-options transit-tenant1 router-port=tenant1-transit
### 添加静态路由
ovn-nbctl lr-route-add edge1 "20.0.0.0/24" 192.168.0.2
ovn-nbctl lr-route-add edge1 "10.0.0.0/24" 192.168.0.2
ovn-nbctl lr-route-add tenant1 "0.0.0.0/0" 192.168.0.1
ovn-nbctl lr-route-list edge1
ovn-nbctl lr-route-list tenant1
### 测试连通性
ip netns exec vm21 ping -c 2 192.168.0.1
网关与外网连接
### Central节点
### 创建外网逻辑交换机,并配置网关到叫交换机的连接
ovn-nbctl ls-add outside
ovn-nbctl lrp-add edge1 edge1-outside 02:d4:1d:8c:d9:be 192.168.233.177/24
ovn-nbctl lsp-add outside outside-edge1
ovn-nbctl lsp-set-type outside-edge1 router
ovn-nbctl lsp-set-addresses outside-edge1 02:d4:1d:8c:d9:be
ovn-nbctl lsp-set-options outside-edge1 router-port=edge1-outside
### 为外网网卡ens4创建网桥
ovs-vsctl add-br br-ex
### 为外网网卡ens4创建网桥到网络的映射
ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=dataNet:br-ex
### 在逻辑交换机outside上添加本地网络端口,并且本地网络的名字为dataNet
ovn-nbctl lsp-add outside outside-localnet
ovn-nbctl lsp-set-addresses outside-localnet unknown
ovn-nbctl lsp-set-type outside-localnet localnet
ovn-nbctl lsp-set-options outside-localnet network_name=dataNet
### 关联外网网卡到网桥上
# ovs-vsctl add-port br-ex eth1
### 测试连通性(需要注意vm2的ip地址是不是没了,dhclient好像有些问题)
ip netns exec vm22 ping -c 2 192.168.233.177
### 设置网桥地址
ip addr add 192.168.233.7/24 dev br-ex
ip link set br-ex up
### 重置下路由
# ip route
# ip route del default via 192.168.233.1
# ip route del 192.168.233.0/24 dev eth1
设置SNAT
### Central节点
### 设置网关chassis
ovn-nbctl lrp-set-gateway-chassis edge1-outside 35a10447-0513-4f8f-a340-33220258b9d9 #为ovn-snctl show对应的Chassis ID
### 配置SNAT规则
ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=20.0.0.0/24 external_ip=192.168.233.177 -- add logical_router edge1 nat @nat
ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=10.0.0.0/24 external_ip=192.168.233.177 -- add logical_router edge1 nat @nat
ovs-ofctl dump-flows br-int table=42
nat表,但是抓包发现并未生效。
02:d4:1d:8c:d9:be > c2:af:5a:9e:73:47, ethertype IPv4 (0x0800), length 98: 20.0.0.20 > 192.168.233.7: ICMP echo request, id 24614, seq 508, length 64
### 测试连通性
ip netns exec vm22 ping -c 2 192.168.233.7
OVN理论部分
OVN的架构和分析
OVN/CMS Plugin 是Neutron的一个插件,作为OVN 和 CMS 之间的接口 。它将CMS中的数据(存储在Neutron DB)翻译成一种“中间格式”。这种中间格式就是逻辑网络配置数据,这样CMS中的网络配置数据就能够被OVN的Northbound DB 所理解。
Northbound DB 里面的几乎所有的内容都是由 CMS 产生的,里面存的就是上面OVN/CMS Plugin翻译之后的逻辑网络的相关数据。比如 logical switch,logical router,logical port和ACL。OVN-northd 类似于一个集中的控制器,监听Northbound DB 数据库的内容变化,它把 Northbound DB 里面的逻辑网络的相关数据翻译成 Southbound DB 可理解的格式(logical datapath flows),并传递给 Southbound DB 进行存储,进而被所有的chassis 读取和应用
Southbound DB 处在 OVN 架构的核心,它是 OVN 中最重要的部分,它跟 OVN 的其他组件都有交互。 里面存的数据和 Northbound DB 语义完全不一样,主要包含 3 类数据:
一、物理网络数据,比如 hypervisor的 IP 地址,hypervisor的 tunnel 封装格式;
二、逻辑网络数据,比如报文如何在逻辑网络中转发;是OVN-northd 从Northbound DB 翻译过来的
三、物理网络和逻辑网络的绑定关系,比如逻辑端口关联到哪个 hypervisor上面。这类数据存储在binding表中,字段有uuid,chassis, logical_datapath, logical_port, mac, parent_port, tag, tunnel_key。
ovn-controller 是 OVN 里面的 agent,类似于 Neutron 里面的 ovs-agent,它也是运行在每个 hypervisor和软件网关之上。
它有下面2种功能:
(1)把物理网络的信息写到
Southbound DB 里面(这类信息就包括 Southbound DB中的第一类数据);
(2)把 Southbound DB 里面存的一些数据转化成
Openflow flow 配到本地的 OVS table 里面,来实现报文的转发。
第2个功能的具体实现机制就是:
ovn-controller连接到到本地的ovsdb-server ,监控、读取、管理OpenvSwitch的配置信息;
ovn-controller作为ovs-vswitchd 的Openflow 控制器来控制流量的转发。另外,从架构图中就可看出ovn-controller是一种分布式SDN控制器。
ovs-vswitchd 和 ovsdb-server 是 OVS 的两个进程:
- ovs-vswitchd :核心模块,实现交换功能,和Linux内核模块一起,实现基于流的交换;
- ovsdb-server :是一个数据库。其保存了整个OVS的配置信息,包括接口,流表和VLAN等;ovs-vswitchd从其查询配置信息;
OVN Northbound DB
Northbound DB 是 OVN 和 CMS 之间的接口,Northbound DB 里面的几乎所有的内容都是由 CMS 产生的,ovn-northd 监听这个数据库的内容变化,然后翻译,保存到 Southbound DB 里面。
Northbound DB 里面主要有如下几张表:
Logical_Switch:每一行代表一个逻辑交换机,逻辑交换机有两种,一种是 overlay logical switches,对应于 neutron network,每创建一个 neutron network,networking-ovn 会在这张表里增加一行;另一种是 bridged logical switch,连接物理网络和逻辑网络,被 VTEP gateway 使用。Logical_Switch 里面保存了它包含的 logical port(指向 Logical_Port table)和应用在它上面的 ACL(指向 ACL table)。
Logical_Port:每一行代表一个逻辑端口,每创建一个 neutron port,networking-ovn 会在这张表里增加一行,每行保存的信息有端口的类型,比如 patch port,localnet port,端口的 IP 和 MAC 地址,端口的状态 UP/Down。
ACL:每一行代表一个应用到逻辑交换机上的 ACL 规则,如果逻辑交换机上面的所有端口都没有配置 security group,那么这个逻辑交换机上不应用 ACL。每条 ACL 规则包含匹配的内容,方向,还有动作。
Logical_Router:每一行代表一个逻辑路由器,每创建一个 neutron router,networking-ovn 会在这张表里增加一行,每行保存了它包含的逻辑的路由器端口。
Logical_Router_Port:每一行代表一个逻辑路由器端口,每创建一个 router interface,networking-ovn 会在这张表里加一行,它主要保存了路由器端口的 IP 和 MAC。
OVN Southbound DB
Southbound DB 里面有如下几张表:
Chassis:每一行表示一个 HV 或者 VTEP 网关,由 ovn-controller/ovn-controller-vtep 填写,包含 chassis 的名字和 chassis 支持的封装的配置(指向表 Encap),如果 chassis 是 VTEP 网关,VTEP 网关上和 OVN 关联的逻辑交换机也保存在这张表里。
Encap:保存着 tunnel 的类型和 tunnel endpoint IP 地址。
Logical_Flow:每一行表示一个逻辑的流表,这张表是 ovn-northd 根据 Nourthbound DB 里面二三层拓扑信息和 ACL 信息转换而来的,ovn-controller 把这个表里面的流表转换成 OVS 流表,配到 HV 上的 OVS table。流表主要包含匹配的规则,匹配的方向,优先级,table ID 和执行的动作。
Multicast_Group:每一行代表一个组播组,组播报文和广播报文的转发由这张表决定,它保存了组播组所属的 datapath,组播组包含的端口,还有代表 logical egress port 的 tunnel_key。
Datapath_Binding:每一行代表一个 datapath 和物理网络的绑定关系,每个 logical switch 和 logical router 对应一行。它主要保存了 OVN 给 datapath 分配的代表 logical datapath identifier 的 tunnel_key。
Port_Binding:这张表主要用来确定 logical port 处在哪个 chassis 上面。每一行包含的内容主要有 logical port 的 MAC 和 IP 地址,端口类型,端口属于哪个 datapath binding,代表 logical input/output port identifier 的 tunnel_key, 以及端口处在哪个 chassis。端口所处的 chassis 由 ovn-controller/ovn-controller 设置,其余的值由 ovn-northd 设置。
表 Chassis 和表 Encap 包含的是物理网络的数据,表 Logical_Flow 和表 Multicast_Group 包含的是逻辑网络的数据,表 Datapath_Binding 和表 Port_Binding 包含的是逻辑网络和物理网络绑定关系的数据。
OVN security group 对比 Neutron security group
OVN tunnel
OVN 支持的 tunnel 类型有三种,分别是 Geneve,STT 和 VXLAN。HV 与 HV 之间的流量,只能用 Geneve 和 STT 两种,HV 和 VTEP 网关之间的流量除了用Geneve和STT外,还能用 VXLAN,这是为了兼容硬件 VTEP 网关,因为大部分硬件VTEP网关只支持 VXLAN。
虽然 VXLAN 是数据中心常用的 tunnel 技术,但是 VXLAN header 是固定的,只能传递一个 VNID(VXLAN network identifier),如果想在 tunnel 里面传递更多的信息,VXLAN 实现不了。所以 OVN 选择了 Geneve 和 STT,Geneve 的头部有个 option 字段,支持 TLV 格式,用户可以根据自己的需要进行扩展,而 STT 的头部可以传递 64-bit 的数据,比 VXLAN 的 24-bit 大很多。
OVN tunnel 封装时使用了三种数据,
Logical datapath identifier(逻辑的数据通道标识符):datapath 是 OVS 里面的概念,报文需要送到 datapath 进行处理,一个 datapath 对应一个 OVN 里面的逻辑交换机或者逻辑路由器,类似于 tunnel ID。这个标识符有 24-bit,由 ovn-northd 分配的,全局唯一,保存在 Southbound DB 里面的表 Datapath_Binding 的列 tunnel_key 里。
Logical input port identifier(逻辑的入端口标识符):进入 logical datapath 的端口标识符,15-bit 长,由 ovn-northd 分配的,在每个 datapath 里面唯一。它可用范围是 1-32767,0 预留给内部使用。保存在 Southbound DB 里面的表 Port_Binding 的列 tunnel_key 里。
Logical output port identifier(逻辑的出端口标识符):出 logical datapath 的端口标识符,16-bit 长,范围 0-32767 和 logical input port identifier 含义一样,范围 32768-65535 给组播组使用。对于每个 logical port,input port identifier 和 output port identifier 相同。
如果 tunnel 类型是 Geneve,Geneve header 里面的 VNI 字段填 logical datapath identifier,Option 字段填 logical input port identifier 和 logical output port identifier,TLV 的 class 为 0xffff,type 为 0,value 为 1-bit 0 + 15-bit logical input port identifier + 16-bit logical output port identifier。
如果 tunnel 类型是 STT,上面三个值填在 Context ID 字段,格式为 9-bit 0 + 15-bit logical input port identifier + 16-bit logical output port identifier + 24-bit logical datapath identifier。
OVS 的 tunnel 封装是由 Openflow 流表来做的,所以 ovn-controller 需要把这三个标识符写到本地 HV 的 Openflow flow table 里面,对于每个进入 br-int 的报文,都会有这三个属性,logical datapath identifier 和 logical input port identifier 在入口方向被赋值,分别存在 openflow metadata 字段和 Nicira 扩展寄存器 reg6 里面。报文经过 OVS 的 pipeline 处理后,如果需要从指定端口发出去,只需要把 Logical output port identifier 写在 Nicira 扩展寄存器 reg7 里面。
OVN tunnel 里面所携带的 logical input port identifier 和 logical output port identifier 可以提高流表的查找效率,OVS 流表可以通过这两个值来处理报文,不需要解析报文的字段。
从上一章节可以看到,OVN 里面的 tunnel 类型是由 HV 上面的 ovn-controller 来设置的,并不是由 CMS 指定的,并且 OVN 里面的 tunnel ID 又由 OVN 自己分配的,所以用 neutron 创建 network 时指定 tunnel 类型和 tunnel ID(比如 vnid)是无用的,OVN 不做处理。
OVN VTEP 网关
小结:
OVN存在的意义(目标)
- 可用于生产环境
- 简洁的设计
- 支持1000台以上的物理机环境(也支持相当数量的虚拟机/容器环境)
- 基于已有的OpenStack OVS 插件 来提升性能和稳定性
- 成为OpenStack+OVS集成场景下的首选方案
已经实现从OVS 平滑升级到 OVN
OVN 对于运行平台没有额外的要求,只要能够运行 OVS,就可以运行 OVN,可以和 Linux,Docker,DPDK 还有 Hyper-V 兼容,所以从 OVS 升级到 OVN 是非常简单快捷的。原有的网络、路由等数据不会丢失,也不需要对这些数据导入导出来进行数据迁移
另外 OVN 可以和很多 CMS(Cloud Management System)集成到一起,尤其是 OpenStack Neutron,这些 CMS 只需要添加一个 plugin 来配置 OVN 即可。
OVN对neutron的改变(以Ocata版本中的OVN和OVS 2.9版本来看OVN带来的变化)
OVN 里面数据的读写都是通过 OVSDB 协议来做的,取代了 neutron 里面的消息队列机制,neutron 变成了一个 API server 来处理用户的 REST 请求,其他的功能都交给 OVN 来做。
使得Neutron组件数量减少
OVN原生的ML2 driver替换掉 OVS ML2 driver 和 Neutron的OVS agent;
OVN原生支持L3和DHCP功能,这样就不再需要Neutron 的L3 agent、 DHCP agent 和DVR。
从 OVN 的架构可以看出,OVN 里面数据的读写都是通过 OVSDB来做的,取代了 Neutron 的消息队列机制,所以有了 OVN 之后,Neutron 里面所有的 agent 都不需要了,Neutron 变成了一个 API server 来处理用户的 REST 请求,其他的功能都交给 OVN 来做,只需要在 Neutron 里面加一个 plugin 来调用配置 OVN。
Neutron 里面的子项目 networking-ovn 就是实现 OVN 的 plugin。Plugin 使用 OVSDB 协议来把用户的配置写在 Northbound DB 里,ovn-northd 监听到 Northbound DB 配置发生改变,然后把配置翻译到 Southbound DB 里面。 ovn-controller 监控到 Southbound DB 数据的发生变化之后,进而更新本地的流表。
OVN 里面报文的处理都是通过 OVS OpenFlow 流表来实现的,而在 Neutron 里面二层报文处理是通过 OVS OpenFlow 流表来实现,三层报文处理是通过 Linux TCP/IP 协议栈来实现。
OVN L3 对比 Neutron L3
Neutron 的三层功能主要有路由,SNAT 和 Floating IP(也叫 DNAT),它是通 Linux kernel 的namespace 来实现的,每个路由器对应一个 namespace,利用 Linux TCP/IP 协议栈来做路由转发。
OVN 支持原生的三层功能,不需要借助 Linux TCP/IP stack,用OpenFlow 流表来实现路由查找,ARP 查找,TTL 和 MAC 地址的更改。OVN 的路由也是分布式的,路由器在每个计算节点上都有实例,有了 OVN 之后,不需要 Neutron L3 agent 了 和DVR了。
OVN和其它通用SDN控制器(比如OpenDayLight)的主要区别
OVN专注于实现云计算管理平台场景下的SDN控制器
OVN专注于实现二层和三层网络功能。除了在传输层实现了基于L4的ACL 外,基本上不在L4 ~ L7层实现某些功能。
OVN的实现了哪些功能?拥有哪些特性?
Logical switches:逻辑交换机,用来做二层转发。
L2/L3/L4 ACLs:二到四层的 ACL,可以根据报文的 MAC 地址,IP 地址,端口号来做访问控制。
Logical routers:逻辑路由器,分布式的,用来做三层转发。
Multiple tunnel overlays:支持多种隧道封装技术,有
Geneve,STT 和 VXLAN。
TOR switch or software logical switch gateways:支持使用硬件 TOR switch 或者软件逻辑 switch 当作网关来连接物理网络和虚拟网络。