GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Ich freue mich auf die Linux-Netzwerkkonfiguration in der anfänglichen Ramdisk (initrd)

Eine initrd (initial ramdisk) ist ein kleines Dateisystem, das während des Bootvorgangs auf einem Linux-System geladen wird. Eine der Aufgaben, für die die initrd verantwortlich sein könnte, ist die Netzwerkkonfiguration.

Dieser Artikel erläutert die Fälle, in denen eine Netzwerkkonfiguration zu Beginn des Startvorgangs erforderlich ist, wie sie implementiert wird und welche Verbesserungen Red Hat Enterprise Linux 8.3 mit sich bringt.

Die Notwendigkeit einer initrd

Wenn Sie den Netzschalter einer Maschine drücken, beginnt der Bootvorgang mit einem hardwareabhängigen Mechanismus, der einen Bootloader lädt . Die Bootloader-Software findet den Kernel auf der Festplatte und bootet ihn. Als nächstes hängt der Kernel das Root-Dateisystem ein und führt ein init aus verarbeiten.

Dieser Prozess klingt einfach und könnte auf einigen Linux-Systemen tatsächlich passieren. Moderne Linux-Distributionen müssen jedoch eine Vielzahl von Anwendungsfällen unterstützen, für die dieses Verfahren nicht geeignet ist.

Erstens könnte sich das Root-Dateisystem auf einem Gerät befinden, das einen bestimmten Treiber benötigt. Bevor Sie versuchen, das Dateisystem einzuhängen, muss das richtige Kernelmodul in den laufenden Kernel eingefügt werden. In einigen Fällen befindet sich das Root-Dateisystem auf einer verschlüsselten Partition und benötigt daher einen Userspace-Helfer, der den Benutzer nach der Passphrase fragt und sie an den Kernel weitergibt. Oder das Root-Dateisystem könnte über NFS oder iSCSI über das Netzwerk freigegeben werden, und das Mounten erfordert möglicherweise zuerst konfigurierte IP-Adressen und Routen auf einer Netzwerkschnittstelle.

[Das könnte Ihnen auch gefallen: Linux-Netzwerke:13 Einsatzmöglichkeiten für Netstat]

Um diese Probleme zu lösen, kann der Bootloader ein kleines Dateisystem-Image (die initrd) an den Kernel übergeben, das Skripte und Tools enthält, um das echte Root-Dateisystem zu finden und einzuhängen. Sobald dies erledigt ist, wechselt die initrd zum echten Root und der Bootvorgang wird wie gewohnt fortgesetzt.

Die Dracut-Infrastruktur

Auf Fedora und RHEL wird die initrd durch dracut erstellt . Von seiner Homepage aus ist dracut „eine ereignisgesteuerte initramfs-Infrastruktur. dracut (das Tool) wird verwendet, um ein initramfs-Image zu erstellen, indem Tools und Dateien von einem installierten System kopiert und mit dem dracut-Framework kombiniert werden, das normalerweise in /usr/lib/dracut/modules.d ."

Ein Hinweis zur Terminologie:Manchmal sind die Namen initrd und initramfs werden synonym verwendet. Sie beziehen sich tatsächlich auf verschiedene Arten, das Bild aufzubauen. Eine initrd ist ein Image, das ein echtes Dateisystem (z. B. ext2) enthält, das vom Kernel gemountet wird. Ein initramfs ist ein cpio-Archiv, das einen Verzeichnisbaum enthält, der als tmpfs entpackt wird. Heutzutage sind die initrd-Images zugunsten des initramfs-Schemas veraltet. Der initrd-Name wird jedoch immer noch verwendet, um den Boot-Vorgang mit einem temporären Dateisystem anzuzeigen.

Kernel-Befehlszeile

Sehen wir uns das zuvor erwähnte NFS-Root-Szenario noch einmal an. Eine Möglichkeit, über NFS zu booten, ist die Verwendung einer Kernel-Befehlszeile, die root=dhcp enthält Argument.

Die Kernel-Befehlszeile ist eine Liste von Optionen, die vom Bootloader an den Kernel übergeben werden und auf die der Kernel und Anwendungen zugreifen können. Wenn Sie GRUB verwenden, kann es durch Drücken des e geändert werden Geben Sie einen Boot-Eintrag ein und bearbeiten Sie die Zeile, die mit linux beginnt .

