An introduction to OVN architecture

| 分类 Network  | 标签 OVN  SDN  OVS 

OVN的特性

OVN是OVS社区在2015年1月份才宣布的一个子项目,但是到目前为止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 当作网关来连接物理网络和虚拟网络。

OVN架构

                                         CMS
                                          |
                                          |
                              +-----------|-----------+
                              |           |           |
                              |     OVN/CMS Plugin    |
                              |           |           |
                              |           |           |
                              |   OVN Northbound DB   |
                              |           |           |
                              |           |           |
                              |       ovn-northd      |
                              |           |           |
                              +-----------|-----------+
                                          |
                                          |
                                +-------------------+
                                | OVN Southbound DB |
                                +-------------------+
                                          |
                                          |
                       +------------------+------------------+
                       |                  |                  |
         HV 1          |                  |    HV n          |
       +---------------|---------------+  .  +---------------|---------------+
       |               |               |  .  |               |               |
       |        ovn-controller         |  .  |        ovn-controller         |
       |         |          |          |  .  |         |          |          |
       |         |          |          |     |         |          |          |
       |  ovs-vswitchd   ovsdb-server  |     |  ovs-vswitchd   ovsdb-server  |
       |                               |     |                               |
       +-------------------------------+     +-------------------------------+

上图是OVN的整体架构,最上面 Openstack/CMS plugin 是 CMS(Cloud Management System) 和 OVN 的接口,它把 CMS 的配置转化成 OVN 的格式写到 Nnorthbound DB 里面。

详细参考ovn-architecture - Open Virtual Network architecture

  • Northbound DB

Northbound DB里面存的都是一些逻辑的数据,大部分和物理网络没有关系,比如logical switchlogical routerACLlogical port,和传统网络设备概念一致。

Northbound DB进程:

root     29981     1  0 Dec27 ?        00:00:00 ovsdb-server: monitoring pid 29982 (healthy)
root     29982 29981  2 Dec27 ?        00:35:53 ovsdb-server --detach --monitor -vconsole:off --log-file=/var/log/openvswitch/ovsdb-server-nb.log --remote=punix:/var/run/openvswitch/ovnnb_db.sock --pidfile=/var/run/openvswitch/ovnnb_db.pid --remote=db:OVN_Northbound,NB_Global,connections --unixctl=ovnnb_db.ctl --private-key=db:OVN_Northbound,SSL,private_key --certificate=db:OVN_Northbound,SSL,certificate --ca-cert=db:OVN_Northbound,SSL,ca_cert --ssl-protocols=db:OVN_Northbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Northbound,SSL,ssl_ciphers /etc/openvswitch/ovnnb_db.db

查看ovn-northd的逻辑数据(logical switch,logical port, logical router):

# ovn-nbctl show
switch 707dcb98-baa0-4ac5-8955-1ce4de2f780f (kube-master)
    port stor-kube-master
        type: router
        addresses: ["00:00:00:BF:CC:B1"]
        router-port: rtos-kube-master
    port k8s-kube-master
        addresses: ["66:ce:60:08:9e:cd 192.168.1.2"]
...
  • OVN-northd

OVN-northd类似于一个集中的控制器,它把 Northbound DB 里面的数据翻译一下,写到 Southbound DB 里面。

# start ovn northd
/usr/share/openvswitch/scripts/ovn-ctl start_northd

ovn-northd进程:

root     29996     1  0 Dec27 ?        00:00:00 ovn-northd: monitoring pid 29997 (healthy)
root     29997 29996 25 Dec27 ?        06:52:54 ovn-northd -vconsole:emer -vsyslog:err -vfile:info --ovnnb-db=unix:/var/run/openvswitch/ovnnb_db.sock --ovnsb-db=unix:/var/run/openvswitch/ovnsb_db.sock --no-chdir --log-file=/var/log/openvswitch/ovn-northd.log --pidfile=/var/run/openvswitch/ovn-northd.pid --detach --monitor
  • Southbound DB

Southbound DB进程:

