Systemd-Targets verstehen: Wichtige Konzepte erklärt
Verstehen Sie Systemd-Targets, Standard-Boot-Targets, Runlevel-Zuordnungen, Isolation, benutzerdefinierte Targets und Fehlerbehebungsbefehle.
Systemd-Targets verstehen: Wichtige Konzepte erklärt
Systemd-Targets sind leichter zu verstehen, wenn Sie aufhören, sie als Dienste zu betrachten. Ein Dienst startet einen Prozess. Ein Target gruppiert Units in einen benannten Systemzustand. Wenn ein Rechner zu multi-user.target bootet, startet systemd kein Programm namens "multi-user". Es versucht, einen Zustand zu erreichen, in dem die von diesem Target gewünschten Units gestartet wurden oder zumindest deren Start-Jobs versucht wurden.
Diese Unterscheidung hilft bei der Fehlersuche bei Boot-Problemen. Wenn graphical.target langsam ist, ist das Target selbst selten das Problem. Eine der Display-, Login-, Netzwerk-, Mount- oder Anwendungs-Units, die in dieses Target eingebunden sind, ist langsam oder schlägt fehl. Targets geben Ihnen die Karte.
Was sind Systemd-Targets?
Im systemd-Ökosystem ist ein Target ein spezieller Unit-Dateityp (wie .service- oder .socket-Dateien), der einem kritischen organisatorischen Zweck dient. Im Gegensatz zu Service-Units, die definieren, wie ein bestimmter Prozess gestartet oder gestoppt wird, definieren Target-Units einen Systemzustand oder eine Sammlung von Units, die gemeinsam aktiv sein sollen. Sie fungieren als logische Gruppierungspunkte und Synchronisationspunkte für andere systemd-Units.
Betrachten Sie Targets als Meilensteine auf der Betriebsreise des Systems. Wenn systemd bootet, startet es nicht einfach willkürlich eine Liste von Diensten; es arbeitet darauf hin, ein bestimmtes Target zu erreichen. Dieses Target wiederum zieht alle notwendigen Dienste, Sockets, Mountpunkte und anderen Targets hinein, die für diesen Zustand erforderlich sind. Dieser abhängigkeitsgesteuerte Ansatz gewährleistet einen vorhersagbaren und effizienten Bootvorgang.
Für diejenigen, die mit älteren Linux-Init-Systemen wie SysVinit vertraut sind, sind systemd-Targets das moderne Äquivalent zu Runleveln. Während SysVinit einen festen Satz von Runleveln hatte (z. B. Runlevel 3 für den Mehrbenutzer-Textmodus, Runlevel 5 für den Mehrbenutzer-Grafikmodus), sind systemd-Targets flexibler. Sie werden benannt, nicht nummeriert, und Sie können benutzerdefinierte Targets definieren, was eine größere Granularität und Erweiterbarkeit bietet.
Wie Targets funktionieren: Gruppierung und Abhängigkeiten
Targets erreichen ihre Gruppierungs- und Zustandsdefinitionsfähigkeiten durch explizite Abhängigkeiten, die in ihren Unit-Dateien definiert sind. Die primären Direktiven, die dafür verwendet werden, sind Wants=, Requires=, After= und Before=.
Wants=: Gibt "schwache" Abhängigkeiten an. WennTarget AWants=Unit B, wird systemd versuchen,Unit Bzu starten, wennTarget Aaktiviert wird. Allerdings wirdTarget Atrotzdem starten, selbst wennUnit Bnicht startet. Dies wird häufig verwendet, um verwandte Dienste zu gruppieren, die wünschenswert, aber nicht unbedingt erforderlich sind.Requires=: Gibt "starke" Abhängigkeiten an. WennTarget ARequires=Unit B, mussUnit Berfolgreich gestartet werden, damitTarget Aaktiviert wird. WennUnit Bfehlschlägt, wird auchTarget Afehlschlagen oder nicht starten. Dies wird für kritische Abhängigkeiten verwendet.After=: Definiert eine Reihenfolgeabhängigkeit. WennTarget AAfter=Unit Bhat, wirdTarget Aerst nach dem Start vonUnit Bstarten. Dies impliziert keine Abhängigkeit vom Erfolg, sondern nur die Reihenfolge.Before=: Das Gegenteil vonAfter=. WennTarget ABefore=Unit Bhat, wirdUnit Berst nach dem Start vonTarget Astarten.Conflicts=: Stellt sicher, dass bestimmte Units nicht gleichzeitig aktiv sind. WennTarget AConflicts=Unit Bhat, wird die Aktivierung vonTarget AUnit Bstoppen, falls es läuft, und umgekehrt.
Diese Direktiven ermöglichen es Targets, als robuste Orchestratoren zu fungieren, die Dienste und andere Targets nach Bedarf einbinden und die Reihenfolge definieren, in der sie starten sollen. Beispielsweise hat multi-user.target typischerweise Wants= network.target und verschiedene andere Dienste, um sicherzustellen, dass sie aktiv sind, wenn das System einen Mehrbenutzerzustand erreicht.
Sie können den Inhalt einer Target-Unit-Datei einsehen, um ihre Abhängigkeiten zu sehen:
systemctl cat multi-user.target
Dieser Befehl gibt den Inhalt der multi-user.target-Unit-Datei aus und zeigt deren Description, Documentation und entscheidend ihre Wants=-, Requires=-, After=- und andere Direktiven, die definieren, was den Mehrbenutzerzustand ausmacht.
Häufige Systemd-Targets erklärt
Systemd bietet eine Vielzahl vordefinierter Targets, die jeweils einem bestimmten Systemzustand oder einer bestimmten Funktionalität entsprechen. Das Verständnis dieser ist für die Systemadministration entscheidend:
default.target: Dies ist das wichtigste Target, da es den Standardzustand definiert, in den Ihr System booten wird. Es ist normalerweise ein Symlink entweder aufgraphical.target(für Desktops) odermulti-user.target(für Server).graphical.target: Dieses Target wird typischerweise für Systeme mit einer grafischen Desktop-Umgebung verwendet. Es bindetmulti-user.targetein und fügt dann Dienste hinzu, die für den grafischen Login-Manager und den Display-Server erforderlich sind (z. B. GDM, LightDM, Xorg, Wayland).multi-user.target: Dies ist der Standardzustand für Mehrbenutzersysteme ohne grafische Oberfläche. Es ist üblich für Server und stellt alle notwendigen Dienste für den Kommandozeilenzugriff, Netzwerk und die meisten Daemon-Operationen bereit.basic.target: Ein minimaler Zustand, der grundlegende Systemdienste für fundamentale Operationen umfasst, aber vormulti-user.target. Es bindet typischerweisesysinit.targetund andere wesentliche Dienste ein.sysinit.target: Dieses Target wird sehr früh im Bootvorgang erreicht. Es ist verantwortlich für Kern-Systeminitialisierungsaufgaben wie das Mounten von/etc/fstab-Dateisystemen (außer entfernten), das Einrichten von Swap und andere hardwarebezogene Initialisierungen.local-fs.target: Stellt sicher, dass alle lokalen Dateisysteme, die in/etc/fstabangegeben sind, gemountet werden.remote-fs.target: Stellt sicher, dass alle entfernten Dateisysteme (z. B. NFS, CIFS), die in/etc/fstabangegeben sind, gemountet werden.network.target: Zeigt an, dass grundlegende Netzwerkkonnektivität verfügbar ist (z. B. Netzwerkschnittstellen sind aktiv). Es garantiert keine vollständige Internetverbindung oder IP-Adresszuweisung.network-online.target: Ein Synchronisationspunkt für Dienste, die warten möchten, bis der Netzwerkmanager das Netzwerk als online betrachtet. Es beweist nicht, dass das Internet, DNS oder eine entfernte API erreichbar ist, und funktioniert nur wie erwartet, wenn der entsprechende Wait-Online-Dienst aktiviert ist.rescue.target: Bietet eine Einzelbenutzer-Shell mit minimal laufenden Diensten und gemounteten lokalen Dateisystemen. Nützlich für Systemwiederherstellung und Fehlerbehebung.emergency.target: Eine noch minimalere Umgebung alsrescue.target. Es bietet eine Shell auf dem Root-Dateisystem, das typischerweise schreibgeschützt gemountet ist. Es werden keine anderen Dienste gestartet. Für kritische Notfallsituationen.poweroff.target,reboot.target,halt.target: Diese Targets werden verwendet, um das System herunterzufahren, neu zu starten oder anzuhalten. Bei Aktivierung stoppen sie die meisten Dienste und bereiten das System auf den gewünschten Energiezustand vor.
Verwalten von Systemd-Targets
Die Interaktion mit systemd-Targets erfolgt hauptsächlich über das Kommandozeilenprogramm systemctl.
Anzeigen aktiver und Standard-Targets
Um zu sehen, in welchem Target Ihr System derzeit läuft:
systemctl get-default
Um alle derzeit geladenen Target-Units aufzulisten:
systemctl list-units --type=target
Dieser Befehl zeigt aktive, geladene und statische Targets zusammen mit ihren Beschreibungen an.
Ändern des Standard-Boot-Targets
Sie können das Target ändern, in das Ihr System standardmäßig bootet. Um beispielsweise multi-user.target als Standard festzulegen:
sudo systemctl set-default multi-user.target
Um zu graphical.target zurückzukehren:
sudo systemctl set-default graphical.target
Dieser Befehl erstellt einen symbolischen Link von /etc/systemd/system/default.target zur gewünschten Target-Datei.
Temporär in ein anderes Target booten
Manchmal müssen Sie nur einmal in ein bestimmtes Target booten (z. B. zur Fehlerbehebung). Sie können dies erreichen, indem Sie während des Bootvorgangs einen Kernel-Parameter anhängen. Wenn das GRUB-Bootmenü erscheint, bearbeiten Sie den Booteintrag (normalerweise durch Drücken von e) und fügen Sie systemd.unit=target_name.target zur Kernel-Befehlszeile hinzu.
Um beispielsweise in den Rettungsmodus zu booten:
systemd.unit=rescue.target
Wechseln von Targets während der Laufzeit
Sie können während des laufenden Systems mit dem Befehl systemctl isolate zu einem anderen Target wechseln. Dieser Befehl stoppt alle Dienste, die nicht vom neuen Target benötigt werden, und startet alle davon benötigten Dienste.
Warnung: Die Verwendung von systemctl isolate kann den Betrieb Ihres Systems stören, insbesondere wenn Sie auf einem Desktop-Rechner von graphical.target zu einem viel niedrigeren Target wie multi-user.target wechseln. Mit Vorsicht verwenden.
Um von graphical.target zu multi-user.target zu wechseln:
sudo systemctl isolate multi-user.target
Um zurück zu graphical.target zu wechseln (vorausgesetzt, es war der vorherige Zustand):
sudo systemctl isolate graphical.target
Erstellen benutzerdefinierter Targets
Obwohl systemd viele nützliche Targets bereitstellt, gibt es Situationen, in denen die Erstellung eines benutzerdefinierten Targets vorteilhaft ist. Dies gilt insbesondere für komplexe Anwendungsbereitstellungen, bei denen Sie mehrere Dienste gruppieren müssen, die immer zusammen starten und stoppen sollen, oder um eine bestimmte Umgebung für Ihre Anwendung zu definieren.
Um ein benutzerdefiniertes Target zu erstellen:
- Erstellen Sie eine
.target-Datei: Platzieren Sie sie in/etc/systemd/system/. Zum Beispielmy-application.target.# /etc/systemd/system/my-application.target [Unit] Description=Mein benutzerdefiniertes Anwendungs-Target Wants=my-database.service my-webserver.service After=my-database.service my-webserver.serviceDescription: Eine menschenlesbare Beschreibung.Wants=: Listen Sie die Dienste oder anderen Targets auf, die dieses Target einbinden soll.After=: Definieren Sie die Reihenfolge. Das Target startet nach diesen Units.
- Erstellen Sie die Dienste: Stellen Sie sicher, dass
my-database.serviceundmy-webserver.service(oder welche Dienste Sie auch auflisten) existieren und ordnungsgemäß konfiguriert sind. - Laden Sie systemd neu: Informieren Sie systemd über die neue Unit-Datei.
sudo systemctl daemon-reload
4. **Aktivieren und Starten**: Sie können jetzt Ihr benutzerdefiniertes Target aktivieren und starten, was wiederum seine gewünschten Dienste startet. bash
sudo systemctl enable my-application.target
sudo systemctl start my-application.target
```
Dies ermöglicht es Ihnen, eine Gruppe verwandter Dienste als eine einzige logische Einheit zu verwalten, was komplexe Anwendungsbereitstellungen vereinfacht.
Runlevel und Targets ohne die Nebelkerzen
Wenn Sie von SysVinit kommen, ist die grobe Zuordnung:
| Alte Runlevel-Idee | Häufiges systemd-Target |
|---|---|
| Einzelbenutzer-Reparaturmodus | rescue.target |
| Mehrbenutzer-Textmodus | multi-user.target |
| Mehrbenutzer-Grafikmodus | graphical.target |
| Neustart | reboot.target |
| Herunterfahren | poweroff.target |
Behandeln Sie dies als Übersetzungshilfe, nicht als perfektes Modell. SysV-Runlevel waren ein kleiner fester Satz nummerierter Zustände. Systemd-Targets sind benannte Units mit Abhängigkeiten, und es kann viele davon geben. Ein Paket kann sein eigenes Target installieren. Sie können eines für einen Bereitstellungsworkflow erstellen. Einige Targets sind für die Isolation gedacht; andere sind nur Gruppierungspunkte, die während des Bootvorgangs verwendet werden.
Sie können sehen, welche Targets eine Isolation erlauben mit:
systemctl show multi-user.target -p AllowIsolate
systemctl show basic.target -p AllowIsolate
Dies ist wichtig, weil systemctl isolate kein harmloser "Ansicht wechseln"-Befehl ist. Es stoppt Units, die nicht Teil der neuen Target-Transaktion sind. Auf einem Desktop wird das Isolieren von multi-user.target normalerweise die grafische Sitzung beenden. Auf einem entfernten Server kann das Isolieren des falschen Targets Netzwerk- oder Login-Dienste stoppen und Sie aussperren.
Wie Dienste Teil eines Targets werden
Die meisten alltäglichen Target-Mitgliedschaften stammen aus dem [Install]-Abschnitt einer Service-Datei:
[Install]
WantedBy=multi-user.target
Wenn Sie ausführen:
sudo systemctl enable myapp.service
erstellt systemd einen Symlink unter einem Verzeichnis wie:
/etc/systemd/system/multi-user.target.wants/myapp.service
Dieser Symlink bewirkt, dass multi-user.target den Dienst während des Bootvorgangs haben möchte. Die Service-Datei kann existieren und vollkommen gültig sein, ohne aktiviert zu sein. In diesem Fall wird das Starten von multi-user.target sie nicht automatisch einbinden.
Aus diesem Grund lösen systemctl start myapp.service und systemctl enable myapp.service unterschiedliche Probleme. start führt es jetzt aus. enable verdrahtet es in ein zukünftiges Boot-Target. enable --now macht beides.
Um zu überprüfen, ob ein Dienst für ein Target aktiviert ist:
systemctl is-enabled myapp.service
systemctl list-dependencies multi-user.target | grep myapp
Wenn ein Dienst manuell startet, aber nicht beim Booten, ist dies eines der ersten Dinge, die Sie überprüfen sollten.
Ein kleines benutzerdefiniertes Target, das tatsächlich nützlich ist
Benutzerdefinierte Targets sind am nützlichsten, wenn sie Operatoren einen einzigen Befehl für eine Gruppe verwandter Units geben. Stellen Sie sich einen einfachen Anwendungsstack vor:
app-api.service
app-worker.service
app-scheduler.service
Sie können erstellen:
# /etc/systemd/system/app-stack.target
[Unit]
Description=Anwendungsstack
Wants=app-api.service app-worker.service app-scheduler.service
After=network-online.target
Wants=network-online.target
AllowIsolate=no
Fügen Sie dann jeden Dienst zum Target hinzu:
[Install]
WantedBy=app-stack.target
Nach daemon-reload aktivieren Sie die Dienste oder das Target, je nachdem, welches Verhalten Sie wünschen:
sudo systemctl daemon-reload
sudo systemctl enable app-api.service app-worker.service app-scheduler.service
sudo systemctl start app-stack.target
Dies gibt Ihnen eine lesbare Gruppierung, ohne so zu tun, als sei das Target ein Prozess-Supervisor. Wenn app-worker.service fehlschlägt, überprüfen Sie diesen Dienst. Das Target ist nur der Gruppierungspunkt.
Wenn Sie möchten, dass das Stoppen des Targets alle Stack-Dienste stoppt, fügen Sie PartOf=app-stack.target zu jedem Dienst hinzu:
[Unit]
PartOf=app-stack.target
Jetzt propagiert systemctl stop app-stack.target zu den Mitgliedsdiensten. Das ist oft das fehlende Stück in Beispielen für benutzerdefinierte Targets.
Fehlerbehebung mit Targets
Targets sind auch für die Fehlerbehebung bei Boot-Problemen oder Dienstausfällen von unschätzbarem Wert:
- Identifizieren von Abhängigkeiten: Wenn ein Dienst nicht startet, kann die Überprüfung des Targets, zu dem er gehört, fehlende oder fehlschlagende Abhängigkeiten aufdecken. Verwenden Sie
systemctl status <dienst_name>undsystemctl list-dependencies <target_name>. - Booten in minimale Targets: Wenn Ihr System nicht in
graphical.targetodermulti-user.targetbootet, versuchen Sie, mit der Kernel-Parameter-Methode inrescue.targetoderemergency.targetzu booten. Dies bietet eine minimale Umgebung, in der Sie Probleme diagnostizieren können, ohne die Komplexität vieler laufender Dienste. - Protokolle prüfen: Überprüfen Sie nach dem Versuch, ein Target oder einen Dienst zu starten, immer die
journalctl-Protokolle auf Fehler:journalctl -b -u <target_oder_dienst_name>
Best Practices und Tipps
- Verwenden Sie
network-online.targetmit Bedacht: Wenn Ihr Dienst vor dem Start eine Netzwerkkonfiguration benötigt, kombinieren SieAfter=network-online.targetmitWants=network-online.targetund bestätigen Sie, dass die entsprechende Wait-Online-Unit aktiviert ist. Behalten Sie dennoch Wiederholungslogiken in der Anwendung für entfernte Abhängigkeiten bei. - Verstehen Sie die Boot-Reihenfolge: Machen Sie sich mit dem allgemeinen Ablauf von
sysinit.targetüberbasic.targetzumulti-user.target/graphical.targetvertraut. Dies hilft bei der Fehlersuche bei Diensten, die früh im Bootvorgang fehlschlagen. - Seien Sie vorsichtig mit
default.target: Das Ändern vondefault.targetkann das Bootverhalten Ihres Systems erheblich verändern. Testen Sie benutzerdefinierte Konfigurationen immer zuerst in einer Nicht-Produktionsumgebung. - Verwenden Sie
Wants=für nicht-kritische Abhängigkeiten: Für Dienste, die nützlich, aber nicht unbedingt erforderlich sind, damit ein Target als "aktiv" gilt, verwenden SieWants=anstelle vonRequires=. Dies verhindert, dass ein einzelner optionaler Dienstausfall kaskadiert und die Aktivierung des gesamten Targets verhindert.
Das mentale Modell, das Sie behalten sollten
Ein Target ist ein benannter Zustand, kein Daemon. default.target bestimmt das normale Boot-Ziel. multi-user.target ist der übliche Serverzustand. graphical.target fügt den Display-Stack hinzu. rescue.target und emergency.target sind Reparaturwerkzeuge. Benutzerdefinierte Targets sind Gruppierungswerkzeuge, wenn sie Operationen klarer machen.
Wenn etwas Target-bezogenes kaputt geht, vermeiden Sie es, zuerst dem Target die Schuld zu geben. Fragen Sie, welche Unit eingebunden wurde, welche Reihenfolgeregel sie verzögert hat und welche Abhängigkeit fehlgeschlagen ist. systemctl cat, systemctl list-dependencies, systemctl show und journalctl -b werden diese Fragen normalerweise schneller beantworten als das Lesen generischer Boot-Diagramme.