Traduzioni: English - Italiano


Bonding

Questo articolo mostra come unire due connessioni Ethernet assieme per creare una interfaccia "auto failover".

Installazione

Prima di tutto occorre installare il pacchetto ifenslave, necessario per abilitare il «bonding»:

# apt-get install ifenslave

Spegnere / Deconfigurare le interfacce esistenti

# ifdown eth0 (Ripetere il comando per tutte le interfacce da include nel bond)
# /etc/init.d/networking stop

{i} Alcune volte, ifdown non funziona, in questo caso si usi ifconfig eth0 down.

Configurazione - Esempio 1

Modificare il file /etc/network/interfaces:

auto bond0

iface bond0 inet static
    address 10.31.1.5
    netmask 255.255.255.0
    network 10.31.1.0
    gateway 10.31.1.254
    slaves eth0 eth1
    bond_mode active-backup
    bond_miimon 100
    bond_downdelay 200
    bond_updelay 200

Per maggiori dettagli si guardi /usr/share/doc/ifenslave/README.Debian e /usr/src/linux/Documentation/networking/bonding.txt.

Configurazione - Esempio 2 ("Modalità laptop")

Connettere le interfacce di rete cablata e wireless insieme (RJ45/WLAN) per definire un'unica interfaccia di rete virtuale ("bonding"), chiamata ad es. bond0.

Fintanto che il cavo di rete è connesso la sua interfaccia (es. eth0) viene usata per il traffico di rete. Se si disconnette la spina RJ45, ifenslave passa all'interfaccia wireless (es. wlan0) in modo trasparente, senza alcuna perdita di pacchetti di rete.

Dopo aver riconnesso il cavo di rete, ifenslave torna a eth0 ("modalità failover").

Dal punto di vista dell'esterno (rete) non importa quale interfaccia sia attiva. Il device di bonding presenta il proprio indirizzo MAC definito via software (cioè virtuale), diverso dagli indirizzi MAC hardware di eth0 o wlan0.

Il server DHCP userà questo indirizzo MAC per assegnare l'indirizzo IP al device bond0. Perciò il computer ha il suo proprio unico indirizzo IP con cui può essere identificato. Senza il bonding ogni interfaccia avrebbe un proprio indirizzo IP.

Modificare il file /etc/network/interfaces:

# Definire gli slave
auto eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0
    bond-mode active-backup
auto wlan0
iface wlan0 inet manual
    wpa-conf /etc/network/wpa.conf
    bond-master bond0
    bond-primary eth0
    bond-mode active-backup

# Definire il master
auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-primary eth0
    bond-mode active-backup
    bond-miimon 100

Notare: la configurazione soprastante è stata provata e funziona su Debian 6 e 7.1. Va in qualche modo in controcorrente rispetto alla documentazione di interfaces, ifup e ifenslave e gli esempi in /usr/share/doc/ifenslave/examples/.

In teoria solo una interfaccia dovrebbe avere l'attributo auto. ifup bond0 attiverò automaticamente gli slave (come dice la documentazione). Ciò è vero in parte ma ovviamente le opzioni di configurazione degli slave vengono ignorate. Ad esempio wlan0 viene attivata senza avviare wpa_supplicant e l'impostazione bond-primary di eth0 viene ignorata. (TODO: È un bug di ifenslave?)

Sembra che gli slave debbano essere attivati prima di bond0 per includere le loro opzioni di configurazione. Per farlo usando lo script /etc/init.d/networking, le loro definizioni devono precedere quella di bond0 e devono essere impostati gli attributi auto.

Naturalmente non devono essere riattivati di nuovo quando si attiva bond0. L'opzione bond-slaves none disabilita ciò. Le opzioni bond-master, bond-primary e bond-mode devono essere ripetute coerentemente per ogni slave.

Si genereranno avvertimenti del tipo "ifup: interface xyz already configured", ma almeno funziona.

Suggerimento

Allo scopo di capire meglio ciò che succede dietro alle quinte, mentre si sperimenta può essere utile un piccolo script per mostrare alcune informazioni sul device di bonding.

#! /bin/sh

echo "Slaves = $(cat /sys/class/net/bond0/bonding/slaves)"
echo "Primary = $(cat /sys/class/net/bond0/bonding/primary)"
echo "Active Slave = $(cat /sys/class/net/bond0/bonding/active_slave)"

r=$(pidof dhclient)
test -n "$r" && ps $r

r=$(pidof wpa_supplicant)
test -n "$r" && ps $r

Debug di ifenslave