root     32441     1  0 Dec28 ?        00:00:00 ovsdb-server: monitoring pid 32442 (healthy)
root     32442 32441  0 Dec28 ?        00:01:45 ovsdb-server --detach --monitor -vconsole:off --log-file=/var/log/openvswitch/ovsdb-server-sb.log --remote=punix:/var/run/openvswitch/ovnsb_db.sock --pidfile=/var/run/openvswitch/ovnsb_db.pid --remote=db:OVN_Southbound,SB_Global,connections --unixctl=ovnsb_db.ctl --private-key=db:OVN_Southbound,SSL,private_key --certificate=db:OVN_Southbound,SSL,certificate --ca-cert=db:OVN_Southbound,SSL,ca_cert --ssl-protocols=db:OVN_Southbound,SSL,ssl_protocols --ssl-ciphers=db:OVN_Southbound,SSL,ssl_ciphers /etc/openvswitch/ovnsb_db.db

Southbound DB 里面存的数据和 Northbound DB 语义完全不一样,主要包含 3 类数据,一是物理网络数据,比如 HV(hypervisor)的 IP 地址,HV 的 tunnel 封装格式;二是逻辑网络数据,比如报文如何在逻辑网络里面转发;三是物理网络和逻辑网络的绑定关系,比如逻辑端口关联到哪个 HV 上面。

# ovn-sbctl show
Chassis "7f99371a-d51c-478c-8de2-facd70e2f739"
    hostname: "kube-node2"
    Encap vxlan
        ip: "172.17.42.32"
        options: {csum="true"}
Chassis "069367d8-8e07-4b81-b057-38cf6b21b2b7"
    hostname: "kube-node3"
    Encap vxlan
        ip: "172.17.42.33"
        options: {csum="true"}
  • OVN-controller

ovn-controller 是 OVN 里面的 agent,类似于 neutron 里面的 ovs-agent,它也是运行在每个 HV 上面。北向,ovn-controller 会把物理网络的信息写到 Southbound DB 里面;南向,它会把 Southbound DB 里面存的一些数据转化成 Openflow flow 配到本地的 OVS table 里面,来实现报文的转发。

# start ovs
/usr/share/openvswitch/scripts/ovs-ctl start --system-id=random
# start ovn-controller
/usr/share/openvswitch/scripts/ovn-ctl start_controller

ovn-controller进程:

root     13423     1  0 Dec26 ?        00:00:00 ovn-controller: monitoring pid 13424 (healthy)
root     13424 13423 82 Dec26 ?        1-15:53:23 ovn-controller unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfile:info --no-chdir --log-file=/var/log/openvswitch/ovn-controller.log --pidfile=/var/run/openvswitch/ovn-controller.pid --detach --monitor

ovs-vswitchd 和 ovsdb-server 是 OVS 的两个进程。

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)。

ovn-nbctl list Logical_Switch可以查看Logical_Switch表中的数据:

# ovn-nbctl --db tcp:172.17.42.30:6641 list Logical_Switch
_uuid               : 707dcb98-baa0-4ac5-8955-1ce4de2f780f
acls                : []
dns_records         : []
external_ids        : {gateway_ip="192.168.1.1/24"}
load_balancer       : [4522d0fa-9d46-4165-9524-51d20a35ea0a, 5842a5a9-6c8e-4a87-be3c-c8a0bc271626]
name                : kube-master
other_config        : {subnet="192.168.1.0/24"}
ports               : [44222421-c811-4f38-8ea6-5504a35df703, ee5a5e97-c41d-4656-bd2a-8bc8ad180188]
qos_rules           : []
...
  • Logical_Switch_Port

每一行代表一个逻辑端口,每创建一个 neutron portnetworking-ovn 会在这张表里增加一行,每行保存的信息有端口的类型,比如 patch portlocalnet port,端口的 IP 和 MAC 地址,端口的状态 UP/Down。

# ovn-nbctl --db tcp:172.17.42.30:6641 list Logical_Switch_Port
_uuid               : 44222421-c811-4f38-8ea6-5504a35df703
addresses           : ["00:00:00:BF:CC:B1"]
dhcpv4_options      : []
dhcpv6_options      : []
dynamic_addresses   : []
enabled             : []
external_ids        : {}
name                : stor-kube-master
options             : {router-port=rtos-kube-master}
parent_name         : []
port_security       : []
tag                 : []
tag_request         : []
type                : router
up                  : false
...
  • ACL

