Simuler une connexion lente entre deux machines serveurs Ubuntu

9

Je veux simuler le scénario suivant: étant donné que j'ai 4 machines serveurs ubuntu A, B, C et D. Je veux réduire la bande passante du réseau de 20% entre la machine A et la machine C et de 10% entre A et B. faire cela en utilisant des outils de simulation / limitation de réseau?

Yehia Elshater
la source
iptables peut avoir une capacité de limitation. Je ne l'ai jamais utilisé, mais ça vaut le coup d'être étudié.
Michael Martinez
@MichaelMartinez Non, ce n'est pas le cas. tcfait lorsqu'il est utilisé avec le marquage iptables.
Xavier Lucas
@XavierLucas bon à savoir!
Michael Martinez

Réponses:

15

Pour ce faire, vous pouvez utiliser tcseul avec des u32filtres ou combiné avec le marquage iptables (peut-être plus simple si vous ne voulez pas apprendre la syntaxe des filtres complexes). Je vais dans le post suivant détailler l'ancienne solution.


Simuler votre configuration

À titre d'exemple, considérons A, B, C et D exécutant des interfaces virtuelles à 10 Mbit / s .

Vous voulez essentiellement:

  • A <==> B: mise en forme à 9 Mbit / s pour la sortie
  • A <==> C: mise en forme de 8 Mbit / s pour la sortie

Afin de simuler cela, je vais créer 4 espaces de noms réseau et interfaces Ethernet virtuelles connectés à un pont.

Bien sûr, dans votre cas, vous travaillerez avec de vraies cartes réseau et le pont sera votre passerelle ou un commutateur en fonction de votre infrastructure.

Donc, dans ma simulation, nous aurons la configuration suivante, dans un réseau 10.0.0.0/24:

                                  10.0.0.254            

                                  +-------+                     
                                  |       |                     
                                  |  br0  |                     
                                  |       |                   
                                  +---+---+                     
                                      |                         
                                      | veth{A..D}.peer        
                                      |                      
                  +------------+------+-----+------------+     
                  |            |            |            |      
            vethA |      vethB |      vethC |      vethD |      
              +---+---+    +---+---+    +---+---+    +---+---+  
              |       |    |       |    |       |    |       |   
              |   A   |    |   B   |    |   C   |    |   D   |   
              |       |    |       |    |       |    |       |  
              +-------+    +-------+    +-------+    +-------+    

              10.0.0.1      10.0.0.2     10.0.0.3     10.0.0.4           

Tout d'abord, la phase de configuration afin que vous puissiez comprendre de quoi elle est faite, ignorez-la si vous ne la connaissez pas, ce n'est pas grave. Ce que vous devez cependant savoir, c'est que la commande ip netns exec <namespace> <command>permet d'exécuter une commande dans un espace de noms réseau (c'est-à-dire dans l'une des cases du dessin précédent). Cela sera également utilisé dans la section suivante.

# Create the bridge
ip link add br0 type bridge

# Create network namespaces and veth interfaces and plug them into the bridge
for host in {A..D} ; do 
    ip link netns add ${host}
    ip link add veth${host} type veth peer name veth${host}.peer
    ip link set dev veth${host}.peer master br0
    ip link set dev veth${host} netns ${host}
    ip netns exec ${host} ip link set veth${host} up
done

# Assign IPs
ip addr add 10.0.0.254/24 dev br0
ip netns exec A ip addr add 10.0.0.1/24 dev vethA
ip netns exec B ip addr add 10.0.0.2/24 dev vethB
ip netns exec C ip addr add 10.0.0.3/24 dev vethC
ip netns exec D ip addr add 10.0.0.4/24 dev vethD

Donc, à ce stade, nous avons la configuration décrite précédemment.


Façonner le trafic

Il est temps d'entrer dans le contrôle du trafic afin d'obtenir ce que vous voulez. L' tcoutil vous permet d'ajouter des disciplines de mise en file d'attente:

  • Pour la sortie: une fois que le noyau doit envoyer des paquets et avant d'accéder au pilote NIC.
  • Pour l'entrée: après avoir accédé au pilote NIC et avant que les routines du noyau ne soient exécutées sur les paquets reçus.

