GNU/Linux >> Linux Esercitazione >  >> Linux

In attesa della configurazione della rete Linux nel ramdisk iniziale (initrd)

Un initrd (ramdisk iniziale) è un piccolo filesystem caricato durante il processo di avvio su un sistema Linux. Una delle attività di cui potrebbe essere responsabile initrd è la configurazione della rete.

Questo articolo spiega i casi in cui è necessaria la configurazione di rete all'inizio del processo di avvio, come viene implementata e i miglioramenti che Red Hat Enterprise Linux 8.3 apporta.

La necessità di un initrd

Quando si preme il pulsante di accensione di una macchina, il processo di avvio inizia con un meccanismo dipendente dall'hardware che carica un bootloader . Il software del bootloader trova il kernel sul disco e lo avvia. Successivamente, il kernel monta il filesystem di root ed esegue un init processo.

Questo processo sembra semplice e potrebbe essere ciò che effettivamente accade su alcuni sistemi Linux. Tuttavia, le moderne distribuzioni Linux devono supportare un vasto insieme di casi d'uso per i quali questa procedura non è adeguata.

Innanzitutto, il filesystem di root potrebbe trovarsi su un dispositivo che richiede un driver specifico. Prima di provare a montare il filesystem, è necessario inserire il modulo del kernel corretto nel kernel in esecuzione. In alcuni casi, il filesystem di root si trova su una partizione crittografata e quindi necessita di uno userspace helper che chieda la passphrase all'utente e la invii al kernel. Oppure, il filesystem di root potrebbe essere condiviso sulla rete tramite NFS o iSCSI e il montaggio potrebbe richiedere prima indirizzi IP e percorsi configurati su un'interfaccia di rete.

[ Potrebbe piacerti anche: Rete Linux:13 usi per netstat ]

Per superare questi problemi, il bootloader può passare al kernel una piccola immagine del filesystem (l'initrd) che contiene script e strumenti per trovare e montare il vero filesystem di root. Fatto ciò, initrd passa alla radice reale e l'avvio continua come al solito.

L'infrastruttura di Dracut

Su Fedora e RHEL, initrd è costruito tramite dracut . Dalla sua home page, dracut è "un'infrastruttura initramfs basata su eventi. dracut (lo strumento) viene utilizzato per creare un'immagine initramfs copiando strumenti e file da un sistema installato e combinandolo con il framework dracut, che di solito si trova in /usr/lib/dracut/modules.d ."

Una nota sulla terminologia:a volte, i nomi initrd e initramfs sono usati in modo intercambiabile. In realtà si riferiscono a diversi modi di costruire l'immagine. Un initrd è un'immagine contenente un filesystem reale (ad esempio ext2) che viene montato dal kernel. Un initramfs è un archivio cpio contenente un albero di directory che viene decompresso come tmpfs. Al giorno d'oggi, le immagini initrd sono deprecate a favore dello schema initramfs. Tuttavia, il nome initrd è ancora usato per indicare il processo di avvio che coinvolge un filesystem temporaneo.

Riga di comando del kernel

Rivisitiamo lo scenario radice NFS menzionato prima. Un possibile modo per eseguire l'avvio tramite NFS è utilizzare una riga di comando del kernel contenente root=dhcp argomento.

La riga di comando del kernel è un elenco di opzioni passate al kernel dal bootloader, accessibile al kernel e alle applicazioni. Se utilizzi GRUB, puoi modificarlo premendo la e tasto su una voce di avvio e modificando la riga che inizia con linux .

Il codice dracut all'interno di initramfs analizza la riga di comando del kernel e avvia DHCP su tutte le interfacce se la riga di comando contiene root=dhcp . Dopo aver ottenuto un lease DHCP, dracut configura l'interfaccia con i parametri ricevuti (indirizzo IP e percorsi); estrae anche il valore dell'opzione DHCP del percorso radice dal lease. L'opzione contiene l'indirizzo e il percorso di un server NFS (che potrebbe essere, ad esempio, 192.168.50.1:/nfs/client ). Dracut quindi monta la condivisione NFS in questa posizione e procede con l'avvio.

Se non esiste un server DHCP che fornisce l'indirizzo e il percorso radice NFS, i valori possono essere configurati esplicitamente nella riga di comando:

root=nfs:192.168.50.1:/nfs/client ip=192.168.50.101:::24::ens2:none

Qui, il primo argomento specifica l'indirizzo del server NFS e il secondo configura ens2 interfaccia con un indirizzo IP statico.

Esistono due sintassi per specificare la configurazione di rete per un'interfaccia:

ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]

ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<mtu>][:<macaddr>]]

