Open vSwitch系列之一 Open vSwitch誕生
Open vSwitch系列之二 安裝指定版本ovs
Open vSwitch系列之三 ovs-vsctl命令使用
Open vSwitch系列之四 ovs-ofctl命令使用
Open vSwitch系列之五 網橋特性功能配置
Open vSwitch系列之六 vlan隔離
Open vSwitch系列之七 meter表限速
Open vSwitch系列之八 vxlan隧道
Open vSwitch系列之九 Group表
Open vSwitch系列之十 調用北向接口下發流表
OpenvSwitch系列之十一 ovs-dpdk
網絡限速有很多種方式,比如網卡限速,隊列限速,meter表限速。其中meter表限速是頗具代表性的限速方式。因為網卡限速和隊列限速都是傳統網絡的限速方式,而meter表是SDN架構下的限速方式。本篇主要介紹meter限速。
由於meter表是OpenFlow13出現的特性,而Open VSwitch 2.8.0以上的版本才支持OpenFlow13。
所以本文實驗環境: Ubuntu1604 desktop
+ Mininet
+ ovs2.8.1
。
安裝順序:先安裝mininet
所有組件,然后編譯安裝ovs2.8.1
原理
meter表限速的原理是丟棄多余數據包。首先創建一個轉發的流表。比如:
- 交換機上有流表:1端口進來的流量從2端口出去,
in_port=1,actions=output:2
。 - 這個時候再創建一個meter表,作用是:速度超過10M的流量丟棄,
meter=1,type=drop,rate=10000
- 最后修改流表使用該meter表。
in_port=1,actions=meter:1,output:2
這是從1端口進來的流量,在從2端口轉發出去之前會被meter表處理,處理方式就是丟棄掉超過10M的流量,然后再轉發到2口。
以上就是meter表的工作原理,使用的是偽命令。下面具體分析meter表
數據結構:
meter表的數據結構如下:
struct ofp_meter_mod {
struct ofp_header header;
uint16_t command; /* One of OFPMC_*. */
uint16_t flags; /* One of OFPMF_*. */
uint32_t meter_id; /* Meter instance. */
struct ofp_meter_band_header bands[0]; /* The bands length is inferred from the length field in the header. */
};
command:
command字段是表示該meter表的操作,是增加、修改或者刪除 meter表。
/* Meter commands */
enum ofp_meter_mod_command {
OFPMC_ADD, /* New meter. */
OFPMC_MODIFY, /* Modify specified meter. */
OFPMC_DELETE, /* Delete specified meter. */
};
flags:
flag字段能夠表示的信息很多,一個16位的字節,能夠表示:
- meter表限速的單位。默認單位是 kb/s
- 更換成 packet/s 的算法
- 是否開啟burst
- 是否統計
enum ofp_meter_flags {
OFPMF_KBPS = 1 << 0, /* Rate value in kb/s (kilo-bit per second). */
OFPMF_PKTPS = 1 << 1, /* Rate value in packet/sec. */
OFPMF_BURST = 1 << 2, /* Do burst size. */
OFPMF_STATS = 1 << 3, /* Collect statistics. */
};
meter_id:
meter_id 這個字段是meter表的身份id,在交換機中是唯一的。memter_id的定義是從1開始的,最大值是根據交換機能夠支持的最大數值而定。
band:
/* Common header for all meter bands */
struct ofp_meter_band_header {
uint16_t type; /* One of OFPMBT_*. */
uint16_t len; /* Length in bytes of this band. */
uint32_t rate; /* Rate for this band. */
uint32_t burst_size; /* Size of bursts. */
};
band字段是一個速度band數組。它可以包含多個數量的計量帶,並且每一個計量帶都可以重復。同一時間只有一個計量帶生效,如果數據包的速度超過所有的計量帶,那么配置的速度最高的計量帶會被使用。
/* Common header for all meter bands */
struct ofp_meter_band_header {
uint16_t type; /* One of OFPMBT_*. */
uint16_t len; /* Length in bytes of this band. */
uint32_t rate; /* Rate for this band. */
uint32_t burst_size; /* Size of bursts. */
};
type:
The type field must be one of the following:
/* Meter band types */
enum ofp_meter_band_type {
OFPMBT_DROP = 1, /* Drop packet. */
OFPMBT_DSCP_REMARK = 2, /* Remark DSCP in the IP header. */
OFPMBT_EXPERIMENTER = 0xFFFF /* Experimenter meter band. */
};
type
字段是指高出限速值的數據包的處理方式。主要有丟棄
和設置優先丟棄
。一個openflow交換機可能不會支持所有的band的type值,也不是所有的meter都要支持全部的type值。
type中三種處理動作:
-
drop:
計量帶OFPMBT_DROP定義了一個簡單的速度限制器,會丟棄掉超過該值的數據包 -
remark:
OFPMBT_DSCP_REMARK 字段定義了一個簡單的DiffServ 策略,當超過定義值的數據包到來時,其ip頭部中的丟棄字段DSCP會被標記。這樣該ip數據包就會優先被丟棄。
ip數據包:
服務類型:占 8 位,用來獲得更好的服務.這個字段在舊標准中叫做服務類型,但實際上一直沒有被使用過.1998年IETF把這個字段改名為區分服務 DS(Differentiated Services).只有在使用區分服務時,這個字段才起作用.
-
experimenter:
該類型應該是被用於創新實驗使用的,可以自定義超出定義值的數據包處理方式。
len
len字段表示的該band的數據包的長度
rate:
rate字段表示可能作用於數據包的值即限速的值。rate字段的單位是kb每秒,除非在flags字段包含了OFPMF_PKTPS
,這時rate的單位是 packet/s
brust_size:
brust_size
字段只有在flags字段包含了OFPMC_BURST
才會被使用。它主要用於在使用meter表時突發的大量數據包或者字節時。burst的單位是kb,當flags包含OFPMF_PKTPS
時,burst的單位為 packet
meter使用
拓撲創建
使用mininet創建一個最簡單的拓撲,一個控制器,一個交換機,兩個主機。mininet是SDN中網絡仿真器,用來創建控制器、交換機、主機等網絡設備。mn
命令創建一個自帶的控制器,ovs交換機和主機。
iperf
工具是用來測量網絡帶寬的常用命令。
服務端開啟一個監聽 iperf -s
,客戶端連接服務端,測試帶寬iperf -c 10.0.0.1
。默認是TCP連接,可以測試出兩個主機之間的帶寬。
在沒有限速之前測試其速度大小。可以看出其速度是27.5GB/s。測得的速度和機器的性能有關,當前的實驗環境機器是4核 8G SSD固態盤。
設置datapath
設置datapath為用戶態。datapath一般來說是運行在內核態,如果想實現限速功能,就需要將其設置成用戶態。
ovs-vsctl set bridge s1 datapath_type=netdev
ovs-vsctl set bridge s1 protocols=OpenFlow13
下發meter表
下發限速的meter表。名字:s1;速度:5M;動作:丟棄;id:1
ovs-ofctl add-meter s1 meter=1,kbps,band=type=drop,rate=5000 -O OpenFlow13
ovs-ofctl dump-meters s1 -O openflow13
下發流表,並使用meter表
下發轉發的流表。匹配進端口為1,轉發動作為meter:1,output:2
。meter:1
表示匹配到的流表首先交給meter表處理,就是超過5M的數據包丟棄掉,然后在交給output:2
,從2端口轉發出去。
ovs-ofctl add-flow s1 priority=200,in_port=1,action=meter:1,output:2 -O OpenFlow13
ovs-ofctl add-flow s1 priority=200,in_port=2,output:1 -O OpenFlow13
關閉tx校驗
當 datapath_type
設置為 netdev
之后,就是將datapath從內核態轉化到用戶態,這時datapath收到數據包會校驗數據包並且校驗不通過而丟棄數據包。這是很多時候為什么datapath_type=netdev
之后,主機之間能夠ping通,但是不能夠使用iperf
測量帶寬的原因。需要將tx-checksumming
關閉掉。
1、 關閉主機的網卡的tx校驗
root@ljk-VirtualBox:/home/ljk/Desktop# ethtool -K enp0s3 tx off
Cannot get device udp-fragmentation-offload settings: Operation not supported
Cannot get device udp-fragmentation-offload settings: Operation not supported
Actual changes:
tx-checksumming: off
tx-checksum-ip-generic: off
tcp-segmentation-offload: off
tx-tcp-segmentation: off [requested on]
2、 關閉iperf客戶端
的tx校驗
驗證
通過iperf
驗證速度可以得到此時的帶寬為5M。注意在iperf
打流時使用UDP的流測量准確度會高與TCP。
客戶端以10M的速度打流
iperf -u -c 10.0.0.2 -b 10M -i 5 -t 20
服務端接收並驗證。可以看到meter限速是5M,而服務端的速度也接近這個值,說明限速是成功的。
iperf -u -s
多band(計量帶)meter表
前面介紹band時說過一個meter表中可以包含多個band,當一個merer表有多個計量帶時,以小於當前帶寬的最大的rate作為限速的速度,下面測試多個計量帶時限速的表現。
下發多計量帶meter表
設置meter表有多個計量帶,rate=5000,以及rate=12000。就是rate=5M和rate=12M
ovs-ofctl add-meter s1 meter=1,kbps,band=type=drop,rate=5000,rate=12000 -O OpenFlow13
以高於rate的帶寬驗證
客戶端以15M的帶寬打流
服務端接收到的帶寬為12M左右。
15M的帶寬,限速在12M,而不是5M。所以符合多計量帶的限速規則。
以帶寬限速中間范圍值驗證
兩個限速為5M和12M,客戶端以中間值8M帶寬測試
服務端接收到的帶寬為5M左右,限速符合多計量帶規則。
burst_size 瞬時流量
burst 令牌桶原理
在計量帶中有一個參數叫做burst_size
,這個參數為非必填字段,但是從這個字段能夠體現限流的操作的基本原理。burst_size
是令牌桶的容量。所謂令牌桶,原理如下圖:
令牌桶的意義在於:每一個數據包想要被轉發都需要得到一個令牌,而令牌來自於令牌桶。令牌桶以一個速度獲得令牌,該速度就是限速的速度,超過令牌桶容量的令牌會溢出,同時數據包轉發以一定的速度消耗令牌,這就是限速的原理。而burse_size
指的就是令牌桶的容量。
令牌桶的作用是面對突發的大量數據請求可以瞬間消耗令牌桶內的令牌,所以有 burse_size
的效果就是某個大流量到來的瞬間限速的速度等於令牌桶的容量+限速的速度
下發攜帶burst_size參數的meter表
下發meter表,設置 rate=5000
,burst_size=5000
,所以理論上瞬時的限速值為rate
+burst_size
= 10M
ovs-ofctl -O OpenFlow13 add-meter s1 meter=3,kbps,burst,band=type=drop,rate=5000,burst_size=5000
驗證
客戶端以15M的帶寬打流
設置服務端每秒輸出一次帶寬,從顯示可以看出,第1秒中的速度達到10M,然后速度下降穩定在5M左右。
iperf -u -s -i 1
分析:第1s內15M的帶寬的流量到來,瞬間消耗了令牌桶的令牌 5000k ,同時加上穩定下發到令牌桶中的令牌 5000k/s,兩方面加起來就是10M左右,所以第1s帶寬能瞬間達到10M。如果后面帶寬小於限速的5M,令牌桶內的令牌會慢慢積累起來,等待一下次高峰流量的到來。
小結
使用meter表能夠完成很多創新的場景,比如 Qos,差異化服務等,希望通過本篇文章能夠讓學習SDN的童鞋掌握meter表的常規使用,實現更多自己的網絡創新。