12 Settembre 2022

Automatizza i test di rete con questo strumento Linux open source

Usa iperf3 per risolvere i problemi di larghezza di banda, tempi, protocollo e altri problemi sulla tua rete TCP/IP.

iperf 3

La rete TCP/IP è un argomento complesso e diventa davvero complicato quando si tenta di definire problemi con le prestazioni o risolvere un problema. Aiuta a disporre di strumenti in grado di sondare il tuo sistema e confermare i tuoi sospetti o, meglio ancora, che non ci sono problemi.

Uno di questi strumenti è l’open source iperf3. Ecco la sua descrizione da GitHub:

iperf è uno strumento per la misura attiva della larghezza di banda massima raggiungibile su reti IP. Supporta l’ottimizzazione di vari parametri relativi a tempi, protocolli e buffer. Ciascun test riporta il throughput/bitrate misurato, la perdita e altri parametri.

Questo articolo mostra come:

  • Esamina i problemi di larghezza di banda tra due endpoint con iperf 3
  • Testare la connettività multicast UDP (User Datagram Protocol) (utilizzato da Precision Time Protocol e altri protocolli per la sincronizzazione dell’ora)
  • Scopri gli errori del controllo di ridondanza ciclica (CRC) su un’interfaccia di rete
  • Usa ethtool e tcpdump per confermare che un’interfaccia di rete o un cavo difettosi interrompono il traffico
  • Scrivi script più complessi usando Python 3

Spiegherò anche brevemente l’affinità della CPU e perché potrebbe essere importante per iperf3.

Inizia con iperf3

Per seguire questo tutorial, avrai bisogno di:

  • Una distribuzione Linux (ho eseguito i miei esempi su un server Fedora)
  • La possibilità di eseguire comandi come root (usando sudo , per esempio)
  • Una comprensione di base dei principi di rete

Esegui il comando per installare iperf3. Su Fedora:

$ sudo dnf install -y iperf3

Iperf3 funziona eseguendo un client e un server che dialogano tra loro. Ecco alcuni termini da conoscere prima di iniziare a usarlo:

  • Il throughput  misura quanti pacchetti arrivano alle destinazioni con successo.
  • La larghezza di banda  di rete è la massima capacità di trasferimento dati di una rete.
  • Il jitter  è il ritardo di tempo tra quando un segnale viene trasmesso e quando viene ricevuto. Le buone connessioni hanno un tempo di risposta costante.
  • TCP  sta per Transmission Control Protocol . È un protocollo affidabile che garantisce l’arrivo dei pacchetti nello stesso ordine in cui sono stati inviati tramite una stretta di mano .
  • UDP  non ha un protocollo di handshake come TCP. È più veloce di TCP, ma se un pacchetto viene perso, non verrà rispedito e non vi è alcuna garanzia che i pacchetti arrivino nell’ordine inviato.

iperf3

Nella dimostrazione in questo articolo:

  • Il client e il server si collegano all’interfaccia Ethernet cablata. (Non userò le interfacce wireless perché sono più soggette a jitter a causa del rumore esterno.)
  • Il mio test utilizza le impostazioni predefinite (porta, connessione TCP a meno che non venga sovrascritta con il flag --udpsul client).

La dimostrazione conferma se:

  • Lo switch tra le due macchine supporta connessioni a 1.000 Mbit/sec e le interfacce sono state configurate a tale capacità.
  • La modalità full-duplex è abilitata per inviare e ricevere dati sulla scheda contemporaneamente. Lo confermerai più avanti nell’articolo con un altro strumento chiamato ethtool.

Senza ulteriori indugi, inizierò.

Misura la larghezza di banda e il jitter

Ecco i comandi iniziali sul server:

[server ~]$ sudo ethtool eth0|rg -e 'Speed|Duplex'
 Speed: 1000Mb/s
 Duplex: Full

[server ~]$ ip --oneline address|rg 192
2: eth0    inet 192.168.1.11/24 brd 192.168.1.255 scope global dynamic eth0\       valid_lft 2090sec preferred_lft 2090sec

