Simula una connessione lenta tra due macchine server Ubuntu


9

Voglio simulare il seguente scenario: dato che ho 4 macchine server Ubuntu A, B, C e D. Voglio ridurre la larghezza di banda della rete del 20% tra la macchina A e la macchina C e il 10% tra A e B. Come farlo utilizzando strumenti di simulazione / limitazione della rete?


iptables potrebbe avere capacità di limitazione. Non l'ho mai usato, ma vale la pena esaminarlo.
Michael Martinez,

@MichaelMartinez No, non lo è. tcfa quando viene utilizzato con la marcatura iptables.
Xavier Lucas,

@XavierLucas buono a sapersi!
Michael Martinez,

Risposte:


15

Per fare ciò puoi utilizzare da tcsolo con i u32filtri o in combinazione con il segno iptables (forse più semplice se non vuoi imparare la sintassi dei filtri complessi). Nel prossimo post descriverò in dettaglio la soluzione precedente.


Simulazione della configurazione

Ad esempio, consideriamo A, B, C e D con interfacce virtuali a 10 Mbit / s .

In pratica vuoi:

  • A <==> B: modellazione 9 Mbit / s per uscita
  • A <==> C: 8 Mbit / s per modellare l'uscita

Per simularlo creerò 4 spazi dei nomi di rete e interfacce Ethernet virtuali collegate a un bridge.

Ovviamente, nel tuo caso lavorerai con NIC reali e il bridge sarà il tuo gateway o uno switch a seconda della tua infrastruttura.

Quindi nella mia simulazione avremo la seguente configurazione, in una rete 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           

Innanzitutto, la fase di installazione è in modo da poter capire di cosa è fatta, saltarla se non si ha familiarità con essa, non è un grosso problema. Quello che devi sapere, tuttavia, è che il comando ip netns exec <namespace> <command>consente di eseguire un comando in uno spazio dei nomi di rete (ovvero in una delle caselle del disegno precedente). Questo sarà usato anche nella prossima sezione.

# 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

Quindi a questo punto abbiamo la configurazione descritta in precedenza.


Dare forma al traffico

È tempo di prendere il controllo del traffico per ottenere quello che vuoi. Lo tcstrumento consente di aggiungere discipline di accodamento:

  • Per uscita: una volta che il kernel ha bisogno di inviare pacchetti e prima di accedere al driver NIC.
  • Per l'ingresso: dopo aver effettuato l'accesso al driver della scheda di rete e prima che le routine del kernel vengano eseguite sui pacchetti ricevuti.

Viene fornito con 3 nozioni: qdisc , classi e filtri . Queste nozioni possono essere utilizzate per impostare una complessa gestione del flusso di pacchetti e dare priorità al traffico in base a qualsiasi criterio / criterio desideri.

In breve:

  • I Qdisc sono strutture in cui i pacchetti verranno accodati / accodati per via endovenosa.
  • Le classi sono contenitori per qdisc che agiscono con comportamenti specifici.
  • I filtri sono modi per instradare i pacchetti tra le classi, molti di essi possono essere definiti sullo stesso punto di ingresso con priorità durante l'elaborazione.

Tutti questi di solito funzionano come un albero in cui le foglie sono qdisc e le classi sono nodi. La radice di un albero o sottostruttura sarà dichiarata come <id>:e i nodi figli saranno dichiarati come <parent_id>:<children_id>. Tieni presente questa sintassi.

Per il tuo caso, prendiamo A e rendiamo l'albero con il quale desideri impostare tc:

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

Spiegazione :

  • 1:è il qdisc radice collegato al dispositivo vethA, verrà preso esplicitamente come htbper la gerarchia token bucket (il qdisc predefinito di un dispositivo è pfifoo pfifo_fastdipende dal sistema operativo). È specificamente appropriato per la gestione della bandwith. I pacchetti non corrispondenti ai filtri definiti a questo livello andranno in 1:30classe.
  • 1:1sarà una htbclasse che limita l'intero traffico del dispositivo a 10 Mbit / s.
  • 1:10sarà una htbclasse che limita il traffico in uscita a 9 Mbit / s (90% di 10 Mbit / s).
  • 1:20sarà una htbclasse che limita il traffico in uscita a 8 Mbit / s (80% di 10 Mbit / s).
  • 1:30sarà una htbclasse che limita il traffico a 10 Mbit / s (fallback).
  • :10, :20, :30 siamo sfq qdisc per Accodamento equità stocastica. In altre parole, questi qdisc assicureranno l'equità nella programmazione della trasmissione basata sui flussi.

L'intera cosa è impostata dai seguenti comandi:

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

L'ultima cosa di cui abbiamo bisogno è aggiungere filtri in modo che i pacchetti IP con IP di destinazione uguale a B passino alla 1:10classe e i pacchetti IP con IP di destinazione uguale a C andranno alla 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

Ora che hai avuto l'idea, dovrai aggiungere tcregole simili a B e C in modo che anche le trasmissioni verso A da questi rig siano modellate.


analisi

Ora proviamo. Per questo sono personalmente abituato a giocareiperf , consiste semplicemente in un singolo binario che può essere eseguito come client o come server e invierà automaticamente il maggior traffico possibile tra entrambi gli host.

Tra A e 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

Otteniamo i nostri 9 Mbit / s limite di banda .

Tra A e 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

Otteniamo il nostro limite di banda 8 Mbit / s .

Tra A e 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

Qui abbiamo raggiunto la velocità massima dell'interfaccia virtuale di 10 Mbit / s .

Si noti che il burst della prima misura di ogni corsa può essere gestito meglio in htbclassi regolando il parametro adeguato.


Pulire

Rimuovere :

  • Il filtro di priorità 1 1:: tc filter del dev vethA parent 1: prio 1 u32.
  • Tutti i filtri su 1:: tc filter del dev vethA parent 1:.
  • Classe 1:20ed i suoi figli: tc class del dev vethA parent 1:1 classid 1:20.
  • L'intero albero: tc qdisc del dev vethA.

Per ripulire il set di simulazione:

# 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

1
Grazie mille per la tua straordinaria risposta. Se possibile, potresti aggiungere i comandi per rimuovere i filtri? nel caso in cui qualcuno desideri ripristinare questa configurazione in modo sicuro dopo la simulazione.
Yehia Elshater,

1
@YahiaZakaria Ho appena aggiunto queste informazioni nell'ultima parte del mio post.
Xavier Lucas il

0

Ubuntu ha IPFW portato da FreeBSD e IPFW ha DUMMYNET che consente di gestire vari parametri di rete: larghezza di banda, ritardo, tasso di perdita di pacchetti, ecc.



0

Il trucco funziona bene.

Questa discussione mostra alcune limitazioni: /unix/109973/how-to-change-speed-limit-of-running-trickle-instance


Trickle viene utilizzato per simulare la banda di rete con un programma specifico. L'OP sembra cercare una soluzione nell'ambito dell'host.
Xavier Lucas,

Trickled può essere utilizzato per simulare un gruppo di connessioni (non solo una singola connessione). In effetti la domanda potrebbe essere interpretata come "tutte le connessioni host-to-host".
Mathew il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.