Sie fragen sich, wie Sie Dienste im Hintergrund oder beim Booten verwalten können?

Der Mechanismus für die Verwaltung und den Start von Prozessen beim Booten hat sich geändert. Bis RHEL/CentOS 6.x hätten Sie ein Skript in /etc/init.d/ erstellt und mit Hilfe von chkconfig aktiviert, aber bei RHEL 7 ist das anders.

Er wurde durch systemd ersetzt, und da dies mehr oder weniger der Standardprozessmanager der wichtigsten Linux-Versionen ist, werden sich Systemadministratoren, die sich mit anderen Varianten auskennen, sofort zu Hause fühlen. In diesem Artikel erfahren Sie, was systemd ist, was die Gründe für den Wechsel waren und wie Sie systemd verwenden, um Hintergrundprozesse einzurichten, auszuführen und zu verwalten.

Was ist systemd?

Da jeder Prozess in Linux transparent sichtbar ist, wollen wir sehen, wo systemd lauert. Auf meinem System erhalte ich die folgende Anzeige:

 ~$ ps -ef | grep systemd
root 1 0 0 Nov11 ?        00:01:02 /lib/systemd/systemd --system --deserialize 22
nachricht 768 1 0 Nov11 ?        00:05:46 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root 805 1 0 Nov11 ?        00:10:22 /lib/systemd/systemd-logind
ankush 1132 1 0 Nov11 ?        00:00:00 /lib/systemd/systemd --user
ankush 1176 1132 0 Nov11 ?        00:04:50 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
ankush 9772 20029 0 21:11 pts/6 00:00:00 grep --color=auto systemd
systemd 17298 1 0 Nov19 ? 00:00:12 /lib/systemd/systemd-resolved
systemd 17303 1 0 Nov19 ? 00:00:00 /lib/systemd/systemd-timesyncd
root 17307 1 0 Nov19 ? 00:00:02 /lib/systemd/systemd-journald
root 18182 1 0 Nov19 ? 00:00:00 /lib/systemd/systemd-udevd

Ich wette, Sie haben es sofort bemerkt. Der erste Prozess in der Auflistung wurde als Benutzer root gestartet und hat die pid 1.

Natürlich war dies der erste Prozess, den das System beim Booten startete. Sagen Sie hallo zu systemd. 🙂

Ganz einfach: systemd ist der “Mutterprozess”, der andere Prozesse im System startet, verwaltet und beendet und außerdem Informationen über deren Protokollierung, den Status des Dateisystems usw. bereitstellt.

Noch eine Anmerkung zum Namen. Der Name lautet tatsächlich systemd und nicht System D oder etwas anderes. Das “d” steht für Daemon, einen Standard-Linux-Prozess, der im Hintergrund arbeitet (lauert?) und nicht mit einer Terminalsitzung verknüpft ist.

Warum hat RHEL zu systemd gewechselt?

Wie wir bereits besprochen haben, ist systemd ein System- und Prozessmanager und ersetzt in RHEL 7 das bekannte Programm Upstart. Warum hat RHEL diese Entscheidung getroffen? Nun, dafür gibt es sehr gute Gründe, also lassen Sie uns einen kurzen Blick darauf werfen.

Parallele Dienstinitialisierung

Anders als das SysV-Init-Programm ist systemd in der Lage, Dienste parallel zu starten. Das init-Programm hingegen startet sie einzeln. In einer Zeit, in der selbst mobile Geräte über Multi-Core-CPUs verfügen, ist das Fehlen einer parallelen Initialisierung ein großes Manko.

Dynamische (heiße) Dienstverwaltung

Wenn Ihnen aufgefallen ist, dass USB-Laufwerke auf früheren Fedora-Systemen explizit gemountet werden müssen, während sie bei Ubuntu und ähnlichen Distributionen automatisch aufspringen, liegt das an systemd. Er ist in der Lage, Änderungen an der Hardware live zu erkennen und Dienste bei Bedarf zu beenden/zu starten. Manche mögen argumentieren, dass dies unnötig ist, aber für viele ist alles, was die kognitive Belastung reduziert, höchst willkommen.

Aufgeschobener Start von Diensten

systemd verkürzt die Bootzeiten, da es den Start von Diensten auf den Zeitpunkt verschieben kann, an dem er tatsächlich benötigt wird. Ein einfaches Beispiel sind Dienste, die sich auf das Netzwerkdateisystem beziehen. Wenn keine Netzwerkfestplatte verfügbar ist, macht es keinen Sinn, einen Dienst zu starten.

Schnellere Prozesskommunikation