每一行代表一个应用到逻辑交换机上的 ACL 规则,如果逻辑交换机上面的所有端口都没有配置 security group,那么这个逻辑交换机上不应用 ACL。每条 ACL 规则包含匹配的内容,方向,还有动作。

  • Logical_Router

每一行代表一个逻辑路由器,每创建一个 neutron router,networking-ovn 会在这张表里增加一行,每行保存了它包含的逻辑的路由器端口。

# ovn-nbctl --db tcp:172.17.42.30:6641 list Logical_Router
_uuid               : e12293ba-e61e-40bf-babc-8580d1121641
enabled             : []
external_ids        : {"k8s-cluster-router"=yes}
load_balancer       : []
name                : kube-master
nat                 : []
options             : {}
ports               : [2cbbbb8e-6b5d-44d5-9693-b4069ca9e12a, 3a046f60-161a-4fee-a1b3-d9d3043509d2, 40d3d95d-906b-483b-9b71-1fa6970de6e8, 840ab648-6436-4597-aeff-f84fbc44e3a9, b08758e5-7017-413f-b3db-ff68f49460a4]
static_routes       : []
  • Logical_Router_Port

每一行代表一个逻辑路由器端口,每创建一个 router interface,networking-ovn 会在这张表里加一行,它主要保存了路由器端口的 IP 和 MAC。

# ovn-nbctl --db tcp:172.17.42.30:6641 list Logical_Router_Port
_uuid               : 840ab648-6436-4597-aeff-f84fbc44e3a9
enabled             : []
external_ids        : {}
gateway_chassis     : []
mac                 : "00:00:00:BF:CC:B1"
name                : rtos-kube-master
networks            : ["192.168.1.1/24"]
options             : {}
peer                : []

更多请参考ovn-nb - OVN_Northbound database schema.

Southbound DB

Southbound DB 处在 OVN 架构的中心,它是 OVN 中非常重要的一部分,它跟 OVN 的其他组件都有交互。

Southbound DB 里面有如下几张表:

  • Chassis

ChassisOVN新增的概念,OVS里面没有这个概念,Chassis可以是 HV,也可以是 VTEP 网关。

每一行表示一个 HV 或者 VTEP 网关,由 ovn-controller/ovn-controller-vtep 填写,包含 chassis 的名字和 chassis 支持的封装的配置(指向表 Encap),如果 chassis 是 VTEP 网关,VTEP 网关上和 OVN 关联的逻辑交换机也保存在这张表里。

# ovn-sbctl list Chassis
_uuid               : 3dec4aa7-8f15-493d-89f4-4a260b510bbd
encaps              : [bc324cd4-56f2-4f73-af9e-149b7401e0d2]
external_ids        : {datapath-type="", iface-types="geneve,gre,internal,lisp,patch,stt,system,tap,vxlan", ovn-bridge-mappings=""}
hostname            : "kube-node1"
name                : "c7889c47-2d18-4dd4-a3b7-446d42b79f79"
nb_cfg              : 34
vtep_logical_switches: []
...
  • Encap

保存着tunnel的类型和 tunnel endpoint IP 地址。

# ovn-sbctl list Encap
_uuid               : bc324cd4-56f2-4f73-af9e-149b7401e0d2
chassis_name        : "c7889c47-2d18-4dd4-a3b7-446d42b79f79"
ip                  : "172.17.42.31"
options             : {csum="true"}
type                : vxlan
...
  • Logical_Flow

每一行表示一个逻辑的流表,这张表是 ovn-northd 根据 Nourthbound DB 里面二三层拓扑信息和 ACL 信息转换而来的,ovn-controller 把这个表里面的流表转换成 OVS 流表,配到 HV 上的 OVS table。流表主要包含匹配的规则,匹配的方向,优先级,table ID 和执行的动作。

# ovn-sbctl lflow-list
Datapath: "kube-node1" (2c3caa57-6a58-4416-9bd2-3e2982d83cf1)  Pipeline: ingress
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(eth.src[40]), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=100  , match=(vlan.present), action=(drop;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "default_sshd-2"), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "k8s-kube-node1"), action=(next;)
  table=0 (ls_in_port_sec_l2  ), priority=50   , match=(inport == "stor-kube-node1"), action=(next;)
....
  • Multicast_Group

