Catégories
Open-source Planet-libre Systeme

Des outils de test pour stresser votre système

Le développement logiciel nécessite des phases de test et de validation qui sont souvent menées sur des machines non chargées. Je vous propose donc de découvrir, dans ce billet, une série de petits logiciels permettant de simuler une charge sur votre système et qu’il faudra donc lancer en parallèle de vos applications à valider. J’ai uniquement sélectionné des logiciels libres, légers, en ligne de commande et disponible dans les dépôts Ubuntu standards.

Comment stresser une machine ?

Plusieurs leviers permettent de « stresser » une machine:

  • consommation CPU
  • utilisation de la mémoire MEM
  • entrée/sortie IO
  • lecture/écriture disque DISK
  • entrée/sortie réseau NET

L’utilisation conjointe de ces leviers permet de simuler une charge sur une machine cible. L’amplitude des paramètres appliquées à ces leviers est bien sûr à adapter à votre configuration hardware et système.

Note: l’utilisation des logiciels décrits si-dessous peut entraîner le plantage pure et simple de votre machine (cela m’est arrivé pendant mes tests…). Je vous conseille donc vivement de ne pas les appliquer sur une machine en production…

Fuzz

Le premier logiciel est Fuzz. Contrairement aux autres solutions, ce dernier ne génère pas de « stress » par lui même mais demande à d’autres programmes de le faire.

Ainsi, la ligne de commande suivante:

fuzz grep foo

va lancer 10.000 fois la commande « grep foo » en lui donnant en entrée des données factices. Ainsi votre machine va chercher la chaîne de caractère foo dans un flot de données. Nous pouvons donc voir, grâce à Glances (un peu de pub…),  que la charge CPU (recherche de sous-chaine) et IO (entrée-sortie disque) augmentent.

Le nombre d’exécution (-r par défaut 10.000) et le time-out (-t par défaut 120 secondes) sont bien-sur paramétrable en ligne de commande (voir le man).

Si vous connaissez les applications qui tourneront en parallèle de la votre, il est facile de simuler votre environnement cible. Il manque par contre un peu de finesse pour tester votre application avec des contraintes pré-définies (par exemple avec une charge CPU de 75%).

Spew

Développé par HP et mis à disposition de la communauté, Spew est spécialisé sur le stress par entrée-sortie disque. Il permet d’écrire et/ou de lire des fichiers de test sur votre disque.

Pour générer un fichier de 5 Go nommé /tmp/bibi:

$ spew 5G /tmp/bibi
WTR:    90320.56 KiB/s   Transfer time: 00:00:58    IOPS:   180641.12

La même commande mais en forçant la relecture du fichier à la fin de l’écriture:

$ spew --read-after-write 5G /tmp/titi
WTR:    74740.25 KiB/s   Transfer time: 00:01:10    IOPS:   149480.49
RTR:  1761227.45 KiB/s   Transfer time: 00:00:02    IOPS:  3522454.90
On peut voir une montée en charge globale de la machine (LOAD) mais juste avec des entrées/sorties (IO):

Note: pensez à supprimer vos fichiers de test (/tmp/bibi)…

Stress et StressAppTest

Deux logiciels qui font fonctionnellement la même chose (jouer sur l’ensemble des leviers permettant de stresser une machine) mais de manière différente…

Stress est une application permettant de générer des processus (worker) ayant des caractéristiques communes:

  • CPU (consommation de la CPU grâce à l’exécution de la commande sqrt)
  • MEM (avec exécution des commandes malloc et free)
  • IO (avec execution de la commande sync)
  • DISK (execuiyon des commandes read et write)

Avec la commande suivante:

stress -m 10 --vm-bytes 512000000 -t 30

On se retrouve donc avec 10 processus consommant chacun 512 Mo:

Contrairement à Stress, StressAppTest ne génère par défaut qu’un seul processus qui va regrouper les caractéristiques de stress souhaitées.

Ainsi, la commande:

$ stressapptest -s 30 -M 256 -m 8 -C 8 -W