Il primo può essere utilizzato per la configurazione automatica (DHCP o IPv6 SLAAC) e il secondo per la configurazione statica o una combinazione di automatico e statico. Ecco alcuni esempi:

ip=enp1s0:dhcp
ip=192.168.10.30::192.168.10.1:24::enp1s0:none
ip=[2001:0db8::02]::[2001:0db8::01]:64::enp1s0:none

Nota che se passi un ip= opzione, ma dracut non ha bisogno di rete per montare il filesystem di root, l'opzione viene ignorata. Per forzare la configurazione di rete senza una radice di rete, aggiungi rd.neednet=1 alla riga di comando.

Probabilmente avrai notato che tra i metodi di configurazione automatica c'è anche ibft . iBFT sta per iSCSI Boot Firmware Table ed è un meccanismo per passare i parametri sui dispositivi iSCSI dal firmware al sistema operativo. iSCSI (Internet Small Computer Systems Interface) è un protocollo per accedere ai dispositivi di archiviazione di rete. La descrizione di iBFT e iSCSI non rientra nell'ambito di questo articolo. L'importante è che passando ip=ibft al kernel, la configurazione di rete viene recuperata dal firmware.

Dracut supporta anche l'aggiunta di percorsi personalizzati, specificando il nome della macchina e i server DNS, creando legami, bridge, VLAN e molto altro. Vedi la pagina man di dracut.cmdline per maggiori dettagli.

Moduli di rete

Il framework dracut incluso in initramfs ha un'architettura modulare. Comprende una serie di moduli, ciascuno contenente script e binari per fornire funzionalità specifiche. Puoi vedere quali moduli sono disponibili per essere inclusi in initramfs con il comando dracut --list-modules .

Al momento, ci sono due moduli per configurare la rete:network-legacy e network-manager . Potresti chiederti perché moduli diversi forniscono la stessa funzionalità.

network-legacy è più vecchio e usa script di shell che chiamano utilità come iproute2 , dhclient e arping per configurare le interfacce. Dopo il passaggio alla radice reale, viene eseguito un servizio di configurazione di rete diverso. Questo servizio non è a conoscenza di cosa sia il network-legacy modulo destinato a fare e lo stato corrente di ciascuna interfaccia. Ciò può causare problemi nel mantenimento dello stato oltre il limite dell'interruttore principale.

Un importante esempio di stato da mantenere è il lease DHCP. Se l'indirizzo di un'interfaccia viene modificato durante l'avvio, la connessione a una condivisione NFS si interrompe, causando un errore di avvio.

Per garantire una transizione senza interruzioni, è necessario un meccanismo per trasferire lo stato tra i due ambienti. Tuttavia, il passaggio dello stato tra servizi con modelli di configurazione diversi può essere un problema.

Il network-manager Il modulo dracut è stato creato per migliorare questa situazione. Il modulo esegue NetworkManager in initrd per configurare i profili di connessione generati dalla riga di comando del kernel. Una volta terminato, NetworkManager serializza il suo stato, che viene successivamente letto dall'istanza NetworkManager nella radice reale.

Fedora 31 è stata la prima distribuzione a passare a network-manager initrd per impostazione predefinita. Su RHEL 8.2, network-legacy è ancora l'impostazione predefinita, ma network-manager è disponibile. Su RHEL 8.3, dracut utilizzerà network-manager per impostazione predefinita.

Abilitazione di un modulo di rete diverso

Sebbene i due moduli dovrebbero essere ampiamente compatibili, ci sono alcune differenze nel comportamento. Alcuni di questi sono documentati nel nm-initrd-generator pagina man. In generale, si suggerisce di utilizzare il network-manager modulo quando NetworkManager è abilitato.