Il est livré avec 3 notions: qdisc , classes et filtres . Ces notions peuvent être utilisées pour configurer une gestion complexe du flux de paquets et hiérarchiser le trafic en fonction du ou des critères que vous souhaitez.

En un mot :

  • Les Qdisc sont des structures où les paquets seront finalement mis en file d'attente / retirés de la file d'attente.
  • Les classes sont des conteneurs pour les qdisc agissant avec des comportements spécifiques.
  • Les filtres sont des moyens d'acheminer les paquets entre les classes, plusieurs d'entre eux peuvent être définis sur le même point d'entrée avec des priorités pendant le traitement.

Tout cela fonctionne généralement comme un arbre où les feuilles sont des disques qd et les classes sont des nœuds. La racine d'un arbre ou d'un sous-arbre sera déclarée comme <id>:et les nœuds enfants seront déclarés comme <parent_id>:<children_id>. Gardez cette syntaxe à l'esprit.

Pour votre cas, prenons A et rendons l'arbre avec lequel vous souhaitez configurer tc:

                                     1:
                                      |
                                      |
                                      |
                                     1:1
                                   /  |  \
                                  /   |   \
                                 /    |    \
                               1:10  1:20  1:30
                                |     |     |
                                |     |     |
                               :10   :20   :30

Explication:

  • 1:est le qdisc racine attaché au périphérique vethA, il sera pris explicitement comme htbpour le compartiment de jetons de hiérarchie (le qdisc par défaut d'un périphérique est pfifoou pfifo_fastdépend du système d'exploitation). Il est particulièrement approprié pour la gestion de la bande passante. Les paquets qui ne correspondent pas aux filtres définis à ce niveau iront en 1:30classe.
  • 1:1sera une htbclasse limitant l'ensemble du trafic de l'appareil à 10 Mbit / s.
  • 1:10sera une htbclasse limitant le trafic de sortie à 9 Mbit / s (90% de 10 Mbit / s).
  • 1:20sera une htbclasse limitant le trafic de sortie à 8 Mbit / s (80% de 10 Mbit / s).
  • 1:30sera une htbclasse limitant le trafic à 10 Mbit / s (repli).
  • :10, :20, :30sont sfqqdisc pour la mise en file d'attente d'équité stochastique. En d'autres termes, ces qdiscs garantiront l'équité de la planification de la transmission en fonction des flux.

Tout cela est configuré par les commandes suivantes:

ip netns exec A tc qdisc add dev vethA root handle 1: htb default 30
ip netns exec A tc class add dev vethA parent 1: classid 1:1 htb rate 10mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:10 htb rate 9mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:20 htb rate 8mbit burst 15k
ip netns exec A tc class add dev vethA parent 1:1 classid 1:30 htb rate 10mbit burst 15k
ip netns exec A tc qdsic add dev vethA parent 1:10 handle 10: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:20 handle 20: sfq perturb 10
ip netns exec A tc qdisc add dev vethA parent 1:30 handle 30: sfq perturb 10

La dernière chose dont nous avons besoin est d'ajouter des filtres pour que les paquets IP avec IP de destination égal à B iront en 1:10classe et les paquets IP avec IP de destination égal à C iront en 1:20classe:

ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 1 u32 match ip dst 10.0.0.2/32 flowid 1:10
ip netns exec A tc filter add dev vethA parent 1: protocol ip prio 2 u32 match ip dst 10.0.0.3/32 flowid 1:20

Maintenant que vous avez l'idée, vous devrez ajouter des tcrègles similaires à B et C afin que les transmissions vers A de ces plates-formes soient également façonnées.


Essai

Maintenant, testons-le. Pour cela, je suis personnellement habitué à jouer avec iperf, il se compose simplement d'un seul binaire qui peut être exécuté en tant que client ou serveur et enverra automatiquement autant de trafic que possible entre les deux hôtes.

Entre A et B :

 $ ip netns exec B iperf -s -p 8001
  ...
 $ ip netns exec A iperf -c 10.0.0.2 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.2, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58191 connected with 10.0.0.2 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  2.0- 4.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  4.0- 6.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  6.0- 8.0 sec  2.12 MBytes  8.91 Mbits/sec
