ovs-vswitchd.conf.db(5)是Open vSwitch数据库的一份使用手册。Open vSwitch数据库内部使用了很多表来存储不同特性的配置信息。
下图展示的是这些表格之间的关系图:
我们关注的OVS流控功能主要集中在上图红色所框的部分。
图中的符号:”?”、”*”、”+”代表的意思是:
“?”:0个或1个;
“*”:0个或多个;
“+”:1个或多个;
Port: 表示一个Bridge中的0个或多个Port。通常情况下,一个Port对应一个Interface。当Port对应多个Interface时,称为”Bounded Port – 绑定端口”。每个Port可以对应有0个或1个Qos。
Interface:一个Interface中,可以有Ingress Policing。
注意:Ingress和Engress是从vSwitch的角度来看的。如下图所示。所以,对于Ingress,物理网络接口eth0为从外部网络接收报文方向,虚拟网络接口vnet0和vnet1为VM发送报文方向;对于Engress,物理网络接口eth0为向外部网络发送报文方向,虚拟网络接口vnet0和vnet1为VM接收报文方向。
- Ingress Policing(在手册中的page 32):
这个设置是用来控制Interface接收报文的速率。对于物理接口,这是用来限制从外部接收报文的速率;对于虚拟接口(与虚拟机连接),这是用来限制虚拟机VM可以发送报文的速率。Policing只是一种简单的Qos,对于超出配置速率到来的报文,直接丢弃掉。由于它的简单,policing通常不够准确且比egress Qos不够有效。需要配置如下两个参数:
- ingress_policing_burst: interface接收数据的最大突发,单位为kb。这个值也对应了令牌桶的大小。如果设置为0,默认值为1000kb。如果ingress_policing_rate为0,这个值是无效的。
- ingress_policing_rate: interface接收数据的最大速率,单位为kbps。接收的数据速率如果超过了这个配置值,将丢弃报文。默认值为0,表示禁用policing。
通常建议设置一个较大的ingress_policing_burst值,这将使得整个算法更为有效。这个值不应该小于MTU。
对于TCP流,通常ingress_policing_burst设置为ingress_policing_rate的10%(比如ingress_policing_rate为1Mbps,那么ingress_policing_burst设置为100kb)。这样可以获得所期望的速率。而对于UDP流,可将ingress_policing_burst设置为略大于MTU的值,同时确保报文大小不大于MTU,否则将由于报文的分片而对性能产生较大的影响。
Ingress Policing配置示例:
ovs-vsctl set interface tap0 ingress_policing_rate=1000
ovs-vsctl set interface tap0 ingress_policing_burst=100
ovs-vsctl set interface tap1 ingress_policing_rate=10000
ovs-vsctl set interface tap1 ingress_policing_burst=1000
- Qos table(在手册的page 41):
type: Qos的类型(string),有如下的类型可选择。
- linux-htb: 分层令牌桶;
- linux-hfsc: 分层公平服务曲线;
- linux-sfq: 随机公平队列;
- linux-codel: 可控制时延;
- linux-fq_codel: 可控制时延的公平队列;
queues: queue numbers。
Queue numbers是用来映射对应的Queue。该数值的范围取决于type值。Queue 0是默认的queue。
other_config: max-rate(为linux-htb和linux-hfsc配置使用)
所有queue共享的最大速率。单位是bit/s。可选。如果未指定,对于物理接口,默认值为接口的速率。对于其他接口或链路速率未知的接口,默认值为100Mbps。
配置示例:假设设置一个bridge br0,与物理以太网接口eth0(1Gbps)及其两个虚拟接口vif1.0和vif2.0相连。vif1.0到eth0限速10Mbps,vif2.0到eth0限速20Mbps。
ovs-vsctl -- \ add-br br0 -- \ add-port br0 eth0 -- \ add-port br0 vif1.0 -- set interface vif1.0 ofport_request=5 -- \ add-port br0 vif2.0 -- set interface vif2.0 ofport_request=6 -- \ set port eth0 qos=@newqos -- \ --id=@newqos create qos type=linux-htb \ other-config:max-rate=1000000000 \ queues:123=@vif10queue \ queues:234=@vif20queue -- \ --id=@vif10queue create queue other-config:max-rate=10000000 -- \ --id=@vif20queue create queue other-config:max-rate=20000000
- Queue Table(在手册上的page43)
端口输出队列的配置。由Qos table中的queues关联。
dscp: 整数,可选。0~63。如果设置了该值,Open vSwitch将会标记所有从该队列输出的报文。如果未设置,报文的DSCP比特值将保留不变。
配置linux-htb参数:
- other_config: min-rate: 可选。至少为1。最小保证的带宽,单位bit/s;
- other_config: max-rate: 可选。至少为1。最大允许的带宽,单位bit/s。如果定义了该参数,出队的速率可以运行超过所规定的速率(在有额外带宽的前提下)。如果未定义,默认为没有限制。
- other_config: burst: 可选。至少为1。单位bit。该参数值表示当队列空闲时,可以累积的令牌最大数量。
- other_config: priority: 可选。值的范围为0~4,294,967,295。如果未定义,默认值为0。
配置linux-hfsc参数:
- other_config: min-rate: 可选。至少为1。最小保证带宽,单位bit/s。
- other_config: max-rate: 可选。至少为1。最大允许的带宽,单位bit/s。如果定义了该参数,出队的速率可以允许超过所指定的速率(在有额外带宽可用的前提下)。如果未定义,默认是没有限制。
配置示例:(引用上面的示例)
ovs-vsctl -- \ add-br br0 -- \ add-port br0 eth0 -- \ add-port br0 vif1.0 -- set interface vif1.0 ofport_request=5 -- \ add-port br0 vif2.0 -- set interface vif2.0 ofport_request=6 -- \ set port eth0 qos=@newqos -- \ --id=@newqos create qos type=linux-htb \ other-config:max-rate=1000000000 \ queues:123=@vif10queue \ queues:234=@vif20queue -- \ --id=@vif10queue create queue other-config:max-rate=10000000 -- \ --id=@vif20queue create queue other-config:max-rate=20000000
上面的例子配置,到达接口eth0的报文并不知道如何根据什么策略来进入相应的队列中。这些报文默认地进入default queue。我们可以使用OpenFlow来将报文送入相应的队列中:
ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normalovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal 这样,来自接口vif1.0的报文,送入队列123,来自接口vif2.0的报文送入队列234中。
- 测试实验 – 使用netperf工具
测试拓扑图如下所示:
- 在vmnet2设置ingress,配置如下:(分配限速速率为1M、10M、0M)
- 限速1M:
ovs-vsctl set interface vmnet2 ingress_policing_rate=1000
ovs-vsctl set interface vmnet2 ingress_policing_burst=100
执行ovs-vsctl list interface vmnet2,查看配置的结果,如下图所示:
在VM1上,使用netperf工具,向VM2发送TCP报文。执行如下的命令:
netperf –H 172.18.105.84,限速结果如下图所示:
在VM1上,使用netperf工具,向VM2发送UDP报文。执行如下的命令:
netperf –H 172.18.105.84 –t UDP_STREAM -- -m 1000,限速结果如下图所示:
- 限速10M:
ovs-vsctl set interface vmnet2 ingress_policing_rate=10000
ovs-vsctl set interface vmnet2 ingress_policing_burst=1000
执行ovs-vsctl list interface vmnet2,查看配置的结果,如下图所示:
在VM1上,使用netperf工具,向VM2发送TCP报文。执行如下的命令:
netperf –H 172.18.105.84,限速结果如下图所示:
在VM1上,使用netperf工具,向VM2发送UDP报文。执行如下的命令:
netperf –H 172.18.105.84 –t UDP_STREAM -- -m 1000,限速结果如下图所示:
- 不限速(限速0M)
ovs-vsctl set interface vmnet2 ingress_policing_burst=0
ovs-vsctl set interface vmnet2 ingress_policing_rate=0
执行ovs-vsctl list interface vmnet2,查看配置的结果,如下图所示:
- 设置vmnet3 egress --- htb算法
配置命令:在vmnet4限速VM1流量6M,VM2流量4M
ovs-vsctl -- \
add-br br0 -- \
add-port br0 vmnet4 -- \
add-port br0 vmnet2 -- set interface vmnet2 ofport_request=2 -- \
add-port br0 vmnet3 -- set interface vmnet3 ofport_request=3 -- \
set port vmnet4 qos=@newqos -- \
--id=@newqos create qos type=linux-htb \
other-config:max-rate=10000000 \
queues:2=@vmnet2queue \
queues:3=@vmnet3queue -- \
--id=@vmnet2queue create queue other-config:min-rate=6000000 other-config:max-rate=10000000 -- \
--id=@vmnet3queue create queue other-config:min-rate=4000000 other-config:max-rate=10000000
设置OpenFlow流表:
ovs-ofctl add-flow br0 in_port=2,actions=set_queue:2,normal
ovs-ofctl add-flow br0 in_port=3,actions=set_queue:3,normal
配置后的效果:
- vm1向vm3打流:
因为只有vm1向vm3打流,所以不存在vm2与vm1带宽的比例分配,所以vm1可以以最大的速率10M发送数据。
- vm2向vm3打流:
同样因为只有vm2向vm3打流,所以不存在vm2与vm1带宽的比例分配,所以vm2可以以最大的速率10M发送数据。
- vm1和vm2一起向vm3打流:
上面的两个图,第一个图是对应vm2,第二个图对应vm1.从中可以看出,vm1和vm2一起向vm3打流时,带宽按6:4的比例分配。