Log: Commandline - stressapptest -s 30 -M 256 -m 8 -C 8 -W
Stats: SAT revision 1.0.3_autoconf, 64 bit binary
Log: buildd @ allspice on Wed Jan 11 17:38:51 UTC 2012 from open source release
Log: 1 nodes, 4 cpus.
Log: Prefer plain malloc memory allocation.
Log: Using memaligned allocation at 0x7f9e9f157000.
Stats: Starting SAT, 256M, 30 seconds
Log: Region mask: 0x1
Log: Seconds remaining: 20
Log: Seconds remaining: 10
Stats: Found 0 hardware incidents
Stats: Completed: 458960.00M in 31.10s 14756.72MB/s, with 0 hardware incidents, 0 errors
Stats: Memory Copy: 458960.00M at 15298.83MB/s
Stats: File Copy: 0.00M at 0.00MB/s
Stats: Net Copy: 0.00M at 0.00MB/s
Stats: Data Check: 0.00M at 0.00MB/s
Stats: Invert Data: 0.00M at 0.00MB/s
Stats: Disk: 0.00M at 0.00MB/s
Status: PASS - please verify no corrected errors

Donne:

Je vous invite à consulter la documentation officielle du projet pour y découvrir les nombreuses options.

Pour finir…

Cette liste est très loin d’être exhaustive. L’idée étant de partager votre savoir…

Quel logiciel utilisez vous pour faire vos test de performances sur des machines chargées ?

Avez-vous des solutions multi-plateforme ?

A vos claviers 🙂

Catégories
Open-source Planet-libre Reseau

Simuler un réseau WAN entre deux réseaux LAN

A partir de sa version 2.6, le noyau Linux dispose d’une fonction permettant de simuler certaines caractéristiques comme un délais de transit, une perte de paquets ou même un débit maximal sur une simple interface réseau locale. J’avais déjà parlé de ce sujet il y a quelques temps pour simuler une liaison WAN entre une machine et son réseau. Suite à une question d’un lecteur, voici un billet dans lequel nous allons mettre en place un simulateur de liaison WAN entre deux réseaux LAN. Cette infrastructure pourra être utile à toutes personnes devant valider sur table une architecture inter-site.

De quoi avons nous besoin ?

Pour bâtir cette infrastructure, nous avons besoins de deux réseaux LAN (mais deux PC peuvent suffirent) et d’une machine GNU/Linux disposant de deux interfaces réseaux permettant de faire un pont entre ces deux LAN. Le choix d’une architecture en pont (bridgé) permet d’insérer facilement le simulateur dans une architecture réseau existante.

 

Configuration du bridge

Personnellement, j’ai utilisé une distribution GNU/Linux Debian Squeeze pour mettre en place le simulateur. Mais toutes les distributions GNU/Linux avec une version de Kernel >= 2.6 peuvent faire l’affaire.

Après une installation standard du système d’exploitation Debian, il faut ajouter le paquet bridge-utils pour permettre à ce dernier de créer le pont entre les deux interfaces réseaux:

sudo aptitude install bridge-utils

Il faut ensuite éditer le fichier de configuration /etc/network/interfaces de la manière suivante:

auto lo

iface lo inet loopback

iface eth0 inet manual

iface eth1 inet manual

auto br0

iface br0 inet dhcp

bridge_ports eth0 eth1

Puis on fait prendre en compte cette configuration par le système:

sudo /etc/init.d/networking restart

Note: il faut attendre une trentaine de seconde lors de l’initialisation.

On vient donc de créer une nouvelle interface virtuelle (br0) qui fait un pont entre les deux interfaces physiques (eth0 et eth1).

Si vous connectez en l’état le simulateur entre vos deux LAN, tout le trafic transitera de manière transparente à la vitesse maximale de vos interfaces eth0 et eth1.

Configuration du simulateur

On passe maintenant à la partie intéressante de ce billet: comment simuler un lien WAN à partir de notre simulateur.

Vous allez voir que c’est relativement simple. Nous allons utiliser un script de configuration automatique qui va activer / désactiver le simulateur à la demande. Les caractéristiques du WAN à simuler seront codées en dur dans la section configuration du script. A vous de l’adapter à vos besoins.

Voici le script en question (également disponible sur mon GitHub):

#!/bin/bash
#
# simulwan-bridge.sh
# Nicolargo - 2012
#

##############################################################################

# Nom des interfaces ou l'on doit faire les simulations
# eth0 cote LAN local 
# eth1 cote LAN distant
IF=eth1

