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ürsystemd
. Im Sprachgebrauch vonsystemd
werden alle Dienste als Diensteinheiten bezeichnet. - Die Anweisung
After
weistsystemd
(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
teiltsystemd
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=
teiltsystemd
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.