Open vSwitch
Open vSwitch 是一个开源的虚拟交换机实现。广泛应用在云计算行业,为网络管理员提供虚拟云主机之间和之内的流量可见性与可控性。Open vSwitch 旨在用虚拟化方案解决网络问题,与控制器软件一起实现分布式的虚拟交换技术。这意味着,交换机和控制器软件能够在多个服务器之间创建集群网络配置,从而不需要在每一台云主机和物理主机上单独配置网络。这个交换机还支持 VLAN 中继,通过 NetFlow、sFlow 和 RSPAN 实现可见性,通过 OpenFlow 协议进行管理。它还有其他一些特性:严格流量控制,它由 OpenFlow 交换协议实现;远程管理功能,它能通过网络策略实现更多控制。
在虚拟交换机的 Flow 控制器或管理工具方面,OvS 需要借助第三方控制器或管理工具实现复杂的转发策略。例如 OvS 支持 OpenFlow 协议,我们就可以使用任何支持 OpenFlow 协议的控制器来对 OvS 进行远程管理。但这并不意味着 OvS 必须要有一个控制器才能工作。在不连接外部控制器情况下,OvS 自身可以依靠 MAC 地址学习实现二层数据包转发功能,就像 Linux Bridge。
简而言之,Open vSwitch 即开放的 OpenFlow 交换机,能够达到产品级的质量,也就是说可以部署一些生产环境使用。它不光支持基本的二层交换,还支持标准的管理机接口和协议(e.g. NetFlow,sFlow,SPAN,RSAPN,CLI,LACP,802.1ag),可以很好的与 SDN 体系融合。
Open vSwitch 的特性清单:
- 支持通过 NetFlow、sFlow、IPFIX、SPAN、RSPAN 和 GRE-tunneled 镜像使虚拟机内部通讯可以被监控;
- 支持 LACP(IEEE 802.1AX-2008,多端口绑定)协议;
- 支持标准的 802.1Q VLAN 模型以及 Trunk 模式;
- 支持 BFD 和 802.1ag 链路状态监测;
- 支持 STP(IEEE 802.1D-1998);
- 支持细粒度的 QoS;
- 支持 HFSC 系统级别的流量控制队列;
- 支持每虚拟机网卡的流量的流量控制策略;
- 支持基于源 MAC 负载均衡模式、主备模式、L4 哈希模式的多端口绑定;
- 支持 OpenFlow 协议(包括许多虚拟化的增强特性);
- 支持 IPV6
- 支持多种隧道协议(GRE, VXLAN, IPsec, GRE and VXLAN over IPsec)
- 支持通过 C 或者 Python 接口远程配置;
- 支持内核态和用户态的转发引擎设置;
- 支持多列表转发的发送缓存引擎;
- 支持转发层抽象以容易的定向到新的软件或者硬件平台;
系统架构
OvS 主要由三部分组件构成:
- 用户空间主要组件有 ovsdb-server 和 ovs-vswitchd
- 内核空间中由 datapath 内核模块
- 最上面的 Controller 表示 OpenFlow 控制器,控制器与 OvS 是通过 OpenFlow 协议进行连接
- ovs-vswitchd:主要模块,实现内核 datapath upcall 处理以及 ofproto 查表,同时是 dpdk datapath 处理程序。
- ovsdb-server:数据库服务程序, 使用目前普遍认可的 ovsdb 协议。
- ovs-vsctl:网桥、接口等的创建、删除、设置、查询等。
- ovs-dpctl:配置 vswitch 内核模块
- ovs-appctl:发送命令消息到 ovs-vswithchd, 查看不同模块状态
- ovs-ofctl:下发流表信息。该命令可以配置其他 openflow 交换机(采用 openflow 协议)
ovsdb
ovsdb 是 OvS 轻量级的数据库服务,用于存储整个 OvS 的配置信息,包括接口、交换内容、VLAN、虚拟交换机的创建、网卡的添加等信息与操作记录,都被 ovsdb 保存到一个 conf.db 文件(JSON 格式)里面,通过 db.sock 提供服务。OvS 主进程 ovs-vswitchd 根据数据库中的配置信息工作。
|
|
/etc/openvswitch/conf.db:是数据库文件存放位置,ovsdb-server 需要该文件才能启动,可以使用ovsdb-tool create命令创建并初始化此数据库文件。--remote=punix:/var/run/openvswitch/db.sock:实现了一个 Unix Sockets 连接,OvS 主进程 ovs-vswitchd 或其它命令工具(e.g. ovsdb-client) 通过这个 Socket 连接来管理 ovsdb。/var/log/openvswitch/ovsdb-server.log:ovsdb-server 的运行日志文件。
ovs-vswitchd
ovs-vswitchd 本质是一个守护进程,是 OvS 的核心部件。ovs-vswitchd 和 Datapath 一起实现 OvS 基于流表(Flow-based Switching)的数据交换。
- 通过 OpenFlow 协议可以与 OpenFlow 控制器通信
- 使用 ovsdb 协议与 ovsdb-server 数据库服务通信
- 使用 netlink 和 Datapath 内核模块通信。
ovs-vswitchd 支持多个独立的 Datapath,ovs-vswitchd 需要加载 Datapath 内核模块才能正常运行。ovs-vswitchd 在启动时读取 ovsdb-server 中的配置信息,然后自动配置 Datapaths 和 OvS Switches 的 Flow Tables,所以用户不需要额外的通过执行 ovs-dpctl 指令工具去操作 Datapath。当 ovsdb 中的配置内容被修改,ovs-vswitched 也会自动更新其配置以保持数据同步。ovs-vswitchd 也可以从 OpenFlow 控制器获取流表项。
|
|
datapatch
在 OpenFlow Switch 规则的语义中,给交换机,或者桥,用了一个专业的名词,叫做 Datapath。Open vSwitch 的内核模块 openvswitch.ko 实现了多个 Datapath,每个 Datapath 可以具有多个 Ports。每个 Datapath 通过关联流表(Flow Table)来定义网络包的流向。Datapath 监听网卡接口设备,将监听到的数据包首先在流表中进行匹配,找到匹配的流表项之后把对应的 Actions 返回给 Datapath,作为数据处理行为的描述。Datapath 支持数据在内核空间进行交换。Datapath 的内核模块信息:
|
|
更多 Datapath 的信息可以浏览 The Design and Implementation of Open vSwitch。
工作原理
Bridge 处理数据帧遵循以下几条规则:
- 在一个 Port 上接收到的帧不会再往此 Port 发送此帧。
- 接收到的帧都要学习其 Source MAC 地址。
- 如果数据帧是多播或者广播包(通过 2 层 MAC 地址确定)则要向接收 Port 以外的所有 Port 转发,如果上层协议感兴趣,则还会递交上层处理。
- 如果数据帧的地址不能在 CAM(MAC-Port Mapping)表中找到,则向接收 Port 以外的所有 Port 转发。
- 如果 CAM 表中能找到,则转发给相应 Port,如果发送和接收都是同一个 Port,则不发送。
- 网桥是以混杂模式工作的,所有 MAC 地址的数据帧都能够通过。
用户空间 ovs-vswitchd 和内核模块 Datapath 决定了数据包的转发,如下图:
- 内核态的 Datapath 监听接口设备流入的数据包。
- 如果 Datapath 在内核态流表缓存没有找到相应的匹配流表项则将数据包传入(upcall)到用户态的 ovs-vswitchd 守护进程处理。
- (可选)用户态的 ovs-vswitchd 拥有完整的流表项,通过 OpenFlow 协议与 OpenFlow 控制器或者 ovs-ofctl 命令行工具进行通信,主要是接收 OpenFlow 控制器南向接口的流表项下发。或者根据流表项设置,ovs-vswitchd 可能会将网络包以 Packet-In 消息发送给 OpenFlow 控制器处理。
- ovs-vswitchd 接收到来自 OpenFlow 控制器或 ovs-ofctl 命令行工具的消息后会对内核态的 Flow Table 进行更新。或者根据局部性原理,用户态的 ovs-vswitchd 会将刚刚执行过的 Datapath 没有缓存的流表项注入到 Flow Table 中。
- ovs-vswitchd 匹配完流表项之后将数据包重新注入(reinject)到 Datapath。
- Datapath 再次访问 Flow Table 获取流表项进行匹配。
- 最后,网络包被 Datapath 根据流表项 Actions 转发或丢弃。
上述,Datapath 和 ovs-vswitchd 相互配合中包含了两种网络包的处理方式:
- Fast Path:Datapatch 加载到内核后,会在网卡上注册一个钩子函数,每当有网络包到达网卡时,这个函数就会被调用,将网络包开始层层拆包(MAC 层,IP 层,TCP 层等),然后与流表项匹配,如果找到匹配的流表项则根据既定策略来处理网络包(e.g. 修改 MAC,修改 IP,修改 TCP 端口,从哪个网卡发出去等等),再将网络包从网卡发出。这个处理过程全在内核完成,所以非常快,称之为 Fast Path。
- Slow Path:内核态并没有被分配太多内存,所以内核态能够保存的流表项很少,往往有新的流表项到来后,老的流表项就被丢弃。如果在内核态找不到流表项,则需要到用户态去查询,网络包会通过 netlink(一种内核态与用户态交互的机制)发送给 ovs-vswitchd,ovs-vswitchd 有一个监听线程,当发现有从内核态发过来的网络包,就进入自己的处理流程,然后再次将网络包重新注入到 Datapath。显然,在用户态处理是相对较慢的,故称值为 Slow Path。
在用户态的 ovs-vswtichd 不需要吝啬内存,它包含了所有流表项,这些流表项可能是 OpenFlow 控制器通过 OpenFlow 协议下发的,也可能是 OvS 命令行工具 ovs-ofctl 设定的。ovs-vswtichd 会根据网络包的信息层层匹配,直到找到一款流表项进行处理。如果实在找不到,则一般会采用默认流表项,比如丢弃这个包。
当最终匹配到了一个流表项之后,则会根据 “局部性原理(局部数据在一段时间都会被频繁访问,是缓存设计的基础原理)” 再通过 netlink 协议,将这条策略下发到内核态,当这条策略下发给内核时,如果内核的内存空间不足,则会开始淘汰部分老策略。这样保证下一个相同类型的网络包能够直接从内核匹配到,以此加快执行效率。由于近因效应,接下来的网络包应该大概率能够匹配这条策略的。例如:传输一个文件,同类型的网络包会源源不断的到来。
工具命令
- ovs-vsctl:用于管理 ovs-vswitchd 的配置信息。
- ovs-ofctl:用于管理 OvS 的流表信息。
- ovs-pki:用于管理 OvS 与 OpenFlow Controller 之间的 TSL 通信框架。
- ovs-dpctl:用于管理 Datapath,比如查看 Datapath 信息。
- ovs-appctl:应用层的指令集,例如:模拟数据包用于测试 OvS Switch 数据转发流程。
|
|
安装部署
OS:CentOS7
Step1. 关闭 SELinux,否则 ovsdb-server Manager 无法正常工作。
|
|
Step 2. yum install
|
|
Step 3. 启动服务
|
|
查看当前的 OvS 版本:
|
|
查看 OvS 服务进程清单:
|
|
查看加载的内核模块:
|
|
ovs-db
ovs-db 在操作系统上的载体是 JSON 文件 /etc/openvswitch/conf.db,通过执行指令 ovsdb-client dump 可以查看其内容,e.g.
|
|
使用图形化工具可以更加友好的查看:
数据库表之间的关系如下图所示:
其中 Open_vSwitch 表是 OvS DB 的 root(根)。
它的表结构如下图,记录 ovs-vswitchd 的配置信息,e.g.
- Bridge 设备的配置
- OvS 本身的配置
- other_config:stats-update-interval:将统计信息写入数据库的间隔时间
- other_config:flow-restore-wait: 针对 hot-upgrade,如果为 True 则不处理任何包。一般使用的过程为:先停掉 ovs-vswitchd,然后将这个值设为 True,再启动 ovs-vswitchd。这个时候不处理任何包,然后使用 ovs-ofctl 将 flow table restore 到一个正确的状态,最后设置这个值为 False,开始处理包。
- other_config:flow-limit:指定 Flow Table 中 flow entry(入口)的数量
- other_config:n-handler-threads:用于处理新 Flow 的线程数
- other_config:n-revalidator-threads:用于验证 Flow 的线程数
- other_config:enable-statistics:是否统计以下项目
- statistics:cpu:统计 CPU 数量,线程
- statistics:load_average:system load
- statistics:memory:总 RAM,Swap
- statistics:process_NAME:统计 memory size, cpu time 等(with NAME replaced by a process name)
- statistics:file_systems:mount point, size, used
- client request id:cur_cfg 和 next_cfg,当一个 Client 修改完数据库时,next_cfg 加 1,然后等待 OvS 应用这些修改,当应用完毕,则 cur_cfg 加 1,此时 cur_cfg 等于 next_cfg。显然,该配置是为了保证高并发请求的一致性而存在的。
- 对 ovsdb-server 的配置,指向 Manager 表,ovs-vswitchd 作为 ovsdb-server 的 Client 之一,Manager 配置了 DB Connection 的字段。
- 对 SSL DB Connection 的配置:指向 SSL 表,主要配置 SSL 安全通信所需要的 private key、certificate 等文件的路径。
Open vSwitch 的操作对象
数据库结构是一款软件的资源模型设计的映射,下文主要根据 OvS 的资源模型来依次认识每种资源对象的特性与作用。
Manager
Manager 对象都是为了配置 ovsdb-server 的 Connection,让 Clients(e.g. ovs-vswitchd、ovs-vsctl、host) 可以远程对 ovsdb-server 执行 DB Operation。从上述架构图可知,ovsdb-server 是 ovs-db 提供管理的 RPC 接口。加载了 Open_vSwitch 表中的 manager_options 字段值来作为监听端口。
Manager 的表结构:
其中最重要的字段是 target,记录了 ovsdb-server 的监听参数信息:
- Active(主动)database connection methods:
ssl:ip[:port]:监听在指定 Remote IP 的 Port 上,协议为 SSLtcp:ip[:port]:监听在指定 Remote IP 的 Port 上,协议为 TCPunix:FILE:Unix domain socket named FILE
- Passive(被动)database connection methods:
pssl:[port][:ip]:监听在本机 IP 的指定 Port 上,协议为 SSLptcp:[port][:ip]:监听在本机 IP 的指定 Port 上,协议为 TCP
通过下述指令设置:
|
|
NOTE:基于 TCP 的 DB Connection,使得 ovs-vsctl 在远程机器上也可以控制 ovsdb-server。
配置 Manager OvS DB Connection
|
|
检查 Port 是否正常开启:
|
|
从远程计算机上执行连接:
|
|
NOTE:注意防火墙的干扰因素。
SSL
如果将 Open vSwitch 配置为通过网络连接到 OpenFlow 控制器(ovs-vswitchd 与 ovs-controller 之间),那么建议你使用 OpenSSL 来构建安全的网络通讯,双向的 SSL 互相可确保 OpenFlow 连接的完整性和与安全。
想建立 SSL 连接,首先要获取相关的 CA 证书,并将这些证书记录到 SSL 表中。启动 ovsdb-server 时,通过选项 --private-key=db:Open_vSwitch,SSL,private_key --certificate=db:Open_vSwitch,SSL,certificate --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert 来指定应用这些参数。
SSL 表结构:
SSL 表属性:
- private_key:私钥
- ca_cert:CA 根证书
- bootstrap_ca_cert(Boolean):如果为 True,则每次启动 ovsdb-server,都会向 Controller 获取最新的 CA 证书。否则,就继续使用旧的 CA 证书。
- certificate:CA 签发的证书
其中主机(客户端)的 Public key 包含在 CA 签发的证书(certificate)内,然后再由 CA 中心的 private key 进行签名,CA 中心来担保这个 certificate 是合法的。为了验证 CA 签名,还需要 CA 的 public key,并放到 ca_cert 指向的 CA 证书里面。而 CA 本身的 public key 也需要被签名更高级的 CA 或者 CA(根 CA)自己担保。
SSL 验证流程:
-
客户端持有 CA 根证书(ca_cert)并与 CA 的私钥进行验证(CA 根证书由 CA 通过自己的私钥进行自签发),验证成功则说明该 CA 是 root CA,可以自己担保自己。
-
客户端持有 CA 签发的证书(certificate,内含客户端公钥)并与 CA 根证书进行验证(由 CA 签发的证书可以使用 CA 私钥解开),如果验证成功则返回客户端的公钥。
-
客户端持有自己的私钥并与 CA 解开的客户端公钥进行验证,验证成功,则说明该客户端是受到 CA 担保的。
-
客户端与服务器建立 SSL 连接。
-
简而言之,客户端需要保证持有自己的私钥、CA 签发的证书、CA 根证书才可以完成 SSL 验证。更多 CA 自签发的内容,请浏览《自建 CA 中心并签发 CA 证书》。
|
|
配置 SSL Connection
自签发 CA 根证书:
- Step 1. 生成 CA 根证书的 RSA 私钥
|
|
- Step 2. 生成 CA 根证书的签名请求(CSR)
|
|
- Step 3. 自签发 CA 根证书(内含了 CA 的公钥)
|
|
PS:自签发即自己担保自己,用自己的私钥对自己的 CSR 进行签发,所以也称为根证书。
签发客户端证书:
- Step 1. 生成客户端私钥
|
|
- Step 2. 生成客户端签名请求
|
|
- Step 3. CA 中心签发客户端证书(CA 中心担保该客户端)
|
|
配置 SSL Connection:
|
|
NOTE:set-ssl 一定要指定绝对路径,否则无法正确载入证书文件。
查看修改:
|
|
验证:
- 此时如果不输入 PKI 配置则无法通过 SSL 认证
|
|
- 将 cliu8private.key、cliu8certificate.pem、cacertificate.pem 的副本复制到客户端
|
|
- 在客户端请求建立 SSL 连接
|
|
NOTE:
|
|
Bridge
Bridge 即网桥,但在 Linux 的语义中 Bridge 与以太网交换机具有相同的含义,是 Open vSwitch 最核心的对象。下面主要记录了 OvS 关于 Bridge 的常见操作。
Bridge 常用操作指令
|
|
- 创建虚拟交换机:
|
|
- 创建虚拟 “网线”(VETH pair):
|
|
- 查看新建的设备:
|
|
- 将虚拟 “网线” 的一端接入虚拟交换机:
|
|
NOTE:Bridge ubuntu_br 的同名 Port,一般就是 Bridge 的管理端口了,类比物理交换机的管理端口,一般会为其配置 IP 地址。
Controller
OvS 是一个 OpenFlow Switch 实现,可以通过 OpenFlow Controlle 对所有分布式的 Bridge 进行统一管理。所谓 “管理”,实际上是对 Bridge 的 Flow Table 的管理。SDN Controller 的核心是控制策略的下发,并以此来决策数据的流向。
Controller 有两种类型:
- Primary Controller:真正控制 Bridge 的 Flow Table,Bridge 会保持与 Controller 的连接,如果连接失败或断开,取决于 Bridge 的 Fail Mode 来进行处理。一个 Bridge 可以连接到多个 Controller,但是 Controller 之间的协作需要 Controller 自己来完成。
- Service Controller:仅仅用于 Support,偶尔操作,Maintain 使用,如果 Connection 与 Bridge 断开连接,Bridge 的 Fail Mode 也不会起作用。
OvS 为 Bridge 提供了下列两种 Fail Mode:
- Secure:断开连接后 Bridge 会试图重连 Controller 直至成功,并不会自己维护 Flow Table。
- Standalone:若 Bridge 尝试三次依旧连接不上 Controller,则会自己建立并维护独立的 Flow Table。
|
|
Controller 表结构:
Controller 常用指令
|
|
安装 Floodlight
OpenFlow Controller 的种类繁多,常见有如 OpenDaylight 等等,详细清单可浏览《OpenFlow Controllers in GENI》。本篇以 Floodlight 为例,感受 Controller 对 Bridge 的流量控制功能。
官方网站:http://www.projectfloodlight.org/getting-started/ 官方部署手册:https://floodlight.atlassian.net/wiki/spaces/floodlightcontroller/pages/1343544/Installation+Guide
Installing Floodlight:
|
|
NOTE: 这里使用的是 Tag 1.2 版本
Running Floodlight in the Terminal:
|
|
检查 Controller 的监听端口:
|
|
NOTE:Floodlight 会通过监听 /0.0.0.0:6653 Socket 来获取 Bridge 的连接。
将 Bridge 连接到 Controller:
|
|
NOTE:Bridge 连接到 Controller 之后,Controller 就可以收集、下发、管理 Bridge 的相关信息了(e.g. Flow Table)。
访问 Web GUI:
|
|
将 KVM 虚拟机接入 OvS Bridge
将三台 KVM 虚拟机接入到 Bridge:
|
|
NOTE:VM1、2、3 都连接到同一个 Bridge 上,只要三者具有网段的 IP 地址就可以通信了。
查看 Floodlight Dashboard:
等待一段时间 Floodlight 就会将会主机上的 Bridges、Bridge 上的 Hosts、Host 的 IP/MAC 地址等信息收集上来。
Floodlight Controller 常用指令
Floodlight Dashboard 基本上只作为展示,所以大部分操作依旧需要通过指令行来完成。
- 请求该 Controller 上所有 Switch 的 DPID
|
|
- 查看流表项
|
|
- 查看指定 Switch 的流表项
|
|
- 添加静态流表项
|
|
- 只允许 10.0.0.101 和 10.0.0.103 相互 Ping 的静态流表
|
|
- 删除指定流表
|
|
- 删除指定 Switch 所有流表
|
|
Mirror
Mirror 的功能就是配置一个 Bridge 将某些具有特定条件的包发给指定的 Mirrored Ports。
包的条件有以下几种:
- select_all
- select_dst_port
- select_src_port
- select_vlan
指定的目的 Ports 有以下两种:
- output_port (SPAN Switched Port ANalyzer)
- output_vlan (RSPAN Remote Switched Port ANalyzer)
SPAN
Source (SPAN) port - A port that is monitored with use of the SPAN feature. Destination (SPAN) port - A port that monitors source ports, usually where a network analyzer is connected.
|
|
RSPAN
-
被监控的流量不是发送到一个指定的端口,而是 Flood 给指定的 VLAN
-
监听的端口不一定要在本地 Switch 上,可以在指定的 VLAN 的任意 Switch 上
-
S1 is a source switch
-
S2 and S3 are intermediate switches
-
S4 and S5 are destination switches.
-
learning is disabled to enable flooding
Port 与 Interface
Port 即 Bridge 的端口,每个 Port 都隶属于一个 Bridge。Interface 则是连接到 Port 的网络接口设备,实际负责接受和发送数据包。通常情况下,Port 和 Interface 是一对一关系,为 Port 配置 bond 模式后,Port:Interface 是 1:N 的关系。
Port 具有以下 3 种类型:
- Normal:可以把 HostOS 中已有的网卡(物理的或虚拟的)挂载到 Bridge 上,OvS 会在 Bridge 上生成一个同名的 Port 处理进出这块网卡的数据包。需要注意的是,挂载到 Bridge 上的网络不支持分配 IP 地址。
|
|
- Internal:是 OvS 内部创建的虚拟网卡接口。每创建一个 Internal 类型的 Port,OvS 就会在 HostOS 上自动创建一个同名 internal Interface 并挂载到 Port 上。只有 Internal 类型的 Interface 设备才支持配置 IP 地址信息。
|
|
- Patch:当 HostOS 上有多个 OvS Bridge 时,可以使用 Patch Port(虚拟网线端口)把两个 Bridge 连起来。Patch Port 总是成对出现,分别连接到两个网桥上,从一个 Patch Port 收到的数据包会被转发到另一个 Patch Port。类似于 Linux 系统中的 VETH Pair。使用 Patch Port 连接的两个网桥跟一个网桥没什么区别。
|
|
- Tunnel:常见隧道技术有 GRE 或 VxLAN。隧道技术是在现有的物理网络之上构建一层虚拟网络,上层应用只与虚拟网络相关,以此实现的虚拟网络比物理网络配置更加灵活,并能够实现跨主机的 L2 通信。隧道技术让不同主机上的 Bridge 能够互通,就像连接在一个大的 Bridge 上似的。
|
|
- netdev:通用网卡设备(e.g. eth0、veth)
- 接收:一个 netdev 在 L2 收到报文后会直接通过 OvS 接收函数处理,不会再走传统内核 TCP/IP 协议栈。
- 发送:OvS 中的一条流指定从该 netdev 发出的时候就通过该网卡设备发送。
- internal:虚拟网卡设备
- 接收:当从系统发出的报文路由查找通过该设备发送的时候,就进入 OvS 接收处理函数。
- 发送:OvS 中的一条流制定从该 internal 设备发出的时候,该报文被重新注入内核协议栈。
- gre device:隧道设备(不管用户态创建多少个 GRE Tunnel,在内核态有且只有一个 GRE 设备)
- 接收:当系统收到 GRE 报文后,传递给 L4 层解析 gre header,然后传递给 OvS 接收处理函数。
- 发送:OvS 中的一条流制定从该 GRE 设备发送,报文会根据流表规则加上 GRE 头以及外层包裹 IP,查找路由发送。
Port 的 VLAN
Port 的一个重要的特性就是 VLAN Configuration,具有两种类型:
- Trunk Port
- Access Port
Trunk Port:
- 这个 Port 不配置 Tag,配置 trunks。
- 如果 trunks 为空,则所有的 VLAN 都 trunk,缺省 VLAN ID 为 0,全部允许通过。
- 如果 trunks 不为空,则仅有符合条件(ID)的 VLAN 能通过。
简而言之,就是物理交换机的 Trunk 口,符合 Trunks 列表的 VLAN ID 可通过。
Access Port:
- 这个 Port 配置 Tag,从这个 Port 进来的包都被打上 Tag(ID)。
- 如果从其他的 Trunk Port 中进来的本身就带有 VLAN ID 的包,若 VLAN ID 等于这个 Port 的 Tag,则会从这个 Port 发出。
- 从其他的 Access Port 进来的包,如果 Tag 相同,也会被 Forward 到这个 Port。
- 从 Access Port 发出的包会被摘除 Tag,不带 VLAN ID。
- 如果一个本身带 VLAN ID 的包到达 Access Port,即便 VLAN ID 等于 Tag,也会被抛弃,Access Port 只接受 Untag 包。
简而言之,由 Access Port 接收到的包会被打上 Tag,Access Port 只接收 Untag 包,否则丢弃。具有相同 VLAN ID 的包会给转发到对应的 Access Port 然后解除 Tag 再发出。
Port 的 VLAN 常用操作指令
|
|
Port 的 Bond
Port 和 Interface 的关系是一对多的关系,因为 OvS 支持 Bond 功能。所谓 Bond 就是将多个 Interface “捆绑” 在一起形成一个虚拟的连接,从而实现高可用性以及高吞吐量的效果。
常见的 bond_mode 有以下几种:
- active-backup:故障转移,一个连接 Active,其他连接 Backup。
- balance-slb:负载均衡,根据源 MAC 和 output VLAN 进行负载均衡。
- balance-tcp:负载均衡,必须在支持 LACP 协议的情况下才可以,可根据 L2, L3, L4 进行负载均衡。
- stable(LACP):Attempts to always assign a given flow to the same slave consistently.
PS:LACP (Link Aggregation Control Protocol,链路聚合控制协议)。
OvS 的 bond 模型:
Port 的 QoS
OvS 中的 Qos 往往是和 Flow Policy 一起使用的。总所周知 QoS 有两个方向,一个是入方向(Ingress),一个是出方向(Egress)。
网络流程 QoS 的实现原理与方式
在 Linux 上最常用的网络 QoS 就是 TC 工具,其主要是通过 队列 的方式来实现的。
- Classless Queuing Disciplines:默认为 pfifo_fast,是一种不把网络包分类的技术。pfifo_fast 根据网络包中的 TOS 对应的数字,在 TOS 的 priomap 中查看对应的 Band,不同的 Band 对应的不同的队列。
- SFQ, Stochastic Fair Queuing:有很多的 FIFO 的队列,TCP Session 或者 UDP stream 会被分配到某个队列。包会 RoundRobin 的从各个队列中取出发送。这样一个 Session 就不会占据所有的流量。但不是每一个 Session 都具有一个队列,而是通过 Hash 算法,将大量的 Session 分配到有限的队列中。这样两个或若干个 Session 会共享一个队列,也有可能互相影响。因此 Hash 函数会经常改变,从而 Session 不会总是相互影响。
- TBF, Token Bucket Filter:所有的网络包排成队列进行发送,但不是到了队头就能发送,而是需要拿到 Token 的包才能发送。Token 根据设定的速率(Rate)生成,所以即便队列很长,也会按照 Rate 进行发送。当没有包在队列中时,Token 还是以既定的速度生成,但是并非无限累积,而是到 Buckets 放满为止,篮子(buckets)的大小常用 burst/buffer/maxburst 参数来设定。Buckets 会避免下面这种情况:当长时间没有包发送的时候,积累了大量的 Token,突然来了大量的包,每个都能得到 Token,造成瞬间流量大增。
- Classful Queuing Disciplines:其中典型的为 HTB, Hierarchical Token Bucket。
- Shaping:仅仅发生在叶子节点,依赖于其他的 Queue。
- Borrowing:当网络资源空闲的时候,借点过来为我所用。
- Rate:设定的速率。
- Ceil:最大的速率,与 Rate 之间的差值表示最多能向别人借多少。
使用 TC 创建一个 HTB(Hierarchical Token Bucket)树
|
|
实际上 OvS 能控制的只有 Egress QoS,通过 Shaping 实现。而 Ingress QoS 是无法控制的,只能通过 Policy 将指定的包丢弃。
Ingress policy:
|
|
Egress shaping:Port QoS policy 仅支持 HTB。
- 在 Port 上可以创建 QoS
- 一个 QoS 可以有多个 Queue
- 规则通过 Flow 设定
Tunnel
OvS 支持三种隧道类型,这三种 Tunnel 的原理均在 《Networking 基础术语/概念》中讲过,不再赘述。
- GRE
- VxLAN
- IPSec_gre
OvS Tunnel 的操作指令示例
|
|
Flow Table
Open vSwitch 定义了一系列的 Flow Table,通过这些 Tables 来控制网络包的流向和结构。
根据 OpenFlow 协议,一行 Flow Entry 应该由两部分组成:
- Match Field
- Action
如果数据包符合 Match 则执行 Action。
Match Field 对网络包进行解析,解析的内容涵盖了 TCP/IP 协议族各层,具有下列字段,看这些字段是否能够匹配某个值。
- Layer 1 – Tunnel ID, In Port, QoS priority, skb mark
- Layer 2 – MAC address, VLAN ID, Ethernet type
- Layer 3 – IPv4/IPv6 fields, ARP
- Layer 4 – TCP/UDP, ICMP, ND
Action 主要包含下列操作:
- Output to port (port range, flood, mirror)
- Discard, Resubmit to table x
- Packet Mangling (Push/Pop VLAN header, TOS, …)
- Send to controller, Learn
常用流表操作指令
OvS 对 Flow Table 的管理,主要通过 ovs-ofctl 工具来完成:
|
|
参考资料
- OpenVSwitch 官方网站
- The Design and Implementation of Open vSwitch
- https://www.sdnlab.com/5365.html
- http://arthurchiao.art/blog/ovs-deep-dive-0-overview/
- https://opengers.github.io/openstack/openstack-base-use-openvswitch/#ovsdb-server
- https://tonydeng.github.io/sdn-handbook/ovs/internal.html
- https://www.slideshare.net/rajdeep/openvswitch-deep-dive
- https://www.cnblogs.com/hwy89289709/p/7344326.html
-
No backlinks found.