Die parallelen Fähigkeiten von systemd wirken sich auch auf die Kommunikation zwischen den Prozessen aus. systemd ist in der Lage, parallel auf Sockets und den Systembus zuzugreifen, was die Wartezeiten der Prozesse auf Kommunikationsressourcen erheblich verkürzt.

Automatischer Neustart

Wenn ein Dienst abstürzt, kann systemd dies erkennen und versuchen, ihn neu zu starten. In den meisten Fällen reicht ein einfacher Neustart aus, damit eine Anwendung wieder funktioniert, es sei denn, es liegen grundlegendere Probleme vor.

Auf jeden Fall macht systemd hier das Leben eines Systemadministrators einfacher.

systemd in RHEL7 – Was ändert sich für Sysadmins?

Wenn Sie das ungute Gefühl haben, dass systemd nicht mit allem Schnickschnack aufwarten kann, haben Sie Recht. Es gibt ein paar wichtige Inkompatibilitäten, die RHEL-Sysadmins überraschen können. Werfen wir einen kurzen Blick darauf.

Eingeschränkte Runlevel-Unterstützung

systemd erkennt und unterstützt die Runlevels nur unzureichend. Es werden nicht alle Runlevel unterstützt, und für einige Ziele gibt es vielleicht sogar gar keine. In solchen Fällen gibt systemd “N” als Antwort auf die Runlevel-Befehle zurück, was bedeutet, dass es keinen entsprechenden Runlevel für dieses Ziel gibt. Alles in allem rät uns Red Hat, die Runlevel-Befehle nicht (!) zu verwenden.

Keine benutzerdefinierten Befehle

Dieser Punkt wird weh tun. Ein großer Vorteil von SysV war die Möglichkeit, benutzerdefinierte Befehle zu definieren, um eine bessere Funktionalität für die Verwaltung von Prozessen zu erhalten. Mit systemd gibt es diese Möglichkeit nicht und Sie müssen sich mit Start, Stopp, Status, Neustart usw. begnügen.

Nur für die Familie und nicht interaktiv

systemd behält (natürlich) den Überblick über die gestarteten Prozesse und speichert deren PIDs. Das Problem ist jedoch, dass systemd nicht mit Prozessen umgehen kann, die nicht von ihm gestartet wurden. Außerdem ist es für einen Benutzer nicht möglich, mit einem von systemd gestarteten Prozess zu interagieren. Alle Ausgaben werden in /dev/null gespeichert, so dass Sie sich keine Hoffnungen machen können, die Ausgaben mitzuschneiden.

Kein Kontext

Im Gegensatz zu init-Diensten erben die von systemd gestarteten Prozesse keine Umgebung von einem Benutzer im System. Mit anderen Worten: Informationen wie PATH und andere Systemvariablen sind nicht verfügbar, und jeder neue Prozess wird in einem leeren Kontext gestartet.

Wenn Ihnen diese Liste von Einschränkungen die Tränen in die Augen treibt, sind Sie nicht allein. systemd ist eine polarisierende Kraft in der Linux-Welt, und wenn Sie nach “systemd sucks” googeln, finden Sie jede Menge Lesestoff 😉

Wie startet man einen Dienst automatisch, wenn er nicht läuft?

Dies ist ein ziemlich häufiger Anwendungsfall bei Installationen. Wir müssen ein Programm in einer Sprache daemonisieren, in der es keine langlaufenden Prozesse gibt: PHP! Nehmen wir an, ich schreibe ein PHP-Skript, um eingehende Websocket-Verbindungen zu verarbeiten (schließlich haben wir eine Chat-Anwendung entwickelt!) und das Skript befindet sich in /home/ankush/chat_server/index.php.

Da Websocket-Verbindungen jederzeit auf den Server zugreifen können, muss dieser Prozess jederzeit verfügbar sein und die eingehenden Verbindungen überwachen. Wir können hier nicht den traditionellen PHP-Lebenszyklus verwenden, da WebSockets zustandsabhängige Verbindungen sind und wenn das Skript stirbt, ist die Verbindung eine Liste. Wie auch immer, genug über WebSockets. Schauen wir uns an, wie wir dieses Skript über systemd dämonisieren können.

Alle systemd-Dienste befinden sich in /etc/systemd/system, also erstellen wir dort eine Datei, die unser Websocket-Server-Skript beschreibt. Angenommen, Sie sind als Root-Benutzer eingeloggt.

# vi /etc/systemd/system/chat_server.service

und dann wird Folgendes benötigt.

 [Einheit]
Beschreibung=Chat Server Service
Nach=network.target