每一行代表一个组播组,组播报文和广播报文的转发由这张表决定,它保存了组播组所属的 datapath,组播组包含的端口,还有代表 logical egress porttunnel_key

  • Datapath_Binding

每一行代表一个 datapath 和物理网络的绑定关系,每个 logical switchlogical router 对应一行。它主要保存了 OVN 给 datapath 分配的代表 logical datapath identifiertunnel_key

示例:

# ovn-sbctl list Datapath_Binding
_uuid               : 4cfe0e4c-1bbb-406a-9d85-e7bc24c818d0
external_ids        : {logical-router="e12293ba-e61e-40bf-babc-8580d1121641", name=kube-master}
tunnel_key          : 1

_uuid               : 5ec4f962-77a8-44e8-ae01-5b7e46b6a286
external_ids        : {logical-switch="e865aa50-7510-4b7f-9df4-b82801a8e92b", name=join}
tunnel_key          : 2

_uuid               : 2c3caa57-6a58-4416-9bd2-3e2982d83cf1
external_ids        : {logical-switch="7c41601a-dcd5-4e77-b0e8-ca8692d7462b", name="kube-node1"}
tunnel_key          : 4

Port_Binding

这张表主要用来确定 logical port 处在哪个 chassis 上面。每一行包含的内容主要有 logical port 的 MAC 和 IP 地址,端口类型,端口属于哪个 datapath binding,代表 logical input/output port identifiertunnel_key, 以及端口处在哪个 chassis。端口所处的 chassis 由 ovn-controller/ovn-controller 设置,其余的值由 ovn-northd 设置。

示例:

# ovn-sbctl list Port_Binding    
_uuid               : 5e5746d8-3533-45a8-8abe-5a7028c97afa
chassis             : []
datapath            : 2c3caa57-6a58-4416-9bd2-3e2982d83cf1
external_ids        : {}
gateway_chassis     : []
logical_port        : "stor-kube-node1"
mac                 : ["00:00:00:18:22:18"]
nat_addresses       : []
options             : {peer="rtos-kube-node1"}
parent_port         : []
tag                 : []
tunnel_key          : 2
type                : patch
  • 小结

Chassis 和表 Encap 包含的是物理网络的数据,表 Logical_Flow 和表 Multicast_Group 包含的是逻辑网络的数据,表 Datapath_Binding 和表 Port_Binding包含的是逻辑网络和物理网络绑定关系的数据。

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 portinput port identifier output port identifier 相同。

如果 tunnel 类型是 Geneve,Geneve header 里面的 VNI 字段填 logical datapath identifier,Option 字段填 logical input port identifierlogical output port identifier,TLV 的 class 为 0xffff,type 为 0,value 为 0 (1-bit) + logical input port identifier (15-bit) + logical output port identifier (16-bit)。详细参考Geneve: Generic Network Virtualization Encapsulation

Geneve Option:

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Option Class         |      Type     |R|R|R| Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Variable Option Data                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

OVS 的 tunnel 封装是由 Openflow 流表来做的,所以 ovn-controller 需要把这三个标识符写到本地 HV 的 Openflow flow table 里面,对于每个进入 br-int 的报文,都会有这三个属性,logical datapath identifierlogical input port identifier 在入口方向被赋值,分别存在 openflow metadata 字段和 OVS 扩展寄存器 reg14 里面。报文经过 OVS 的 pipeline 处理后,如果需要从指定端口发出去,只需要把 Logical output port identifier 写在 OVS 扩展寄存器 reg15 里面。

示例(port 6对应Geneve tunnel接口):

table=0,in_port=6 actions=move:NXM_NX_TUN_ID[0..23]->OXM_OF_METADATA[0..23],move:NXM_NX_TUN_METADATA0[16..30]->NXM_NX_REG14[0..14],move:NXM_NX_TUN_METADATA0[0..15]->NXM_NX_REG15[0..15],resubmit(,33)

可以看到,NXM_NX_TUN_IDtunnel_keyreg14为15 bit,reg15为16 bit.

OVN tunnel 里面所携带的 logical input port identifierlogical output port identifier 可以提高流表的查找效率,OVS 流表可以通过这两个值来处理报文,不需要解析报文的字段。

Refs


上一篇     下一篇