Difference between revisions of "Traffic shaping with tc"

From OpenVZ Virtuozzo Containers Wiki
Jump to: navigation, search
m (Reverted edits by 77.121.217.121 (Talk) to last revision by Kir)
(hYaKOcJVWzNGfWBE)
Line 1: Line 1:
Sometimes it's necessary to limit traffic bandwidth from and to a [[container]].
+
I was really confused, and this answered all my qeustonis.
You can do it using ordinary <code>tc</code> tool.
 
 
 
== Packet routes ==
 
First of all, a few words about how packets travel from and to a [[container]].
 
Suppose we have [[Hardware Node]] (HN) with a container (CT) on it, and this
 
container talks to some Remote Host (RH). HN has one "real" network interface
 
<tt>eth0</tt> and,
 
thanks to OpenVZ, there is also "virtual" network interface <tt>venet0</tt>.
 
Inside the container we have interface <tt>venet0:0</tt>.
 
 
 
<pre>
 
    venet0:0              venet0    eth0
 
CT >------------->-------------> HN >--------->--------> RH
 
 
 
    venet0:0              venet0    eth0
 
CT <-------------<-------------< HN <---------<--------< RH
 
</pre>
 
 
 
== Limiting outgoing bandwidth ==
 
We can limit container outgoing bandwidth by setting the <tt>tc</tt> filter on <tt>eth0</tt>.
 
<pre>
 
DEV=eth0
 
tc qdisc del dev $DEV root
 
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit
 
tc class add dev $DEV parent 1: classid 1:1 cbq rate 256kbit allot 1500 prio 5 bounded isolated
 
tc filter add dev $DEV parent 1: protocol ip prio 16 u32 match ip src X.X.X.X flowid 1:1
 
tc qdisc add dev $DEV parent 1:1 sfq perturb 10
 
</pre>
 
X.X.X.X is an IP address of container.
 
 
 
== Limiting incoming bandwidth ==
 
This can be done by setting the <code>tc</code> filter on <code>venet0</code>:
 
<pre>
 
DEV=venet0
 
tc qdisc del dev $DEV root
 
tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 100mbit
 
tc class add dev $DEV parent 1: classid 1:1 cbq rate 256kbit allot 1500 prio 5 bounded isolated
 
tc filter add dev $DEV parent 1: protocol ip prio 16 u32 match ip dst X.X.X.X flowid 1:1
 
tc qdisc add dev $DEV parent 1:1 sfq perturb 10
 
</pre>
 
Note that <code>X.X.X.X</code> is an IP address of container.
 
 
 
== Limiting CT to HN talks ==
 
As you can see, two filters above don't limit [[container]] to [[HN]] talks.
 
I mean a [[container]] can emit as much traffic as it wishes. To make such a limitation from the [[HN]],
 
it is necessary to use <tt>tc</tt> police on <tt>venet0</tt>:
 
<pre>
 
DEV=venet0
 
tc filter add dev $DEV parent 1: protocol ip prio 20 u32 match u32 1 0x0000 police rate 2kbit buffer 10k drop flowid :1
 
</pre>
 
 
 
== Limiting packets per second rate from container ==
 
To prevent dos atacks from the container you can limit packets per second rate using iptables.
 
<source lang="bash">
 
DEV=eth0
 
iptables -I FORWARD 1 -o $DEV -s X.X.X.X -m limit --limit 200/sec -j ACCEPT
 
iptables -I FORWARD 2 -o $DEV -s X.X.X.X -j DROP
 
</source>
 
Here <code>X.X.X.X</code> is an IP address of container.
 
 
 
== An alternate approch using HTB ==
 
 
 
For details refer to the [http://luxik.cdi.cz/~devik/qos/htb/ HTB Home Page]
 
 
 
<source lang="bash">
 
#!/bin/sh
 
#
 
# Incoming traffic control
 
#
 
CT_IP1=$1
 
CT_IP2=$2
 
DEV=venet0
 
#
 
tc qdisc del dev $DEV root
 
#
 
tc qdisc add dev $DEV root handle 1: htb default 10
 
#
 
tc class add dev $DEV parent 1: classid 1:1 htb rate 100mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:20 htb rate 20mbit ceil 20mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:30 htb rate 30mbit ceil 30mbit burst 15k
 
#
 
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
 
tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
 
tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10
 
#
 
if [ ! -z $CT_IP1 ]; then
 
    tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip dst "$CT_IP1" flowid 1:20
 
fi
 
if [ ! -z $CT_IP2 ]; then
 
    tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip dst "$CT_IP2" flowid 1:30
 
fi
 
#
 
echo;echo "tc configuration for $DEV:"
 
tc qdisc show dev $DEV
 
tc class show dev $DEV
 
tc filter show dev $DEV
 
#
 
# Outgoing traffic control
 
#
 
DEV=eth0
 
#
 
tc qdisc del dev $DEV root
 
#
 
tc qdisc add dev $DEV root handle 1: htb default 10
 
#
 
tc class add dev $DEV parent 1: classid 1:1 htb rate 100mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:20 htb rate 20mbit ceil 20mbit burst 15k
 
tc class add dev $DEV parent 1:1 classid 1:30 htb rate 30mbit ceil 30mbit burst 15k
 
#
 
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10
 
tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
 
tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10
 
#
 
if [ ! -z $CT_IP1 ]; then
 
    tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip src "$CT_IP1" flowid 1:20
 
fi
 
if [ ! -z $CT_IP2 ]; then
 
    tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip src "$CT_IP2" flowid 1:30
 
fi
 
#
 
echo;echo "tc configuration for $DEV:"
 
tc qdisc show dev $DEV
 
tc class show dev $DEV
 
tc filter show dev $DEV
 
</source>
 
 
 
== External links ==
 
* [http://lartc.org/howto/ Linux Advanced Routing & Traffic Control HOWTO]
 
 
 
[[Category: HOWTO]]
 
[[Category: Networking]]
 

Revision as of 04:09, 28 November 2011

I was really confused, and this answered all my qeustonis.