[Dienst]
Typ=einfach
Benutzer=ankush
ExecStart=php /home/ankush/chat_server/index.php
Neustart=bei Abbruch


[Installieren]
WantedBy=multi-user.target

Speichern Sie die Datei und laden Sie im nächsten Schritt den systemd-Daemon neu

 # systemctl daemon-reload

und den Dienst zu starten, den wir gerade erstellt haben:

 # systemctl start chat_server

Wenn Sie keine Fehler sehen, war’s das!

Werfen wir noch schnell einen Blick darauf, was die verschiedenen Direktiven in der Datei bedeuten:

  • Der Teil [Unit] definiert eine neue Diensteinheit für systemd. Im Sprachgebrauch von systemd werden alle Dienste als Diensteinheiten bezeichnet.
  • Die Anweisung After weist systemd (vorhersehbarerweise) an, diesen Dienst erst nach dem Start der Netzwerkdienste zu starten (wer würde sonst die untergeordnete Behandlung von Socket-Verbindungen übernehmen?!).
  • Die Anweisung Type=simple teilt systemd mit, dass sich dieser Dienst nicht selbst aufspalten soll. Mit anderen Worten, es wird immer nur eine Instanz laufen.
  • User=ankush bedeutet, dass dieser Dienst unter dem Benutzer “ankush” ausgeführt wird. Wir könnten dies in “root” ändern, aber das ist aus Sicherheitsgründen nicht empfehlenswert.
  • ExecStart ist, wie Sie sehen können, der eigentliche Befehl, der ausgeführt wird.
  • Restart=on-abort bedeutet, dass der Dienst neu gestartet werden soll, wenn er abbricht. In PHP lecken lang laufende Prozesse Speicher und explodieren schließlich, daher ist dies notwendig.
  • Die Direktive WantedBy= teilt systemd mit, zu welchem Ziel (denken Sie an Gruppen) dieser Dienst gehört. Dies führt dazu, dass innerhalb dieses Ziels symbolische Links erstellt werden, die auf den Dienst verweisen.

Im Allgemeinen reicht dies für die Ausführung von Hintergrundprozessen mit systemd in RHEL 7 aus.

Weitere Optionen für die Neustart-Logik

In dem obigen Beispiel habe ich Restart=on-abort konfiguriert, aber das ist nicht die einzige Option. Es gibt noch weitere Optionen, die Sie je nach Bedarf auswählen können.

  • on-failure – wird neu gestartet, wenn der Exit-Code oder das Signal unsauber ist
  • always – Neustart, wenn ein Abbruch festgestellt wird, sauberes oder unsauberes Signal
  • on-abnormal – unsauberes Signal, Watchdog oder Timeout
  • on-success – nur wenn es durch ein sauberes Signal oder einen Exit-Code gestoppt wurde

Dienst für den Start beim Booten konfigurieren

Wenn Sie mit dem Skript zufrieden sind und sicherstellen, dass es funktioniert, müssen Sie es so konfigurieren, dass es beim Booten ausgelöst und gestartet wird.

Gehen Sie zu /etc/systemd/system und führen Sie den folgenden Aktivierungsbefehl aus (vergessen Sie nicht, den Namen der .service-Datei mit dem Ihrer eigenen zu ändern)

 # systemctl enable chat_server.service

Sie werden eine Bestätigung sehen, dass ein Symlink erstellt wurde.

 Symlink von /etc/systemd/system/multi-user.target.wants/chat_server.service nach /etc/systemd/system/chat_server.service erstellt.

Starten Sie Ihren Server neu und Sie sollten sehen, dass der Dienst beim Booten startet.

Das war ganz einfach! Oder etwa nicht?

Hilfe! Ich habe sehr viel in Upstart investiert 🙁

Ich kann Sie verstehen, Ihr Fall ist eher die Norm als die Ausnahme. RHEL verwendet Upstart schon so lange, dass sich der Wechsel fast wie ein Verrat anfühlt. Aber hey, Systeme ändern sich ständig, und wir sollten uns nicht über Kleinigkeiten streiten. Red Hat ist sich bewusst, dass viele Benutzer noch mit älteren Versionen arbeiten und hat einen Migrationsleitfaden erstellt, den Sie sich unbedingt ansehen sollten.

Ein kleiner Trost ist, dass systemd mit den SysV-Init-Skripten kompatibel ist, so dass Sie in den meisten Fällen nur Ihre Dateien verschieben und die gleichen Dienste nutzen müssen.

Möchten Sie mehr über Linux-Administration und Fehlerbehebung erfahren? Schauen Sie sich diesen Online-Kurs an.