9.16 详解 Neutron 的 QoS

QoS 的全称是 Quality of Service,也就是服务质量。

Neutron 支持的 QoS 类型有

  • bandwidth_limit(带宽限速):实现带宽速速

  • DSCP(差分服务代码点):给网络流量包添加一个 DSCP 标记,以此实现流量的优先级

  • minimum_bandwidth:暂时没用过

1. 开户 QoS 支持

在控制节点上执行两条命令修改配置

$ openstack-config --set /etc/neutron/neutron.conf DEFAULT service_plugins neutron.services.qos.qos_plugin.QoSPlugin

$ openstack-config --set /etc/neutron/plugins/ml2/ml2_conf.ini ml2 extension_drivers port_security,qos

然后重启 neutron-server

$ crm resource cleanup openstack-neutron-server-clone

在计算节点上执行命令修改配置

$ openstack-config --set /etc/neutron/plugins/ml2/openvswitch_agent.ini agent extensions qos

然后重启对应的 neutron-agent 服务

$ systemctl restart neutron-openvswitch-agent

DSCP 差分服务代码点

DSCP 大小为 6 个 bit,也就是最大可表示 64 个分类。

但在 Neutron 里可用的标记只有这些

0, 8, 10, 12, 14, 16, 18, 20,
22, 24, 26, 28, 30, 32, 34, 36,
38, 40, 46, 48, 56

可以看到,它们都是0-56 间的偶数,但是排除 2-6, 42, 44 和 50-54。

image0

原理

在 IP 协议分组里有一个 ToS(服务类型) 的字段,就是用来表示 ToS 的。

ToS 字段,总共 8 个 bit

image1

前面 3 个 bit

为优选权子字段,现在已经废弃,这个字段默认值是000,从wireshark抓包结果看,表示的是:

003::每天五分钟入门TCP/IP协议栈::IP协议之TOS字段说明

003::每天五分钟入门TCP/IP协议栈::IP协议之TOS字段说明

但是在某些协议中仍然是有用的,比如 OSPFv2 协议

image2

关于 Precedence (优先级),有如下几种

111 - Network Control
110 - Internetwork Control
101 - CRITIC/ECP
100 - Flash Override
011 - Flash
010 - Immediate
001 - Priority
000 – Routine

中间 4 个bit

这四个 bit 组合在一起,表示了该数据报对应的服务类别,这个应用层的服务类别是不同的。这里所说的服务类别,是指:

1000 -- minimize delay          最小延迟
0100 -- maximize throughput     最大吞吐量
0010 -- maximize reliability    最高可靠性
0001 -- minimize monetary cost  最小费用
0000 -- normal service          一般服务

IP首部中的ToS字段,只能表示一种服务类别,也就是:这4bit字段中,最多只能有一个bit字段为1。

看下不同应用下该4bit字段对应的值: 003::每天五分钟入门TCP/IP协议栈::IP协议之TOS字段说明 翻译过来就是: 003::每天五分钟入门TCP/IP协议栈::IP协议之TOS字段说明 最小延迟,对应于对延迟敏感的应用,如telnet和人login等。 最大吞吐量,对应于对吞吐量要求比较高的应用,如FTP文件应用,对文件传输吞吐量有比较高的要求。 最高可靠性,对网络传输可靠性要求高的应用,如使用SNMP的应用、路由协议等等。 最小费用,如NNTP这种用户网络新闻等。

最后 1 个bit

这个1bit末尾,没有被使用,必须强制设置为0

最后,很重要的一点,只有当网络设备(如交换机等)能够支持(能够识别IP首部中的ToS字段)识别ToS字段时,这给字段设置才有意义。

创建 policy

$ neutron qos-policy-create qos-dscp --shared
Created a new policy:
+-----------------+--------------------------------------+
| Field           | Value                                |
+-----------------+--------------------------------------+
| created_at      | 2020-07-01T06:43:23Z                 |
| description     |                                      |
| id              | ee7e7a83-c67d-4f27-b77c-3345553e5abe |
| name            | qos-dscp                             |
| project_id      | 2ac17c7c792d45eaa764c30bac37fad9     |
| revision_number | 1                                    |
| rules           |                                      |
| shared          | True                                 |
| tenant_id       | 2ac17c7c792d45eaa764c30bac37fad9     |
| updated_at      | 2020-07-01T06:43:23Z                 |
+-----------------+--------------------------------------+

创建 rule

创建时需要指定 QOS_POLICY,创建完后,就会自动添加到 QOS_POLICY

$ neutron  qos-dscp-marking-rule-create --dscp-mark 14 ee7e7a83-c67d-4f27-b77c-3345553e5abe
Created a new dscp_marking_rule:
+-----------+--------------------------------------+
| Field     | Value                                |
+-----------+--------------------------------------+
| dscp_mark | 14                                   |
| id        | 1d045cf3-eb31-440b-9a74-a9d5fea6a7e0 |
+-----------+--------------------------------------+

绑定policy到 port

$ neutron port-update <port_id> --qos-policy qos-dscp

关闭 QoS

$ neutron port-update <port_id> --no-qos-policy

查看规则

过滤出 tos 后就能看到 ToS(Type of Service) 的值

$ ovs-ofctl dump-flows br-int | grep tos

然后再对照这个表,找到对应的 DSCP 的 decimal ,如果 tos 是 64,那么 DSCP mark 就是 16,其实除以 4 就可以了,也不用对照表。其中这个 16 需要跟交换上支持的一样。

image5

其他

DSCP 是以集群为粒度,一个集群只要创建一个就行,需要的时候将其绑定到 port 上就可以。

2. bandwidth_limit 带宽限速

华云 QoS :https://support.huawei.com/enterprise/zh/doc/EDOC1100055155/101c0e7b

http://blog.chinaunix.net/uid-20530497-id-2490382.html

https://www.zhihu.com/question/21053403

qos 查询命令

$ neutron qos-policy-list
$ neutron qos-bandwidth-limit-rule-list 16fbb0c2-b7ac-4053-a85f-75fb72c3ab55

在 dpdk 宿主机上查询限速

# 查询 ingress(宿主机角度)
$ virsh dumpxml 4f6a0708-aeb8-4208-bea8-2c51e6a94948

# 查询 egress(虚拟机角度)
$ ovs-vsctl list interface vhu198063e9-97

# 查询 ingress(虚拟机角度)
$ ovs-appctl -t ovs-vswitchd qos/show vhu198063e9-97

image6