[server ~]$ iperf3 --server --bind 192.168.1.11 -affinity 1
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

E ora il client:

[client ~]$ sudo ethtool eno1|rg -e 'Speed|Duplex'
 Speed: 1000Mb/s
 Duplex: Full

[client ~]$ iperf3 --client raspberrypi --bind 192.168.1.28 --affinity 1
Connecting to host raspberrypi, port 5201
[  5] local 192.168.1.28 port 47609 connected to 192.168.1.11 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   111 MBytes   932 Mbits/sec    0   2.79 MBytes       
[  5]   1.00-2.00   sec   110 MBytes   923 Mbits/sec    0   2.98 MBytes       
...     
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  1021 MBytes   857 Mbits/sec    0             sender
[  5]   0.00-9.95   sec  1020 MBytes   860 Mbits/sec                  receiver

iperf Done.

Analizzo i risultati:

  • Zero tentativi (colonna Retr). Questo è buono e previsto.
  • Il bitrate è di circa 860 Mbit/sec. La velocità del collegamento è vicina alla larghezza di banda teorica. Gli switch hanno un limite alla quantità di traffico che il backplane può gestire.
  • Il TCP garantisce perdite di trasmissione dei pacchetti, quindi il jitter non viene riportato qui.

Se inverti il test (il client è ora il server), dovresti vedere risultati simili.

Testare la larghezza di banda UDP

Per testare UDP, eseguire le seguenti operazioni solo sul client:

[client ~]$ iperf3 --client raspberrypi --bind 192.168.1.28 --udp --affinity 1
Connecting to host raspberrypi, port 5201
[  5] local 192.168.1.28 port 47985 connected to 192.168.1.11 port 5201
[ ID] Interval           Transfer     Bitrate         Total Datagrams
[  5]   0.00-1.00   sec   129 KBytes  1.05 Mbits/sec  91  
[  5]   1.00-2.00   sec   127 KBytes  1.04 Mbits/sec  90  
[  5]   2.00-3.00   sec   129 KBytes  1.05 Mbits/sec  91  
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-10.00  sec  1.25 MBytes  1.05 Mbits/sec  0.000 ms  0/906 (0%)  sender
[  5]   0.00-9.99   sec  1.25 MBytes  1.05 Mbits/sec  0.028 ms  0/906 (0%)  receiver

Ecco i risultati:

  • Il bitrate è molto più vicino alla larghezza di banda teorica. Inoltre, non c’è perdita di pacchetti, il che è fantastico.
  • UDP non garantisce la perdita di pacchetti, quindi vengono segnalati datagrammi e jitter persi (e hanno buoni valori).

Potresti chiederti cosa sia quella --affinitybandiera. Non è davvero necessario qui per testare la larghezza di banda su questo semplice esempio, ma mi dà una scusa per parlare di affinità.

Deviazione veloce: affinità CPU, NUMA, isolcpus

Se eri curioso e hai controllato la documentazione e gli esempi di iperf, probabilmente hai visto riferimenti all’affinità della CPU o del processore .

Quindi, cos’è? Da Wikipedia:

L’affinità del processore, o blocco della CPU o “affinità della cache”, consente l’associazione e l’annullamento dell’associazione di un processo o di un thread a un’unità di elaborazione centrale (CPU) o a un intervallo di CPU, in modo che il processo o il thread venga eseguito solo sulla CPU designata o CPU anziché qualsiasi CPU.

Perché vorresti aggiungere un processo a un gruppo specifico di CPU?

Nessuna istanza con CPU bloccate può utilizzare le CPU di un’altra istanza bloccata, impedendo così la contesa di risorse tra le istanze. L’accesso alla memoria non uniforme (NUMA) consente a più CPU di condividere le cache L1, L2 e L3 e la memoria principale.

Puoi utilizzare l’hardware NUMA per assicurarti di utilizzare sempre la memoria più vicina alla CPU.