Der dracut-Code in initramfs analysiert die Kernel-Befehlszeile und startet DHCP auf allen Schnittstellen, wenn die Befehlszeile root=dhcp enthält . Nach Erhalt einer DHCP-Lease konfiguriert dracut die Schnittstelle mit den erhaltenen Parametern (IP-Adresse und Routen); es extrahiert auch den Wert der Root-Pfad-DHCP-Option aus der Lease. Die Option enthält die Adresse und den Pfad eines NFS-Servers (was beispielsweise 192.168.50.1:/nfs/client sein könnte ). Dracut mountet dann die NFS-Freigabe an dieser Stelle und fährt mit dem Booten fort.

Wenn es keinen DHCP-Server gibt, der die Adresse und den NFS-Root-Pfad bereitstellt, können die Werte explizit in der Befehlszeile konfiguriert werden:

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

Hier gibt das erste Argument die Adresse des NFS-Servers an und das zweite konfiguriert ens2 Schnittstelle mit einer statischen IP-Adresse.

Es gibt zwei Syntaxen, um die Netzwerkkonfiguration für eine Schnittstelle anzugeben:

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>]]

Der erste kann für die automatische Konfiguration (DHCP oder IPv6 SLAAC) und der zweite für die statische Konfiguration oder eine Kombination aus automatisch und statisch verwendet werden. Hier einige Beispiele:

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

Beachten Sie, dass, wenn Sie ein ip= übergeben Option, aber dracut benötigt kein Netzwerk, um das Root-Dateisystem zu mounten, wird die Option ignoriert. Um die Netzwerkkonfiguration ohne Netzwerkstamm zu erzwingen, fügen Sie rd.neednet=1 hinzu zur Befehlszeile.

Sie haben wahrscheinlich bemerkt, dass es unter den automatischen Konfigurationsmethoden auch ibft gibt . iBFT steht für iSCSI Boot Firmware Table und ist ein Mechanismus, um Parameter über iSCSI-Geräte von der Firmware an das Betriebssystem zu übergeben. iSCSI (Internet Small Computer Systems Interface) ist ein Protokoll für den Zugriff auf Netzwerkspeichergeräte. Die Beschreibung von iBFT und iSCSI würde den Rahmen dieses Artikels sprengen. Wichtig ist, dass Sie ip=ibft übergeben zum Kernel wird die Netzwerkkonfiguration von der Firmware abgerufen.

Dracut unterstützt auch das Hinzufügen benutzerdefinierter Routen, das Angeben des Maschinennamens und der DNS-Server, das Erstellen von Bindungen, Bridges, VLANs und vieles mehr. Weitere Einzelheiten finden Sie auf der Manpage dracut.cmdline.

Netzwerkmodule

Das im initramfs enthaltene dracut-Framework hat eine modulare Architektur. Es besteht aus einer Reihe von Modulen, die jeweils Skripte und Binärdateien enthalten, um bestimmte Funktionen bereitzustellen. Mit dem Befehl dracut --list-modules können Sie sehen, welche Module verfügbar sind, um in das initramfs aufgenommen zu werden .

Im Moment gibt es zwei Module, um das Netzwerk zu konfigurieren:network-legacy und network-manager . Sie fragen sich vielleicht, warum verschiedene Module die gleiche Funktionalität bieten.

network-legacy ist älter und verwendet Shell-Skripte, die Dienstprogramme wie iproute2 aufrufen , dhclient , und arping Schnittstellen zu konfigurieren. Nach dem Wechsel zum echten Root läuft ein anderer Netzwerkkonfigurationsdienst. Dieser Dienst ist sich der network-legacy nicht bewusst das vorgesehene Modul und den aktuellen Zustand jeder Schnittstelle. Dies kann zu Problemen führen, den Zustand über die Root-Switch-Grenze hinweg aufrechtzuerhalten.

Ein prominentes Beispiel für einen beizubehaltenden Zustand ist die DHCP-Lease. Wenn sich die Adresse einer Schnittstelle während des Bootens änderte, wurde die Verbindung zu einer NFS-Freigabe unterbrochen, was zu einem Boot-Fehler führte.

Um einen nahtlosen Übergang zu gewährleisten, ist ein Mechanismus erforderlich, um den Zustand zwischen den beiden Umgebungen zu übergeben. Das Übergeben des Zustands zwischen Diensten mit unterschiedlichen Konfigurationsmodellen kann jedoch ein Problem darstellen.

Der network-manager Das dracut-Modul wurde geschaffen, um diese Situation zu verbessern. Das Modul führt NetworkManager in der initrd aus, um Verbindungsprofile zu konfigurieren, die von der Kernel-Befehlszeile generiert werden. Sobald dies erledigt ist, serialisiert NetworkManager seinen Status, der später von der NetworkManager-Instanz im echten Stammverzeichnis gelesen wird.