Il meccanismo di bonding è basato su un modulo del kernel chiamato bonding che espone la sua interfaccia attraverso il file system virtuale /sys (es. /sys/class/net/bond0/*).

L'impostazione e la configurazione viene fatta in spazio utente con gli script:

Questi script vengono chiamati all'inizializzazione del sistema e allo spegnimento (in realtà è ifup che li chiama). Il loro scopo è di passare al modulo del kernel gli appropriati parametri e impostazioni.

Se qualcosa va storto con il bonding (e il suggerimento visto prima non funziona) si può dover guardare a ciò che gli script fanno passo-passo.

Per abilitare l'output prolisso, invocare direttamente ifup -a -v (invece di invocare /etc/init.d/networking). L'opzione -v abilita un registro di tutti i comandi che vengono eseguiti dagli script. Ciò fornisce almeno una traccia di ciò che sta succedendo e quando.

Sfortunatamente ciò non mostra le reazioni del modulo del kernel (come eventuali messaggi di errore), dato che i messaggi del (modulo del) kernel vengono riportati usndo l'utilità syslog.

Per ottenere una reale vista all'interno di ciò che sta succedendo è necessario fare ciò che viene definito debug invasivo. Ciò significa aggiungere righe in punti critici degli script per inviare un messaggio al syslog.

Esempio:

Funzione sysfs_change_down nel file /etc/network/if-pre-up.d/ifenslave

        logger -t sysfs_change_down sysfs "$1" "$2"
  sysfs "$1" "$2"
        logger -t sysfs_change_down $(cat /sys/class/net/bond0/bonding/mode)

Note aggiuntive per Debian Lenny su Sparc

(potrebbe essere applicabile anche ad altre architetture)

# cd /etc/modprobe.d

# cat > aliases-bond.conf
alias bond0 bonding
  options bonding mode=1 arp_interval=2000 arp_ip_target=192.168.3.1
<CTRL-D>

Senza questo file, durante l'avvio dell'interfaccia unita si otterrà un avvertimento simile a questo:

bonding: Warning: either miimon or arp_interval and arp_ip_target module parameters must be specified, otherwise bonding will not detect link failures! see bonding.txt for details.

Avvio / Configurazione delle nuove interfacce

# ifup bond0
# /etc/init.d/networking start

Inoltre, se si sta usando un ambiente Lenny che è stato aggiorndato da Etch, si raccomanda caldamente di verificare il risultato del seguente comando per verificare la modalità dell'interfaccia «bonding», perché i file di configurazione per Etch e versione più vecchie non funzionano su Lenny o versioni successive.

cat /sys/class/net/bond0/bonding/mode

Test

1. Fare un ping verso un altro sistema nel terminale

# ping X.X.X.X

2. Disconnettere il cavo di rete attiva e guardare il risultato del ping, la rete dovrebbe essere ripristinata in pochi secondi.

3. Riconnettere il cavo di rete disconnesso, aspettare 30 secondi per permettere alla tabella ARP di essere aggiornata

4. Disconnettere un altro cavo di rete e guardare i risultati del ping, la rete dovrebbe essere ripristinata in pochi secondi

Cambiare lo slave attivo

1. Usare ifenslave per cambiare lo slave attivo. L'esempio sottostante imposterà eth0 come slave attivo

# ifenslave -c bond0 eth0 eth1

problema del cambio di nomi di udev

"udev" assegna nomi agli adattatori di rete sulla base di

/etc/udev/rules.d/70-persistent-net.rules

dove una regola tipicamente ha il seguente formato:

# PCI device 0x10ec:0x8168 (r8169)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="xx:xx:xx:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

Il problema con il bonding è che due o più NIC possono avere lo stesso identico indirizzo MAC e ciò confonde udev quando cerca di (ri)assegnare i nomi agli adattatori sulla base dei loro indirizzi MAC e quindi fallisce perché esiste già una scheda con lo stesso indirizzo MAC. Quando ciò avviene i NIC possono rimanere con nomi come "rename2" invece di "eth0", ecc.

Una possibile soluzione è cambiare la regola udev in modo che assegni i nomi alle interfacce di rete sulla base degli ID PCI dei NIC, invece che in base agli indirizzi MAC. Ciò può essere fatto sostituendo

ATTR{address}=="xx:xx:xx:xx:xx:xx"

con qualcosa di simile a

KERNELS=="0000:04:00.0"

nel file "70-persistent-net.rules". Gli ID PCI corrispondenti possono essere trovati in dmesg:

sudo dmesg | grep eth

dove si possono cercare frammenti di riga simili a:

r8169 0000:04:00.0 eth0: RTL8168e/8111e
#     ^^^^^^^^^^^^

In alternativa gli ID PCI possono essere trovati usando "lspci -D | grep Ether":

0000:04:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 06)


CategoryNetwork