Per ricostruire initrd utilizzando un modulo di rete specifico, utilizzare uno dei seguenti comandi:

# dracut --add network-legacy  --force --verbose
# dracut --add network-manager --force --verbose

Poiché questa modifica verrà ripristinata alla successiva ricostruzione di initrd, potresti voler rendere permanente la modifica nel modo seguente:

# echo 'add_dracutmodules+=" network-manager "' > /etc/dracut.conf.d/network-module.conf
# dracut --regenerate-all --force --verbose

Il --regenerate-all l'opzione ricostruisce anche tutte le immagini di initramfs per le versioni del kernel trovate sul sistema.

Il modulo dracut del gestore di rete

Come per tutti i moduli dracut, il network-manager module è suddiviso in fasi che vengono richiamate in momenti diversi durante l'avvio (consultare la pagina man di dracut.modules per maggiori dettagli).

La prima fase analizza la riga di comando del kernel chiamando /usr/libexec/nm-initrd-generator per produrre un elenco di profili di connessione in /run/NetworkManager/system-connections . La seconda parte del modulo viene eseguita dopo che udev si è stabilizzato, cioè dopo che lo spazio utente ha finito di gestire gli eventi del kernel per i dispositivi (incluse le interfacce di rete) trovati nel sistema.

Quando NM viene avviato nell'ambiente root reale, si registra su D-Bus, configura la rete e rimane attivo per reagire agli eventi o alle richieste D-Bus. In initrd, NetworkManager viene eseguito in configure-and-quit=initrd mode, che non si registra su D-Bus (poiché non è disponibile in initrd, almeno per ora) ed esce dopo aver raggiunto il avvio-completato evento.

Il avvio completo l'evento viene attivato dopo che tutti i dispositivi con un profilo di connessione corrispondente hanno tentato di attivarsi, con successo o meno. Una volta configurate tutte le interfacce, NM esce e chiama dracut hooks per notificare agli altri moduli che la rete è disponibile.

Nota che il /run/NetworkManager la directory contenente i profili di connessione generati e altri stati di runtime viene copiata nella radice reale in modo che il nuovo processo NetworkManager in esecuzione sappia esattamente cosa fare.

Risoluzione dei problemi

Se hai problemi di rete in dracut, questa sezione contiene alcuni suggerimenti per investigare il problema.

La prima cosa da fare è aggiungere rd.debug alla riga di comando del kernel, abilitando la registrazione del debug in dracut. I log vengono salvati in /run/initramfs/rdsosreport.txt e sono disponibili anche nel diario.