# Liaison sortante (UPLOAD) a appliquer sur IF
# Debit sortant
BWU=8mbit
# Délai de transit sortant
DELAYU=15ms
# % de paquets perdus sortant
LOSSU=0.0001%

# Liaison entrante (DOWNLOAD) a appliquer sur IF
# Debit entrant
BWD=1mbit
# Délai de transit entrant
DELAYD=15ms
# % de paquets perdus entrant
LOSSD=0.00001%

##############################################################################

start() {
    modprobe ifb
    ip link set dev ifb0 up

    tc qdisc add dev $IF ingress

    tc filter add dev $IF parent ffff: \
    protocol ip u32 match u32 0 0 flowid 1:1 \
    action mirred egress redirect dev ifb0

    # Liaison entrante
    tc qdisc add dev ifb0 root handle 1:0 \
    netem delay $DELAYD 10ms distribution normal \
    loss $LOSSD 25%

    tc qdisc add dev ifb0 parent 1:1 handle 10: \
    tbf rate $BWD buffer 3200 limit 6000

    # Liaison sortante
    tc qdisc add dev $IF root handle 2:0 \
    netem delay $DELAYU 10ms distribution normal \
    loss $LOSSU 25%

    tc qdisc add dev $IF parent 2:1 handle 10: \
    tbf rate $BWU buffer 3200 limit 6000
}

stop() {
    tc qdisc del dev ifb0 root
    tc qdisc del dev $IF root
    # ip link set dev ifb0 down
}

restart() {
    stop
    sleep 1
    start
}

show() {
    echo "Liaison entrante"
    tc -s qdisc ls dev ifb0
    echo "Liaison sortante"
    tc -s qdisc ls dev $IF
}

case "$1" in
    start)
        echo -n "Starting WAN simul: "
        start
        echo "done"
        ;;
    stop)
        echo -n "Stopping WAN simul: "
        stop
        echo "done"
        ;;
    restart)
        echo -n "Restarting WAN simul: "
        restart
        echo "done"
        ;;
    show)
        echo "WAN simul status for $IF:"
        show
        echo ""
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|show}"
        ;;
esac

exit 0

Par défaut, le script simule une liaison WAN de type ADSL (8 Mbps en download et 1 Mbps en upload avec un délais de transit de 30ms en aller/retour et un taux de perte de 10^-4).

Pour l’installer, il suffit de saisir les commandes suivantes:

sudo wget -O /etc/init.d/simulwan.sh https://raw.github.com/nicolargo/simulwan/master/simulwan-bridge.sh
sudo chmod a+x /etc/init.d/simulwan.sh

Pour lancer le simulateur WAN:

sudo /etc/init.d/simulwan.sh start

Pour arrêter le simulateur WAN:

sudo /etc/init.d/simulwan.sh stop

Pour avoir un état des interfaces:

sudo /etc/init.d/simulwan.sh show

Conclusion

Vous venez donc à moindre coût de mettre en place une architecture permettant de simuler des liaisons WAN. Le PC sur lequel se base votre simulateur n’a pas besoin d’être une bête de course et vous pouvez donc facilement récupérer du vieux matériel pour mettre en place ce système.

 

 

 

Catégories
Open-source Reseau

Simuler un lien WAN sous Linux

Il peut être utile, dans le cadre de tests applicatifs, de simuler sur votre réseau local (LAN), les caractéristiques d’une liaison distante (WAN). En effet, vos applications peuvent très bien fonctionner sur un réseau LAN et devenir inexploitable sur des liaisons WAN.

Nous allons utiliser le module Net:Netem des noyaux Linux 2.6 pour simuler les caractéristiques suivantes:

  • Bande passante
  • Délai de transit
  • Perte de paquet
  • Duplication de paquet
  • Re-arrangement de paquet

La configuration de ce module se fait via la commande en ligne tc.

Simuler un délai de transit constant

Le délai est le temps de transit réseau d’un paquet IP. Il dépend de pas mal de paramètres (traversé des équipements, taille des buffers et distance physique entre les deux points du réseau). Nous allons utiliser la commande delay qui va simuler un délai de transit de X ms sur tout les paquets IP sortant de l’interface réseau. On va utiliser la commande « ping » pour vérifier que tout fonctionne comme prévu.

Test du réseau avant la commande tc:

$ ping 192.168.29.1
PING 192.168.29.1 (192.168.29.1) 56(84) bytes of data.
64 bytes from 192.168.29.1: icmp_seq=1 ttl=64 time=0.290 ms
64 bytes from 192.168.29.1: icmp_seq=2 ttl=64 time=0.204 ms

On simule un délai de 40 ms sur tout les paquets sortant (soit environ le délais sur une liaison ADSL):

sudo tc qdisc add dev eth0 root netem delay 40ms

Test du réseau après la commande tc:

$ ping 192.168.29.1
PING 192.168.29.1 (192.168.29.1) 56(84) bytes of data.
64 bytes from 192.168.29.1: icmp_seq=1 ttl=64 time=40 ms
64 bytes from 192.168.29.1: icmp_seq=2 ttl=64 time=40 ms

Pour revenir à la configuration initiale (sans simulateur), on utilise la commande suivante:

sudo tc qdisc del dev eth0 root

On vérifie que l’on retombe bien sur les caractéristiques normale du réseau:

$ ping 192.168.29.1
PING 192.168.29.1 (192.168.29.1) 56(84) bytes of data.
64 bytes from 192.168.29.1: icmp_seq=1 ttl=64 time=0.218 ms
64 bytes from 192.168.29.1: icmp_seq=2 ttl=64 time=0.209 ms

Simuler un délai de transit « normal »

Sur un réseau WAN, le délai de transit n’est jamais constant à travers le temps (surtout pour des liaisons de type Internet). Nous allons donc modifier la commande précédente pour intégrer une variation de délai (gigue de +/- 10ms) sur les paquets sortant:

sudo tc qdisc add dev eth0 root netem delay 40ms 10ms distribution normal

On obtient les caractéristiques suivantes:

$ ping 192.168.29.1PING 192.168.29.1 (192.168.29.1) 56(84) bytes of data.
64 bytes from 192.168.29.1: icmp_seq=1 ttl=64 time=36.9 ms
64 bytes from 192.168.29.1: icmp_seq=2 ttl=64 time=50.5 ms
64 bytes from 192.168.29.1: icmp_seq=3 ttl=64 time=33.1 ms
64 bytes from 192.168.29.1: icmp_seq=4 ttl=64 time=43.1 ms
64 bytes from 192.168.29.1: icmp_seq=5 ttl=64 time=32.5 ms
64 bytes from 192.168.29.1: icmp_seq=6 ttl=64 time=23.6 ms

Pour revenir à la configuration initiale (sans simulateur), on utilise la commande suivante:

sudo tc qdisc del dev eth0 root

Simuler une bande passante limite

Cette fonction ne fait pas partie de Netem mais utilise tout de même la commande tc pour se configurer.

Avant de commencer nous allons tester la capacité de notre réseau LAN avec la commande IPerf (à lancer en mode serveur UDP sur votre machine cible, 192.168.29.1 dans mon cas):

