Comprender tc qdisc e iperf

15

Estoy tratando de limitar el ancho de banda tcy verificar los resultados con iperf. Empecé así:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35213 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   830 MBytes   696 Mbits/sec

Las dos instancias están conectadas directamente a través de Ethernet.

Luego configuré una htb qdisccon una clase predeterminada para limitar el ancho de banda a 1mbit / seg:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit

Pero no obtengo lo que espero:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35217 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-12.8 sec   768 KBytes   491 Kbits/sec

Si duplico la velocidad, el ancho de banda medido no cambia. ¿Qué me estoy perdiendo? ¿Por qué el ancho de banda medido no corresponde al 1mbit del rateparámetro? ¿Qué parámetros debo establecer para limitar el ancho de banda a una velocidad determinada?

Sin embargo, la manpágina dice que tbfdebería ser la qdiscelección para esta tarea:

El Token Bucket Filter es adecuado para ralentizar el tráfico a una velocidad configurada con precisión. Escala bien a grandes anchos de banda.

tbfrequiere parámetros rate, bursty ( limit| latency). Así que probé lo siguiente sin comprender cómo bursty ( limit| latency) afectan el ancho de banda disponible:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k

Esto me dio un ancho de banda medido de 113 Kbits / seg. Jugar con esos parámetros no cambió mucho hasta que noté que agregar un valor para los mtucambios cambia drásticamente:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k mtu 5000

resultó en un ancho de banda medido de 1.00 Mbits / seg.

¿Qué parámetros necesitaría establecer para limitar el ancho de banda a una tasa dada exacta?

¿Debo usar la disciplina htbo tbfhacer cola para esto?

EDITAR :

Con base en estos recursos, he realizado algunas pruebas:

He intentado las siguientes configuraciones.

En una máquina física

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
bridge_ports eth0

Medida con iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.4 port 51804 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Mientras que el iperfservidor calculó un ancho de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.4 port 51804
[  4]  0.0-13.7 sec  1.62 MBytes   993 Kbits/sec

En una máquina virtual sin vinculación

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

Medida con iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 34347 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.3 sec  1.62 MBytes  1.21 Mbits/sec

Mientras que el iperfservidor calculó un ancho de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.7 port 34347
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

En una máquina virtual con enlace (tc configurado en eth0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Medida con iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49054 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Mientras que el iperfservidor calculó un ancho de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49054
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

En una máquina virtual con enlace (tc configurado en bond0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Medida con iperf:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49055 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-13.3 sec   768 KBytes   475 Kbits/sec

Mientras que el iperfservidor calculó un ancho de banda diferente:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49055
[  4]  0.0-14.1 sec   768 KBytes   446 Kbits/sec

El resultado no cambia si elimino eth1(la interfaz pasiva) del enlace.

Conclusión

El control de tráfico en una interfaz de enlace no funciona, o al menos no como se esperaba. Tendré que investigar más a fondo.

Como solución alternativa, se podrían agregar las disciplinas de colas directamente a las interfaces que pertenecen al enlace.

Matías E. Fernández
fuente
Por extraño que parezca, esto parece haber funcionado para este tipo: blog.tinola.com/?e=22
Matías E. Fernández
1
Creo que con htb, tienes que usar tc filterpara poner los paquetes en clases. También es posible que deba cambiar algunos de los parámetros de htb (sintonícelo como tbf). Sugiero investigar tcng, que es un front-end para tc. (Estos son consejos rápidos ...)
derobert
No vi ningún filtro en tu publicación. ¿Qué comandos está utilizando para hacer coincidir el tráfico para que pueda limitarse la velocidad?

Respuestas:

2

Cuando no está seguro de cómo funciona tc, ¿aún puede monitorear tc y observar cómo fluyen los paquetes? Puede usar mi script para monitorear tc y necesita ejecutarlo en una terminal con privilegios elevados. Puede cambiar wlan0 a otra interfaz y también necesita grep y awk:

      #!/bin/sh
      INTERVAL=15
      while sleep $INTERVAL
      do
             /usr/sbin/tc -s -d class show dev wlan0

             uptime
             more /proc/meminfo | grep MemFree | grep -v grep
             echo cache-name num-active-objs total-objs obj-size
             SKBUFF=`more /proc/slabinfo | grep skbuff | grep -v grep | awk 
             '{print $2} {print $3} {print $4}'`

             echo skbuff_head_cache: $SKBUFF
      done
Gigamegs
fuente
0

Intenta aumentar los valores burst/ limit. El cubo de fichas algoritmos del escalan bien, pero tienen una relación precisión / velocidad limitada.

La precisión se logra mediante el uso de un cubo pequeño, la velocidad al aumentar el tamaño de las fichas. Los tokens grandes significan que disminuye la velocidad a la que se reponen (tokens por segundo = bytes por segundo / bytes por token).

El rateparámetro da la tasa promedio que no se debe exceder, los parámetros bursto limitdan el tamaño de la ventana de promedio. Como el envío de un paquete a la velocidad de la línea excede la velocidad establecida para el tiempo en que se transfiere el paquete, la ventana de promedio debe ser al menos lo suficientemente grande como para que el envío de un solo paquete no supere el límite; Si caben más paquetes en la ventana, el algoritmo tendrá una mejor oportunidad de alcanzar el objetivo exactamente.

Simon Richter
fuente
0

ejecute esto antes de agregar disciplina de cola en la interfaz de enlace (bond0 en este caso)

ipconfig bond0 txqueuelen 1000

no funciona porque el dispositivo virtual de software como la interfaz de enlace no tiene una cola predeterminada.

Ventilador
fuente
0

Como los bonddispositivos no tienen una cola definida, establecer el qdisctamaño explícitamente me soluciona el problema.

Aquí hay un ejemplo para que una hoja qdiscse use bajo HTBestructura: tc qdisc add dev $dev parent $parent handle $handle pfifo limit 1000

SagiLow
fuente