Differences between revisions 8 and 9
Revision 8 as of 2019-05-10 09:59:58
Size: 20527
Comment: sync with English master v.43
Revision 9 as of 2021-12-01 08:17:42
Size: 0
Comment: Page become too technical and complex to be kept updated. Also so technical that who needs it probably has to have some English knowledge
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#language it
~-[[DebianWiki/EditorGuide#translation|Traduzioni]]: [[Bonding|English]] - Italiano -~
----
= Bonding =
Questo articolo mostra come unire (''bond'') due connessioni Ethernet assieme per creare una interfaccia "auto failover".

<<TableOfContents()>>

= Installazione =
Prima di tutto occorre installare il pacchetto [[DebianPkg: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 includere 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 [[http://www.kernel.org/doc/Documentation/networking/bonding.txt|/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 successive. L'ultima versione verificata è la Debian 9.8 (*). La configurazione 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.

(*) Con le versioni più nuove di Debian i nomi dei device di rete (possono) sono cambiati, a seconda del percorso di aggiornamento. Le installazioni da zero usano ora "nomi delle interfacce di rete prevedibili" ([[https://wiki.debian.org/NetworkConfiguration#Predictable_Network_Interface_Names]]). Per trovare i nomi delle interfacce guardare in:
{{{$ ls /sys/class/net/ }}}

Questo documento usa ancora i nomi tradizionali.

= Configuratione - Esempio 3 ("Modalità portatile", per lo più come descritto nella documentazione - Debian 9 "stretch") =

Questo è un modo per attivare la modalità portatile con ripiego automatico tra connessione wireless e cablata, con quella cablata come preferita se sono entrambe disponibili. È basato sulla documentazione; tuttavia l'esempio nella documentazione non è completo e non è del tutto corretto. In particolare le modifiche nell'esempio (usr/share/doc/ifenslave/examples/ethernet+wifi) sono:

 * la sezione eth0 ''è'' necessaria, altrimenti funziona inizialmente ma bond0 elimina del tutto eth0, se il collegamento eth0 si disattiva dopo essersi attivato una prima volta (come quando si passa da wireless a cablato e poi di nuovo a wireless), invece di disattivarlo fino a quando non torna disponibile.

 * "bond-give-a-chance 10" ha come risultato che l'interfaccia wlan0 cerca di attivarsi tre volte, con il terzo tentativo che fallisce e diventando inutilizzabile. Rimuoverlo interamente ha risolto il problema. Invece di cancellarlo l'autore lo ha solo commentato; l'esperienza degli altri utenti può essere diversa.

 * l'ordine in cui si creano gli slave sembra aver un effetto: se "bond-slaves" è specificato nel modo atteso (eth0 wlan0), allora wlan0 sarà inizialmente l'interfaccia principale, per essere modificato ad eth0 solo nella direttiva "bond-primary".

 * "bond-mode" è stato modificato da "1" a "active-backup" per essere più intellegibile.

 * sarebbe una buona prassi avere la configurazione della wlan in un file separato in modo che "interfaces" non richieda una speciale protezione, perciò anche ciò è stato modificato dall'autore. I contenuti di "wpa_supplicant.conf" non sono specifici per il bonding e inseriti come di consueto.

Detto questo ecco il fantastico {{{/etc/network/interfaces}}} risultante: {{{
auto bond0
iface bond0 inet static
    bond-slaves wlan0 eth0
    bond-mode active-backup
    bond-primary eth0
    bond-miimon 100
    address <ipv4address>/<maskbits>
    gateway <ipv4address>

allow-bond0 eth0
iface eth0 inet manual

allow-bond0 wlan0
iface wlan0 inet manual
# bond-give-a-chance 10
    wpa-bridge bond0
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
}}}

Se si usa DHCP o qualche altro servizio, è necessario cambiare la sezione "bond0" di conseguenza, ma le altre interfacce devono rimanere "manual", dato che non dovrebbero ottenere un indirizzo IP.

= Fare il bridge con il bond =

Se si vuole usare il bond in un bridge, aggiungere semplicemente le righe del bridge come di consueto nel proprio file /etc/network/interfaces. Modificare l'interfaccia di interface a "manual" e usarla come interfaccia bridge. Ecco un file d'esempio per interfacce bond con bridge:
{{{
# onboard network interface
auto enp4s0
iface enp4s0 inet manual
# PCIe nic
auto enp8s0
iface enp8s0 inet manual
# bond inteface
auto bond0
iface bond0 inet manual
        slaves enp4s0 enp8s0
        bond-mode 802.3ad
# bridge interface
auto br0
iface br0 inet static
        address 192.168.1.17
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        bridge_ports bond0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0
}}}

= Usare systemd-networkd =

Questo metodo non usa il pacchetto ifenslave ricordato sopra. Se il proprio computer usa systemd e le schede di rete funzionano non è necessario fare altro. Notare che, come è prassi comune nei sistemi operativi in stile UNIX, le maiuscole e le minuscole contano: "Bond" è diverso da "bond" e "Nome" non è la stessa cosa di "nome".

== Abilitare systemd-networkd ==

Se non si sta già usando systemd-networkd, è necessario abilitarlo.

{{{
systemctl enable systemd-networkd
}}}

== Configurare il device di bond ==

Creare un file con estensione {{{.netdev}}} in {{{/etc/systemd/network}}}. Chiamarlo usando il nome dell'interfaccia con il bond che si vuole usare (es. bond0.netdev).

Questo esempio presume un bonding 802.3ad o LACP, per maggiori informazioni vedere la pagina di manuale di[[https://manpages.debian.org/stretch/systemd/systemd.netdev.5.en.html|systemd.netdev]] o la [[https://www.kernel.org/doc/Documentation/networking/bonding.txt|documentazione del kernel]].

La maggior parte dei sistemi dovrebbe funzionare con 802.3ad e questa è probabilmente la modalità che si vorrà usare dato che ha le schede di rete che lavorano assieme per dare il doppio del tasso di scambio di dati. Se, tuttavia, nel proprio caso non funziona si può provare un'altra modalità, come active-backup (usata nell'esempio ifenslave soprastante).

Notare che systemd crea sempre un'interfaccia predefinita bond0 che modalità "balance round robin" e la modalità non può essere modificata. Perciò, per usare qualsiasi altra modalità, creare bond1 o un altro nome per l'interfaccia. L'interfaccia bond0 con modalità 802.3ad semplicemente non funzionerà.

{{{
[NetDev]
Name=bond1
Description=LAG/Bond ad uno switch
Kind=bond

[Bond]
Mode=802.3ad
}}}

== Aggiungere interfacce al bond/lag ==

Ci sono due modi per farlo. Uno è di creare un file .network per ogni interfaccia di rete, più uno per la rete con bonding. L'altro è di descrivere le interfacce di rete nel file della rete con bonding. Qui viene usato quest'ultimo metodo.

Creare un file con estensione {{{.network}}} in {{{/etc/systemd/network}}} usando lo stesso nome usato prima (es. bond1.network).

systemd-networkd usa un sistema di corrispondenze per decidere quale interfaccia usare. Si possono usare le corrispondenze basate sui nomi se si preferisce, ma non usare le corrispondenze basate su MAC dato che può creare confusione con il bond che cambia gli indirizzi MAC.

Questo esempio usa le corrispondenze basate su ID PCI.
Per trovare gli indirizzi per le proprie schede di rete usare:

{{{
lspci -d | grep Ether
}}}
 
poi usare tali informazioni per creare il file .network.

{{{
[Match]
Path=pci-0000:00:01.0
Path=pci-0000:05:10.0

[Network]
Bond=bond1
}}}

Un'altra opzione è quella di usare semplicemente i nomi delle interfacce di rete sostituendo la riga Path= con Name=<nome-interfaccia-rete>. Si possono usare anche metacaratteri e si possono specificare entrambi/tutti i device in un unico file:

{{{
[Match]
Name=enp*

[Network]
Bond=bond1
}}}

o

{{{
[Match]
Name=enp0s01
Name=enp5s10

[Network]
Bond=bond1
}}}

== Dare un IP al bond ==

Creare un file con estensione {{{.network}}} in {{{/etc/systemd/network}}}.
Il nome (ovviamente) non dovrebbe essere già in uso. Questo dice a systemd di attivare la rete con bonding. Per un indirizzo IP statico si può usare:

{{{
[Match]
Name=bond1

[Network]
Address=10.31.1.5
Gateway=10.31.1.1
DNS=10.31.1.1
}}}

Per il DHCP (es. per un portatile dove si possono usare connessioni wireless o cablate) provare:

{{{
[Match]
Name=bond1

[Network]
DHCP=yes
}}}

== Rendere attive le impostazioni ==

Se la rete stava usando /etc/network/interfaces prima di impostare il bonding, rinominare il file per impedire che venga usato:

{{{
mv /etc/network/interfaces /etc/network/interfaces.save
}}}

A questo punto è raccomandato riavviare il sistema. È il modo più semplice per ripulire ogni configurazione di rete precedente e testare che systemd-networkd si avvii come atteso. La rete dovrebbe venir attivata con il bonding in funzione. Lo si può verificare con:

{{{
ip link list
}}}

Si dovrebbero vedere 4 device: lo, due interfacce di rete fisiches (indicate come "SLAVE") e il device bond1. solo il device bond1 dovrebbe avere un indirizzo IP. Dovrebbe anche essere indicato come "MASTER".

Se è necessario fare altre modifiche in seguito, o risolvere problemi con le attuali impostazioni, da questo momento in poi si può semplicemente riavviare systemd-networkd dopo aver aggiornato i file /etc/systemd/network.
{{{
systemctl restart systemd-networkd
}}}

== Abilitare il bridging per le macchine virtuali ==

Questa sezione è stata aggiunta perché all'autore non era immediatamente ovvio perché la sua configurazione di rete bridge esistente non funzionasse con systemd-networkd. Prima di impostare il bond di rete, usava le utilità bridge per creare un device br0 usando /etc/network/interfaces. Una volta rimosso tale file era necessario un nuovo modo per impostare il bridge.

Fortunatamente systemd-networkd ha molti talenti ed è piuttosto bravo a gestire i bridge di rete. Tutto ciò che è necessario fare è definire il bridge ed assegnarli le caratteristiche appropriate.

Come per il device bond0, è necessario creare un file .netdev per definire il device. Chi scrive ha creato br1.netdev come segue:

{{{
[NetDev]
Name=br0
Kind=bridge
}}}

Poi ha fatto il collegamento al bond di rete definito in precedenza usando br0.network:
{{{
[Match]
Name=bond1

[Network]
Bridge=br0
}}}

Da ultimo ha modificato il file .network in modo che facesse riferimento a br0 invece che a bond1. Dato che le definizioni precedenti hanno reso bond1 uno slave di br0, ciò risulta nella corretta attivazione del bridge.

== Problema del cambio di nomi di udev ==

Probabilmente si vedranno solo regole UDEV per i dispositivi di rete se si ha aggiornato da versioni precedenti di Debian. Le nuove installazioni danno i nomi alle schede di rete in base ai loro indirizzi PCI. Le regole sono usate per preservare i nomi obsoleti per i device (es. eth0) nel caso vengano usati altrove.

Se si è sicuri di '''non''' usare i nomi obsoleti si può semplicemente rimuovere il file descritto in seguito.

"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
# ^^^^^^^^^^^^
}}}

Tuttavia questo non è raccomandato dato che non trova, ad esempio, i dispositivi wireless o dispositivi che non usano i nomi obsoleti.

L'alternativa preferibile è quella di trovare gli ID PCI 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)
}}}

Notare che nei sistemi moderni si può tradurre l'indirizzo PCI nel nome di rete usando i due numeri di mezzo espressi in base 10. Nell'esempio soprastante il controllore 0000:04:00.0 sarebbe enp4s00.

= Test/Debug =
== 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.

{{{#! wiki debian

#! /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:
 */etc/network/if-post-down.d/ifenslave
 */etc/network/if-up.d/ifenslave
 */etc/network/if-pre-up.d/ifenslave

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 [[it/DebianLenny|Lenny]] che è stato aggiorndato da [[it/DebianEtch|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
}}}


## You can add other _helpful_ links here.
##See also:
## If this page belongs to an existing Category, add it below.
## CategorySomething | CategoryAnother
----
CategoryNetwork