$ iperf -c 192.168.29.1 -u -b 10M
————————————————————
Client connecting to 192.168.29.1, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size:   110 KByte (default)
————————————————————
[  3] local 192.168.29.222 port 47532 connected with 192.168.29.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  11.9 MBytes  10.0 Mbits/sec
[  3] Sent 8505 datagrams
[  3] Server Report:
[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
[  3]  0.0-10.0 sec  11.9 MBytes  10.0 Mbits/sec 0.008 ms    0/ 8505 (0%)

On a donc bien un débit de 10 Mbps.

On commence par créer la racine de l’arbre des classes (avec une simulation de délai « normal » de 40ms):

sudo tc qdisc add dev eth0 root handle 1:0 netem delay 40ms 10ms distribution normal

Puis on y ajoute un « tuyau » limitant le trafic sortant à 512 Kbps:

sudo tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 512kbit buffer 3200 limit 6000

On re-teste notre réseau:

$ iperf -c 192.168.29.1 -u -b 10M
————————————————————
Client connecting to 192.168.29.1, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size:   110 KByte (default)
————————————————————
[  3] local 192.168.29.222 port 57589 connected with 192.168.29.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  11.9 MBytes  10.0 Mbits/sec
[  3] Sent 8505 datagrams
[  3] Server Report:
[ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
[  3]  0.0-10.3 sec    609 KBytes    486 Kbits/sec 14.351 ms 8081/ 8505 (95%)

On arrive bien à limiter le débit réseau sortant à 500 Kbps (un peu moins pour mon test).

Pour revenir à la configuration initiale (sans simulateur), on utilise la commande suivante:

sudo tc qdisc del dev eth0 root

Simuler une perte de paquets

La perte de paquets (ou « packet loss » dans la langue de Shakespeare) peut être simulé par Netem par la commande loss. Dans l’exemple suivant, nous allons simuler un lien WAN avec une perte de 0.1% des paquets sortant (soit 1 paquet perdu sur 1000 envoyé) avec un corrélation de 25% sur la probabilité que 2 paquets soit perdu de suite.

sudo tc qdisc add dev eth0 root netem loss 0.1% 25%

Pour revenir à la configuration initiale (sans simulateur), on utilise la commande suivante:

sudo tc qdisc del dev eth0 root

Simuler d’autres paramètres réseau

Il est également possible de simuler la duplication de paquets (commande duplicate), la corruption de paquets (commande corrupt) et le re-arrangement des paquets (commande gap).

Simuler également les paquets entrants

Imaginons que l’on veuille simuler une liaison de type ADSL, cette liaison est asymétrique en terme de débit. Il faut donc pouvoir simuler de manière différente le débit entrant (DOWNLOAD) du débit sortant (UPLOAD). Pour cela, il faut passer par la déclaration d’une interface réseau virtuelle (ifb) dans laquelle nous allons re-router les paquets entrants. Nous appliquerons nos paramètres réseau de simulation sur cette nouvelle interface.

Commençons par créer cette interface virtuelle:

# modprobe ifb
# ip link set dev ifb0 up
# tc qdisc add dev eth0 ingress
# tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

Puis appliquons un délai de 40ms comme vu dans le chapitre précédant:

# tc qdisc add dev ifb0 root netem delay 40ms 10ms distribution normal

Un exemple complet: simulation d’une liaison ADSL

Voici un script Shell (bash) permettant de mettre en place une simulation de type liaison ADSL sur votre réseau local:

#!/bin/bash
#
# limitbw.sh
# Nicolargo – 2009
#

# Nom de l’interface ou l’on doit faire la simulation
IF=eth0

# Liaison sortante (UPLOAD)

# Debit sortant
BWU=768kbit
# Délai de transit sortant
DELAYU=20ms
# % de paquets perdus sortant
LOSSU=0.01%

# Liaison entrante (DOWNLOAD)

# Debit entrant
BWD=2mbit
# Délai de transit entrant
DELAYD=20ms
# % de paquets perdus entrant
LOSSD=0.01%

start() {

# Liaison entrante

modprobe ifb
ip link set dev ifb0 up
tc qdisc add dev $IF ingress
tc filter add dev $IF parent ffff: \
protocol ip u32 match u32 0 0 flowid 1:1 \
action mirred egress redirect dev ifb0

tc qdisc add dev ifb0 root handle 1:0 \
netem delay $DELAYD 10ms distribution normal \
loss $LOSSD 25%
tc qdisc add dev ifb0 parent 1:1 handle 10: \
tbf rate $BWD buffer 3200 limit 6000

# Liaison sortante

tc qdisc add dev $IF root handle 2:0 \
netem delay $DELAYU 10ms distribution normal \
loss $LOSSU 25%
tc qdisc add dev $IF parent 2:1 handle 10: \
tbf rate $BWU buffer 3200 limit 6000

}

stop() {

tc qdisc del dev ifb0 root

tc qdisc del dev $IF root

# ip link set dev ifb0 down

}

restart() {

stop
sleep 1
start

}

show() {

echo « Liaison entrante »

tc -s qdisc ls dev ifb0

echo « Liaison sortante »

tc -s qdisc ls dev $IF

}

case « $1 » in

start)

echo -n « Starting WAN simul:  »
start
echo « done »
;;

stop)

echo -n « Stopping WAN simul:  »
stop
echo « done »
;;

restart)

echo -n « Restarting WAN simul:  »
restart
echo « done »
;;

show)

echo « WAN simul status for $IF: »
show
echo «  »
;;

*)

echo « Usage: $0 {start|stop|restart|show} »
;;

esac

exit 0

Bonne simulation 😉