[  5]  8.0-10.0 sec  2.00 MBytes  8.39 Mbits/sec
[  5]  0.0-10.1 sec  10.8 MBytes  8.91 Mbits/sec

Nous obtenons notre limite de bande passante de 9 Mbit / s .

Entre A et C:

$ ip netns exec C iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.3 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.3, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 58522 connected with 10.0.0.3 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  2.0- 4.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  4.0- 6.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  6.0- 8.0 sec  1.88 MBytes  7.86 Mbits/sec
[  5]  8.0-10.0 sec  1.75 MBytes  7.34 Mbits/sec
[  5]  0.0-10.1 sec  9.62 MBytes  7.98 Mbits/sec

Nous obtenons notre limite de bande passante de 8 Mbit / s .

Entre A et D:

$ ip netns exec D iperf -s -p 8001
...
$ ip netns exec A iperf -c 10.0.0.4 -p 8001 -t 10 -i 2
------------------------------------------------------------
Client connecting to 10.0.0.4, TCP port 8001
TCP window size: 21.0 KByte (default)
------------------------------------------------------------
[  5] local 10.0.0.1 port 40614 connected with 10.0.0.4 port 8001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0- 2.0 sec  2.62 MBytes  11.0 Mbits/sec
[  5]  2.0- 4.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  4.0- 6.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  6.0- 8.0 sec  2.25 MBytes  9.44 Mbits/sec
[  5]  8.0-10.0 sec  2.38 MBytes  9.96 Mbits/sec
[  5]  0.0-10.2 sec  12.0 MBytes  9.89 Mbits/sec

Nous avons ici l'interface virtuelle pleine vitesse de 10 Mbit / s atteinte.

Notez que la rafale de la première mesure de chaque exécution peut être mieux gérée dans les htbclasses en ajustant le paramètre adéquat.


Nettoyer

Ôter :

  • Le filtre de priorité 1 sur 1:: tc filter del dev vethA parent 1: prio 1 u32.
  • Tous les filtres 1:: tc filter del dev vethA parent 1:.
  • Classe 1:20et ses enfants: tc class del dev vethA parent 1:1 classid 1:20.
  • L'arbre entier: tc qdisc del dev vethA.

Pour nettoyer l'ensemble de simulation:

# Remove veth pairs and network namespaces
for host in {A..D} ; do
    ip link del dev veth${host}.peer
    ip netns del ${host}
done

# Remove the bridge
ip link del dev br0
Xavier Lucas
la source
1
Merci beaucoup pour votre réponse incroyable. Si possible, pourriez-vous ajouter les commandes pour supprimer les filtres? juste au cas où quelqu'un voudrait annuler cette configuration en toute sécurité après la simulation.
Yehia Elshater
1
@YahiaZakaria Je viens d'ajouter ces informations dans la dernière partie de mon message.
Xavier Lucas
0

Ubuntu a IPFW porté depuis FreeBSD, et IPFW a DUMMYNET qui permet de gérer divers paramètres de réseau - bande passante, retard, taux de perte de paquets, etc.

Kondybas
la source
0

Le mieux est d'utiliser les outils tc avec le module netem maintenant intégré (dans le serveur Ubuntu au moins). Vous pouvez trouver plus d'informations dans cet article de Stackoverflow .

Luc Stepniewski
la source
Netem concerne l'émulation rtt et la congestion, pas la bande passante.
Xavier Lucas
1
@XavierLucas, vous avez raison, pour la bande passante, vous avez juste besoin de tc, sans même netem.
Luc Stepniewski
0

Trickle fonctionne bien.

Cette discussion montre quelques limitations: /unix/109973/how-to-change-speed-limit-of-running-trickle-instance

Mathew
la source
Trickle est utilisé pour simuler la bande passante du réseau pour un programme spécifique. Le PO semble chercher une solution à la portée de l'hôte.
Xavier Lucas
Trickled peut être utilisé pour simuler un groupe de connexions (pas seulement une seule connexion). En effet, la question pourrait être interprétée comme "toutes les connexions d'hôte à hôte".
Mathew