Se il sistema non si avvia, è utile ottenere una shell all'interno dell'ambiente initrd per verificare manualmente perché le cose non funzionano. Per questo, c'è un rd.break argomento della riga di comando. Nota che l'argomento genera una shell quando initrd ha terminato il suo lavoro e sta per dare il controllo al processo init nel filesystem root reale. Per fermarti a una fase diversa di dracut (ad esempio, dopo l'analisi della riga di comando), usa il seguente argomento:

rd.break={cmdline|pre-udev|pre-trigger|initqueue|pre-mount|mount|pre-pivot|cleanup}

L'immagine initrd contiene un set minimo di binari; se hai bisogno di uno strumento specifico nella shell di dracut, puoi ricostruire l'immagine, aggiungendo ciò che manca. Ad esempio, per aggiungere il ping e tcpdump binari (incluse tutte le relative librerie dipendenti), esegui:

# dracut -f  --install "ping tcpdump"

e poi, facoltativamente, verifica che siano stati inclusi correttamente:

# lsinitrd | grep "ping\|tcpdump"
Arguments: -f --install 'ping tcpdump'
-rwxr-xr-x   1 root     root        82960 May 18 10:26 usr/bin/ping
lrwxrwxrwx   1 root     root           11 May 29 20:35 usr/sbin/ping -> ../bin/ping
-rwxr-xr-x   1 root     root      1065224 May 29 20:35 usr/sbin/tcpdump

Il generatore

Se hai familiarità con la configurazione di NetworkManager, potresti voler sapere come una determinata riga di comando del kernel viene tradotta nei profili di connessione di NetworkManager. Questo può essere utile per comprendere meglio il meccanismo di configurazione e trovare errori di sintassi nella riga di comando senza dover avviare la macchina.

Il generatore è installato in /usr/libexec/nm-initrd-generator e deve essere chiamato con l'elenco degli argomenti del kernel dopo un doppio trattino. Il --stdout l'opzione stampa le connessioni generate sullo standard output. Proviamo a chiamare il generatore con una riga di comando di esempio:

$ /usr/libexec/nm-initrd-generator --stdout -- \
          ip=enp1s0:dhcp:00:99:88:77:66:55 rd.peerdns=0

802-3-ethernet.cloned-mac-address: '99:88:77:66:55' is not a valid MAC
address

In questo esempio, il generatore segnala un errore perché manca un campo per l'MTU dopo enp1s0 . Una volta corretto l'errore, l'analisi ha esito positivo e lo strumento stampa il profilo di connessione generato:

$ /usr/libexec/nm-initrd-generator --stdout -- \
        ip=enp1s0:dhcp::00:99:88:77:66:55 rd.peerdns=0

*** Connection 'enp1s0' ***

[connection]
id=enp1s0
uuid=e1fac965-4319-4354-8ed2-39f7f6931966
type=ethernet
interface-name=enp1s0
multi-connect=1
permissions=

[ethernet]
cloned-mac-address=00:99:88:77:66:55
mac-address-blacklist=

[ipv4]
dns-search=
ignore-auto-dns=true
may-fail=false
method=auto

[ipv6]
addr-gen-mode=eui64
dns-search=
ignore-auto-dns=true
method=auto

[proxy]

Nota come rd.peerdns=0 argomento si traduce in ignore-auto-dns=true proprietà, che fa sì che NetworkManager ignori i server DNS ricevuti tramite DHCP. Una spiegazione delle proprietà di NetworkManager può essere trovata nella pagina man di nm-settings.

[ Rete fuori controllo? Dai un'occhiata all'automazione della rete per tutti, un libro gratuito di Red Hat. ] 

Conclusione

Il modulo NetworkManager dracut è abilitato per impostazione predefinita in Fedora e sarà presto abilitato anche su RHEL. Porta una migliore integrazione tra la rete in initrd e NetworkManager in esecuzione nel filesystem di root reale.

Sebbene l'attuale implementazione stia funzionando bene, ci sono alcune idee per possibili miglioramenti. Uno è abbandonare il configure-and-quit=initrd mode ed esegui NetworkManager come un demone avviato da un servizio systemd. In questo modo NetworkManager verrà eseguito allo stesso modo di quando viene eseguito nella root reale, riducendo il codice da mantenere e testare.

Per eliminare completamente il configure-and-quit=initrd modalità, NetworkManager dovrebbe anche essere in grado di registrarsi su D-Bus in initrd. Attualmente, dracut non ha alcun modulo che fornisce un demone D-Bus perché l'immagine dovrebbe essere minima. Tuttavia, ci sono già proposte per includerlo in quanto è necessario per implementare alcune nuove funzionalità.

Con D-Bus in esecuzione in initrd, la potente API di NetworkManager sarà disponibile per altri strumenti per interrogare e modificare lo stato della rete, sbloccando un'ampia gamma di applicazioni. Uno di questi è eseguire nm-cloud-setup nell'initrd. Il servizio, spedito nel NetworkManager-cloud-setup Il pacchetto Fedora recupera i metadati dall'infrastruttura dei provider di servizi cloud (EC2, Azure, GCP) per configurare automaticamente la rete.


Linux
  1. Test di integrazione continui per il kernel Linux

  2. Il gioco dei nomi:denominazione delle interfacce di rete in Linux

  3. Linux:perché il kernel non può eseguire Init?

  4. Linux:parti proprietarie o chiuse del kernel?

  5. Cambia il timer del kernel linux

Analizza il kernel Linux con ftrace

Come il kernel Linux gestisce gli interrupt

Come controllare la versione del kernel in Linux

Come usare il comando netstat in Linux

In che modo Linux carica l'immagine "initrd"?

Come impostare l'interfaccia di rete preferita in Linux