Fedora 31 war die erste Distribution, die auf network-manager umgestellt hat standardmäßig in initrd. Unter RHEL 8.2 network-legacy ist immer noch der Standard, aber network-manager ist verfügbar. Unter RHEL 8.3 verwendet dracut network-manager standardmäßig.

Aktivieren eines anderen Netzwerkmoduls

Während die beiden Module weitgehend kompatibel sein sollten, gibt es einige Unterschiede im Verhalten. Einige davon sind im nm-initrd-generator dokumentiert Manpage. Generell wird empfohlen, den network-manager zu verwenden Modul, wenn NetworkManager aktiviert ist.

Verwenden Sie einen der folgenden Befehle, um die initrd mit einem bestimmten Netzwerkmodul neu zu erstellen:

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

Da diese Änderung beim nächsten Neuaufbau der initrd rückgängig gemacht wird, möchten Sie die Änderung vielleicht folgendermaßen dauerhaft machen:

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

Der --regenerate-all Option baut auch alle initramfs-Images für die auf dem System gefundenen Kernel-Versionen neu auf.

Das Dracut-Modul des Netzwerkmanagers

Wie bei allen Dracut-Modulen ist der network-manager Das Modul ist in Stufen aufgeteilt, die zu unterschiedlichen Zeiten während des Bootvorgangs aufgerufen werden (weitere Einzelheiten finden Sie auf der Manpage dracut.modules).

Die erste Stufe analysiert die Kernel-Befehlszeile durch Aufrufen von /usr/libexec/nm-initrd-generator um eine Liste von Verbindungsprofilen in /run/NetworkManager/system-connections zu erstellen . Der zweite Teil des Moduls wird ausgeführt, nachdem sich udev eingerichtet hat, d. h. nachdem der Userspace die Verarbeitung der Kernel-Ereignisse für im System gefundene Geräte (einschließlich Netzwerkschnittstellen) beendet hat.

Wenn NM in der realen Root-Umgebung gestartet wird, registriert es sich auf dem D-Bus, konfiguriert das Netzwerk und bleibt aktiv, um auf Ereignisse oder D-Bus-Anforderungen zu reagieren. In der initrd wird NetworkManager in configure-and-quit=initrd ausgeführt Modus, der sich nicht auf dem D-Bus registriert (da er in der initrd zumindest vorerst nicht verfügbar ist) und nach Erreichen des startup-complete beendet wird Veranstaltung.

Das Startup-Complete Das Ereignis wird ausgelöst, nachdem alle Geräte mit einem übereinstimmenden Verbindungsprofil versucht haben, sich zu aktivieren, ob erfolgreich oder nicht. Sobald alle Schnittstellen konfiguriert sind, beendet sich NM und ruft Dracut-Hooks auf, um andere Module darüber zu informieren, dass das Netzwerk verfügbar ist.

Beachten Sie, dass /run/NetworkManager Verzeichnis, das generierte Verbindungsprofile und anderen Laufzeitstatus enthält, wird in das echte Stammverzeichnis kopiert, sodass der neue NetworkManager-Prozess, der dort ausgeführt wird, genau weiß, was zu tun ist.

Fehlerbehebung

Wenn Sie Netzwerkprobleme in dracut haben, enthält dieser Abschnitt einige Vorschläge zur Untersuchung des Problems.

Als erstes müssen Sie rd.debug hinzufügen zur Kernel-Befehlszeile, wodurch die Debug-Protokollierung in Dracut aktiviert wird. Protokolle werden unter /run/initramfs/rdsosreport.txt gespeichert und sind auch in der Zeitschrift verfügbar.

Wenn das System nicht bootet, ist es hilfreich, eine Shell in die initrd-Umgebung zu bekommen, um manuell zu überprüfen, warum die Dinge nicht funktionieren. Dafür gibt es einen rd.break Kommandozeilenargument. Beachten Sie, dass das Argument eine Shell erzeugt, wenn die initrd ihre Arbeit beendet hat und dabei ist, die Kontrolle an den init-Prozess im echten Root-Dateisystem zu übergeben. Um in einer anderen Phase von dracut zu stoppen (z. B. nach der Befehlszeilenanalyse), verwenden Sie das folgende Argument:

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

Das initrd-Image enthält einen minimalen Satz von Binärdateien; Wenn Sie ein bestimmtes Werkzeug in der Dracut-Shell benötigen, können Sie das Bild neu erstellen und hinzufügen, was fehlt. Zum Beispiel, um den Ping hinzuzufügen und tcpdump Binärdateien (einschließlich aller ihrer abhängigen Bibliotheken), führen Sie aus:

