Linux 限制用户网络带宽
目录

方案:cgroup + TC,前者负责对用户数据包打标签,后者负责对指定标签的数据包做网络IO限制。

network packages -> cgroup/iptables (label) -> tc(class) -> tc(queue)

TC

TC 是Linux内核中控制网络流量的工具,详细的说明请查看man手册或详细中文手册第9章。这里只简单使用一下。

TC基本思想是Linux内核首先把需要发送的数据包交给TC队列,由TC进行排队,然后内核再从TC队列中取出,通过网卡驱动发送出去。 TC有三个核心概念:

  • qdisc(queueing discipline) 规则队列:可以是树形
  • class 类别:附属于一个qdisc
  • filiter 过滤器:映射指定标签的数据包到qdisc

qdisc和class的命名方式以: major number : minor number,qdisc占用major,class占用minor。

简单的实验:针对网卡eth1,对cgroup标记的数据包做速度限制。 首先eth1上清空之前的qdics,然后新建major number为10的qdisc。

tc qdisc del dev eth1 root
tc qdisc add dev eth1 root handle 10: htb

在qdics增加一个分类,设置其带宽为400Mbit。 创建过滤器,使用cgroup做标签。

tc class add dev eth1 parent 10: classid 10:1 htb rate 400mbit
tc filter add dev eth1 parent 10: protocol ip prio 10 handle 1: cgroup

以后如果修改带宽限制,可以设置:

tc class change dev eth1 parent 10: classid 10:1 htb rate 200mbit

cgroup

首先CentOS6下安装cgroup:

# yum install libcgroup

cgroup可以动态配置,也可以写入到配置文件里。 这里我直接写在配置文件里。 cgroup有两个配置文件:

  • cgconfig.conf:定义group和mount。
  • cgrules.conf:用户或组到group的映射

cgroup管理网络资源的类型叫net_cls。 我们首先增加一个net_cls的组。 上一节我们TC建立的classid为10:1,这个id在cgroup里以 0xAAAABBBB方式表示,其中AAAA是major number, BBBB是minor number。 因此我们首先执行:

cgcreate -g net_cls:test_bw
echo 0x100001 > /cgroup/net_cls/test_bw/net_cls.classid

然后把生成的配置直接覆盖到配置文件:

cgsnapshot -s > /etc/cgconfig.conf

我的内容如下:

mount {
cpuset  = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory  = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio   = /cgroup/blkio;
}

group test_bw {
net_cls {
net_cls.classid="1048577";
}
}

然后把需要限制带宽的用户(或组)加入到这个cgroup组中,在 /etc/cgrules.conf中添加一行:

jack   net_cls   test_bw/

这样jack就加入到这个组中。 重启服务:

service cgconfig restart
service cgred restart

这样应该就生效了。

限制Daemon带宽

比如想限制nfs服务器的带宽,只需把nfsddeamon加入到rules里:

*:nfsd    net_cls   test_bw/

然后重启cgred即可。

参考

发表评论