Che aspetto ha un server con diversi nodi NUMA? Puoi scoprirlo con lscpu| rg NUMA:

[client ~]$ lscpu|rg NUMA
NUMA node(s):                    2
NUMA node0 CPU(s):               0-7
NUMA node1 CPU(s):               8-15

Questo è un server a 16 CPU con due nodi NUMA (questo è un esempio semplificato, una macchina con HyperThreading abilitato ha un aspetto diverso. A seconda dell’applicazione, potresti decidere di disabilitarlo.

Ricorda che puoi utilizzare l’affinità della CPU non solo per aumentare le prestazioni di rete ma anche le prestazioni del disco.

Tornando a iperf3, puoi aggiungerlo a una CPU specifica usando -A--affinity. Ad esempio, la CPU 3 (numerata da 0 a n-1) si presenta così:

# Equivalent of running iperf3 with numactl: /bin/numactl --physcpubind=2 iperf3 -c remotehost
iperf3 --affinity 2 --client remotehost

Ricorda che potresti anche dover dire al sistema operativo di evitare di eseguire processi host su queste CPU, quindi se usi Grubby, puoi farlo con isolcpus :

# Find the default kernel
$ sudo grubby --default-kernel

# Use that information and add isolcpus parameter, then reboot
$ sudo grubby --update-kernel=/boot/vmlinuz-5.14.18-100.fc33.x86_64 --args="isolcpus=2"
sudo shutdown -r now 'Updated kernel isolcpus, need to reboot'

Ancora una volta, questo non è necessario per risolvere un problema di rete, ma può tornare utile se vuoi fare in modo che iperf3 si comporti come una delle tue applicazioni ottimizzate.

L’ottimizzazione è un argomento complesso, quindi prendi una tazza di caffè (o due) e preparati a iniziare a leggere.

Usa iperf3 per rilevare i pacchetti persi e gli errori CRC

Un errore CRC è causato da un dispositivo fisico difettoso (scheda di rete, porta dello switch, cavo) o da una mancata corrispondenza nelle configurazioni full e half duplex tra due dispositivi. Questi a volte sono difficili da tracciare sugli switch con modalità cut-through, in cui lo switch inoltra gli errori ricevuti a tutte le porte.

Questo è uno scenario semplificato per garantire che una nuova connessione della scheda di rete funzioni senza CRC o errori ricevuti/trasmessi (Rx/Tx) (il che significa che la scheda, il cavo e la porta dello switch sono OK).

Con questo in mente, potresti fare un semplice test per assicurarti che lo stato del collegamento sia buono:

  • Acquisisci lo stato del CRC e gli errori di pacchetti eliminati sulla scheda di rete in fase di test.
  • Esegui iperf3 in modalità TCP per un tempo più lungo del solito.
  • Recupera le statistiche CRC della scheda di rete.

Se la differenza è maggiore di zero, allora:

  1. Controllare la modalità full-duplex sia sulla scheda che sulla porta dello switch (ethtool).
  2. Sostituire il cavo.
  3. Riposizionare o sostituire la scheda di rete.
  4. Cambia la porta sullo switch.

Ottieni l’immagine; iperf3 aiuterà a “bruciare” il collegamento e ad attivare qualsiasi comportamento indesiderato prima di utilizzare questa interfaccia in produzione.

Ecco il processo in azione. Supponiamo di fare la prima istantanea sul server iperf3:

[server ~]$ sudo ethtool --statistics  eth0| rg -i -e 'dropped|error'
     rx_errors: 0
     tx_errors: 0
     rx_dropped: 0
     tx_dropped: 0
     rxq0_errors: 0
     rxq0_dropped: 0
     rxq1_errors: 0
     rxq1_dropped: 0
     rxq2_errors: 0
     rxq2_dropped: 0
     rxq3_errors: 0
     rxq3_dropped: 0
     rxq16_errors: 0
     rxq16_dropped: 0

Quindi il cliente:

[client ~]$ sudo ethtool --statistics  eno1| rg -i -e 'dropped|errors'
     tx_errors: 0
     rx_errors: 0
     align_errors: 0

Esegui il iperf3server:

[server ~]$ iperf3 --server --bind 192.168.1.11
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

Esegui iperf3sul client per 120 secondi:

[client ~]$ iperf3 --client raspberrypi --bind 192.168.1.28 --time 120 
Connecting to host raspberrypi, port 5201
[  5] local 192.168.1.28 port 41337 connected to 192.168.1.11 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   111 MBytes   934 Mbits/sec    0   2.94 MBytes       
[  5]   1.00-2.00   sec   111 MBytes   933 Mbits/sec    0   2.95 MBytes       
[  5]   2.00-3.00   sec   111 MBytes   933 Mbits/sec    0   2.95 MBytes       
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-120.00 sec  11.0 GBytes   787 Mbits/sec    0             sender
[  5]   0.00-119.70 sec  11.0 GBytes   789 Mbits/sec                  receiver

# Measure again ...
[client ~]$ sudo ethtool --statistics  eno1| rg -i -e 'dropped|errors'
     tx_errors: 0
     rx_errors: 0
     align_errors: 0

Ora parlerò di un altro strumento utile per ottenere le statistiche dell’interfaccia di rete, ethtool.

Cos’è ethtool?

Come spiega Wikipedia :

ethtool è il mezzo principale nei sistemi operativi basati su kernel Linux (principalmente Linux e Android) per visualizzare e modificare i parametri dei controller di interfaccia di rete (NIC) e il software del driver di dispositivo associato dai programmi applicativi in esecuzione nello spazio utente.

Ecco un paio di domande per te dopo aver finito di controllare la pagina man di ethtool :

  1. Cosa fa il sudo ethtool -g eno1comando?
  2. E questo?sudo ethtool -s eno1 speed 1000 duplex full autoneg on

L’utilità ethtool è un altro strumento che dovresti avere nel tuo set di strumenti.

Automatizza iperf3 con Python 3

Potresti notare che iperf3 ha una libreria che ti permette di integrare lo strumento con altri linguaggi, incluso Python:

[client ~]$ rpm -qil iperf3|rg libiperf
/usr/lib64/libiperf.so.0
/usr/lib64/libiperf.so.0.0.0
/usr/share/man/man3/libiperf.3.gz

Sono disponibili diversi collegamenti per Python:

  • iperf3-python ha un’API per integrare iperf3 con Python, usando quei collegamenti.
  • Il modulo Python ethtool  è disponibile ma contrassegnato come deprecato, ma lo userò per ciò di cui ha bisogno questa dimostrazione.

Non tratterò qui l’API, ma piuttosto ti indirizzerò al codice sorgente di uno script Python che utilizza iperf3 ed ethtool per rilevare errori di rete (come ho fatto manualmente sopra). Puoi vederlo in esecuzione di seguito. Controlla il repository ed esegui lo script. Rimarrai stupito di quanto sia facile automatizzare alcune attività con Python.

Cosa puoi fare dopo?

L’apprendimento non si ferma mai, quindi ecco alcuni suggerimenti e osservazioni per farti andare avanti:

  • Fasterdata ha più esempi di utilizzo di iperf con parametri diversi.
  • Tieni presente che isolcpus è considerato deprecato e cpuset è consigliato. Fare riferimento a questa discussione sull’overflow dello stack per vedere come giocare con cpuset.
  • Ora sai come scrivere i tuoi script di risoluzione dei problemi con l’API Python iperf3. Probabilmente dovresti scrivere un server iperf3 che possa mostrare i risultati usando un browser web (magari combinarlo con FastAPI ?).

 

Hai dei dubbi? Non sai da dove iniziare? Contattaci !

Abbiamo tutte le risposte alle tue domande per aiutarti nella giusta scelta.

Chatta con noi

Chatta direttamente con il nostro supporto prevendita.

0256569681

Contattaci telefonicamente negli orari d’ufficio 9:30 – 19:30

Contattaci online

Apri una richiesta direttamente nell’area dei contatti.

INFORMAZIONI

Managed Server S.r.l. è un player italiano di riferimento nel fornire soluzioni avanzate di sistemistica GNU/Linux orientate all’alta performance. Con un modello di sottoscrizione dai costi contenuti e prevedibili, ci assicuriamo che i nostri clienti abbiano accesso a tecnologie avanzate nel campo dell’hosting, server dedicati e servizi cloud. Oltre a questo, offriamo consulenza sistemistica su sistemi Linux e manutenzione specializzata in DBMS, IT Security, Cloud e molto altro. Ci distinguiamo per l’expertise in hosting di primari CMS Open Source come WordPress, WooCommerce, Drupal, Prestashop, Joomla, OpenCart e Magento, affiancato da un servizio di supporto e consulenza di alto livello adatto per la Pubblica Amministrazione, PMI, ed aziende di qualsiasi dimensione.

Red Hat, Inc. detiene i diritti su Red Hat®, RHEL®, RedHat Linux®, e CentOS®; AlmaLinux™ è un marchio di AlmaLinux OS Foundation; Rocky Linux® è un marchio registrato di Rocky Linux Foundation; SUSE® è un marchio registrato di SUSE LLC; Canonical Ltd. detiene i diritti su Ubuntu®; Software in the Public Interest, Inc. detiene i diritti su Debian®; Linus Torvalds detiene i diritti su Linux®; FreeBSD® è un marchio registrato di The FreeBSD Foundation; NetBSD® è un marchio registrato di The NetBSD Foundation; OpenBSD® è un marchio registrato di Theo de Raadt. Oracle Corporation detiene i diritti su Oracle®, MySQL®, e MyRocks®; Percona® è un marchio registrato di Percona LLC; MariaDB® è un marchio registrato di MariaDB Corporation Ab; REDIS® è un marchio registrato di Redis Labs Ltd. F5 Networks, Inc. detiene i diritti su NGINX® e NGINX Plus®; Varnish® è un marchio registrato di Varnish Software AB. Adobe Inc. detiene i diritti su Magento®; PrestaShop® è un marchio registrato di PrestaShop SA; OpenCart® è un marchio registrato di OpenCart Limited. Automattic Inc. detiene i diritti su WordPress®, WooCommerce®, e JetPack®; Open Source Matters, Inc. detiene i diritti su Joomla®; Dries Buytaert detiene i diritti su Drupal®. Amazon Web Services, Inc. detiene i diritti su AWS®; Google LLC detiene i diritti su Google Cloud™ e Chrome™; Microsoft Corporation detiene i diritti su Microsoft®, Azure®, e Internet Explorer®; Mozilla Foundation detiene i diritti su Firefox®. Apache® è un marchio registrato di The Apache Software Foundation; PHP® è un marchio registrato del PHP Group. CloudFlare® è un marchio registrato di Cloudflare, Inc.; NETSCOUT® è un marchio registrato di NETSCOUT Systems Inc.; ElasticSearch®, LogStash®, e Kibana® sono marchi registrati di Elastic N.V. Hetzner Online GmbH detiene i diritti su Hetzner®; OVHcloud è un marchio registrato di OVH Groupe SAS; cPanel®, L.L.C. detiene i diritti su cPanel®; Plesk® è un marchio registrato di Plesk International GmbH; Facebook, Inc. detiene i diritti su Facebook®. Questo sito non è affiliato, sponsorizzato o altrimenti associato a nessuna delle entità sopra menzionate e non rappresenta nessuna di queste entità in alcun modo. Tutti i diritti sui marchi e sui nomi di prodotto menzionati sono di proprietà dei rispettivi detentori di copyright. Ogni altro marchio citato appartiene ai propri registranti. MANAGED SERVER® è un marchio registrato a livello europeo da MANAGED SERVER SRL, Via Enzo Ferrari, 9, 62012 Civitanova Marche (MC), Italia.

Torna in alto