# dracut -f  --install "ping tcpdump"

und überprüfen Sie dann optional, ob sie erfolgreich eingefügt wurden:

# 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

Der Generator

Wenn Sie mit der NetworkManager-Konfiguration vertraut sind, möchten Sie vielleicht wissen, wie eine bestimmte Kernel-Befehlszeile in NetworkManager-Verbindungsprofile übersetzt wird. Dies kann nützlich sein, um den Konfigurationsmechanismus besser zu verstehen und Syntaxfehler in der Befehlszeile zu finden, ohne den Rechner booten zu müssen.

Der Generator wird in /usr/libexec/nm-initrd-generator installiert und muss mit der Liste der Kernel-Argumente nach einem doppelten Bindestrich aufgerufen werden. Die --stdout Option gibt die generierten Verbindungen auf der Standardausgabe aus. Versuchen wir, den Generator mit einer Beispielbefehlszeile aufzurufen:

$ /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 diesem Beispiel meldet der Generator einen Fehler, weil nach enp1s0 ein Feld für die MTU fehlt . Sobald der Fehler behoben ist, ist das Parsing erfolgreich und das Tool gibt das generierte Verbindungsprofil aus:

$ /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]

Beachten Sie, wie rd.peerdns=0 Argument wird in ignore-auto-dns=true übersetzt -Eigenschaft, wodurch NetworkManager über DHCP empfangene DNS-Server ignoriert. Eine Erläuterung der NetworkManager-Eigenschaften finden Sie auf der Manpage nm-settings.

[ Netzwerk gerät außer Kontrolle? Sehen Sie sich Netzwerkautomatisierung für alle an, ein kostenloses Buch von Red Hat. ] 

Schlussfolgerung

Das Dracut-Modul NetworkManager ist standardmäßig in Fedora aktiviert und wird bald auch auf RHEL aktiviert. Es bringt eine bessere Integration zwischen dem Netzwerk in der initrd und dem NetworkManager, der im echten Root-Dateisystem läuft.

Obwohl die aktuelle Implementierung gut funktioniert, gibt es einige Ideen für mögliche Verbesserungen. Eine besteht darin, configure-and-quit=initrd aufzugeben Modus und führen Sie NetworkManager als Daemon aus, der von einem systemd-Dienst gestartet wird. Auf diese Weise wird NetworkManager auf die gleiche Weise ausgeführt, als ob es im echten Stammverzeichnis ausgeführt würde, wodurch der zu wartende und zu testende Code reduziert wird.

Um configure-and-quit=initrd vollständig zu löschen Modus sollte NetworkManager auch in der Lage sein, sich auf D-Bus in der initrd zu registrieren. Derzeit hat dracut kein Modul, das einen D-Bus-Daemon bereitstellt, da das Bild minimal sein sollte. Es gibt jedoch bereits Vorschläge, es aufzunehmen, da es zur Implementierung einiger neuer Funktionen benötigt wird.

Wenn D-Bus in der initrd ausgeführt wird, wird die leistungsstarke API von NetworkManager für andere Tools verfügbar sein, um den Netzwerkstatus abzufragen und zu ändern, wodurch eine breite Palette von Anwendungen freigeschaltet wird. Eine davon ist das Ausführen von nm-cloud-setup in der initrd. Der Dienst, der im NetworkManager-cloud-setup ausgeliefert wird Das Fedora-Paket ruft Metadaten von der Infrastruktur des Cloud-Anbieters (EC2, Azure, GCP) ab, um das Netzwerk automatisch zu konfigurieren.


Linux
  1. Das Namensspiel:Benennen von Netzwerkschnittstellen in Linux

  2. So verwenden Sie den Linux-Befehl mtr

  3. Linux – Warum kann der Kernel Init nicht ausführen?

  4. Linux – Proprietäre oder geschlossene Teile des Kernels?

  5. Ist es möglich, den Linux-Kernel zu booten, ohne ein initrd-Image zu erstellen?

Wie der Linux-Kernel mit Interrupts umgeht

So überprüfen Sie die Kernel-Version in Linux

So verwenden Sie den netstat-Befehl unter Linux

Hinzufügung eines neuen Netzwerkprotokolls im Linux-Kernel

Wie lädt Linux das 'initrd'-Image?

So stellen Sie die bevorzugte Netzwerkschnittstelle unter Linux ein