orm@doc-tcpip.org

Erstellt: Januar 2016 - Letzte Modifikation: Februar 2020

[ Main | Local ]


Systemd - Initialisierung und Wartung eines Systems


Systemd - Basics

Ein integriertes System, um Services und Daemonen zu starten und zu kontrollieren. Es gibt keine irgendwie gearteten init-Files mehr, es erinnert aber stark an den SRC (System Resource Controler" von AIX.

Verwalten kann man allerlei Resourcen (sogenannte Units), welche meistens Services sind, aber auch Sockets oder Devices etc. sein können. Wie so eine Unit zu behandeln ist, wird in einem Unit-File konfiguriert.

Eine solche Unit muss dem Systemd bekannt gemacht werden, erst dann wird sie verwaltet. Soll eine Unit automatisch gestartet werden, muss sie einem Target zugeordnet werden. Das entspricht in etwa den bekannten Run-Level eines Systemes.

Es gibt weiterhin ein Journal, was alle Logging Informationen zusammenfasst.

Interface zum Benutzer: systemctl Kommando

Per Default läuft die Ausgabe in einen Pager, "less". Das ist eher nervig, und man kann es mit der Option --no-pager abschalten.

Mit einer Shell Variable wird das zum Standard: $SYSTEMD_PAGER. Setzt man die auf den leeren String, oder auf "cat", dann hat man das normale Verhalten (Also einfach in der lokalen Konfiguration für die Shell, zb. .bashrc, einen Eintrag machen: "export SYSTEMD_PAGER=").

Teilweise sind die Zeilen der Ausgabe sehr lang und werden abgeschnitten, für einen besseren Überblick. Auch das kann man unterbinden, mit -l.

Ein Beispiel:

     systemctl --no-pager status -l sshd

Start/Stop

     systemctl start mein_dienst.service
     systemctl stop mein_dienst.service  
     systemctl restart mein_dienst.service  ==> Restart - ein "reboot" der Unit
     systemctl reload mein_dienst.service   ==> Reload - ohne Unterbrechung der Funktion
     (es gibt noch einige Kombinationen, siehe systemctl --help ...)

Es ist nicht sicher, ob die entsprechende Unit einen Reload zulässt. Man kann daher gleich die Alternative mitbestellen:

     systemctl reload-or-restart application.service

Status einer Unit

Gibt den aktuellen Zustand, Informationen zum Prozess, und die letzten Einträge im Journal.

     systemctl status mein_dienst.service

Die Einträge im Journal kann man sich explizit ansehen:

     journalctl -u mein_dienst.service    - alle Log Einträge dieser Unit
     journalctl -b -u mein_dienst.service - alle Log Einträge dieser Unit seit dem letzten Boot

Um den Status einer Unit in einem Script abzufragen, gibt es Alternativen, die 0 und 1 zurückgegen:

     systemctl is-active application.service
     systemctl is-enabled application.service
     systemctl is-failed application.service

Welche Units verwaltet der Systemd auf einem gegebenen System?

Dazu muss man sich die Unit-Files ansehen.

Aktive Units:

     systemctl list-units
    
     Die Felder der Ausgabe:
     UNIT: Der Name der Unit
     LOAD: Ist das Unit-File vom Systemd eingelesen worden?
     ACTIVE: Ist die Unit im Moment aktiv?
     SUB: Ein tiefergehender Status der Unit
     DESCRIPTION: Tja, was wohl?

Alle Units:

     systemctl list-units --all

     Man kann filtern, z.B: nach Status oder Typ:
     systemctl list-units --all --state=inactive
     systemctl list-units --type=service

Welche Unit-Files gibt es:

     systemctl list-unit-files

     Anmerkung: Status ist in der Regel: enabled, disabled, static oder masked.
     Der Status static bedeutet, dass die Unit keine Sektion "install" hat. Man kann sie also
     nicht enablen - diese Unit is nur dafür gedacht, einmal zu laufen und hängt von anderen
     Units ab. Sie ist nicht dafür gedacht, alleine zu laufen.

     Der Status masked bedeutet, das der Service garnicht startbar ist. Das Unit-File wird dabei
     gegen /dev/null gelinkt. Um so einen Service wieder zu enablen, muss man ihn erst "unmasken"

Eine Unit einrichten bzw. entfernen

     systemctl enable mein_dienst.service
     systemctl disable mein_dienst.service

Es wird ein symbolischer Link erzeugt, der von der Konfiguration abhängt. Die Unit-Files liegen in /lib/systemd/system oder /etc/systemd/system und werden zu den Targets verlinkt - meist in /etc/systemd/system/ein_target.target.wants.

Um einen Service zu "löschen":

     systemctl mask mein_dienst.service

Um einen "gelöschten" Service wieder erreichbar zu machen:

     systemctl unmask mein_dienst.service

Die Konfiguration einer Unit

Unit-File anzeigen:

     systemctl cat mein_dienst.service

Die Abhängigkeiten einer Unit anzeigen:

Das kann man sich manuell zusammen suchen, indem man sich die Units anzeigen lässt. Alle abhängigen Units muss man dann analog untersuchen, hier ein Beispiel:

    systemctl show network |grep -si want
    Wants=network-online.target network.target

    systemctl show network |grep -si req
    Requires=basic.target system.slice

    systemctl list-dependencies mein_dienst.service (Target Units werden expandiert)
    systemctl list-dependencies --all mein_dienst.service (alle abhängigen Units werden expandiert) 

Mit dem Flag --reverse kann man alle Units anzeigen, die auf die aktuelle Unit angewiesen sind. Mit den Flags --before und --after kann man die Abhängigkeiten der vorigen und der nächsten Unit anzeigen.

Es ist auch möglich, die Dependencies grafisch darzustellen. Das geht mit dem systemd-analyze Kommando und einer Grafik-Package. Das Kommando erzeugt Files, die man in ein Grafik-Format umwandeln kann:

    # yum -y install graphviz
    # systemd-analyze dot network.service | dot -Tsvg > network-dep.svg

Die Konfiguration einer Unit anzeigen:

Alle Parameter, die Systemd für diese Unit verwaltet, werden angezeigt.

     systemctl show mein_dienst.service

Spezifische Parameter, die Systemd für diese Unit verwaltet, werden angezeigt.

     systemctl show sshd.service -p UMask

Ein Unit-File modifizieren:

     systemctl edit mein_dienst.service - ein "Snippet" hinzufügen - also Überschreiben oder Ergänzen

Damit wird ein Snippet hinzugefügt. Es wird ein Verzeichnis in /etc/systemd/system mit dem Namen der Unit angelegt, an den ein "d" angehängt wird. Also in diesem Fall mein_dienst.service.d. In dieses Verzeichnis wird ein .conf Files geschrieben, welches die Überschreibungen und Ergänzungen enthält.

     systemctl edit --full mein_dienst.service - das ganze File bearbeiten

Das File wird nach /etc/systemd/system und hat eine höhere Priorität wie die systemeigenen Unit-Files in /lib/systemd/system.

Um so eine Erweiterung wieder zu entfernen löscht man das .conf oder das ganze Verzeichnis der Unit.

     rm -r /etc/systemd/system/mein_dienst.service.d
     rm /etc/systemd/system/mein_dienst.service

Den Systemd-Daemon nach Änderungen neu starten:

     systemctl daemon-reload

Arbeiten mit Targets (Runlevels)

Ein Target beschreibt einen möglichen Zustand, indem man sein System betreiben will. Im Fall der Runlevel konnte man nur einen Aktiven haben. Die Targets kann man kombinieren, ein System könne zb. ein "multiuser" Target haben, und dazu ein "webserver" Target.

In welchen Target befindet sich mein System jetzt:

     systemctl list-units --type=target

Welche Targets hat mein System:

     systemctl list-unit-files --type=target

Was ist das Default-Target:

     systemctl get-default

Wenn man das ändern möchte:

     systemctl set-default multi-user.target

Welche Units sind an ein Target gebunden?

     systemctl list-dependencies multi-user.target

Um das System in genau einen Zustand zu bringen:

     systemctl isolate multi-user.target
     (alle Units, die nicht an diesem Target hängen, werden gestoppt)

Abhängigkeiten von Units definieren:

Dazu gibt es die Attribute WantedBy=, RequiredBy= sowie Wants=, Requires= and After=. Alle Units, die zum Erreichen eines Targets nötig sind, müssen das in ihrer Konfiguration durch WantedBy= oder RequiredBy= ausdrücken. Das Target wird dann nur erreicht, wenn diese Units gestartet werden konnten.

Eine Unit, die eine andere Unit oder ein bestimmtes Target braucht, um selbst starten zu können, drückt dies mit Wants= oder Requires= aus.

Im Systemd sind verschiedene Targets definiert, was ungefähr den bekannten Runleveln entspricht. Targets werden über Abhängigkeiten von Services aufgebaut, so ist sichergestellt, das alle nötigen Services gestartet werden.

Diese "Dependencies" setzen sich zusammen aus der Definiton des Targets in seinem Unit File und aus zusätzlichen Abhängigkeiten an folgenden Stellen:

     /etc/systemd/system/.d/
     /etc/systemd/system/.requires
     /etc/systemd/system/.wants

Hier finden sich entweder Overrides zum Unit File, oder weitere Links zu anderen Units (in requires and wants).

"Requires" bedeutet, dass die abhängige Unit automatisch mitgestartet bzw. auch gestoppt wird. Mit "Before" und "After" kann man das zeitlich sortieren. Kommt die abhängige Unit nicht hoch, wird das Target nicht erreicht, und es bricht ab (das kann man mit "RequiresOverridable" als Administrator zum Testen unterbinden).

"Requisite" bedeutet, das die abhängige Unit schon laufen muss. Wenn nicht, wird das Target nicht erreicht. Das ist also eine verschärfte Version des "Requires".

"Wants" umgekehrt ist etwas schwächer. Die abhängige Unit wird gestartet, wenn das nicht klappt, gehts trotzdem weiter.

"Requires" und "Wants" können per Link in den genannten Verzeichnissen dargestellt werden.

"Conflicts" führt dazu, dass die abhängige Unit gestoppt wird, und das Target nur erreicht wird, wenn das auch funktioniert.

Das System Stoppen oder Booten:

     systemctl poweroff
     systemctl halt
     systemctl reboot
     systemctl rescue (single user mode)

[ Main | Local ]

[ Allgemein | UNIX | AIX | TCP-IP | TCP | ROUTING | DNS | NTP | NFS | FreeBSD | Linux | RPi | SMTP | Tracing | GPS | LW ]

Copyright 2001-2021 by Orm Hager - Es gilt die GPL
Feedback bitte an: Orm Hager (orm@doc-tcpip.org )