So konfigurieren Sie einen Linux-Dienst für den automatischen Start nach einem Absturz oder Neustart - Teil 2: Referenz

Einführung

In diesem zweiten Teil des Tutorials zum automatischen Starten von Linux-Diensten werden wir einen Schritt zurücktreten und die Init-Prozesse genauer erläutern. Sie sollten ein gutes Verständnis dafür erlangen, wie sie das Startverhalten eines Daemons steuern.

Infirst part dieser Tutorial-Reihe haben wir einige praktische Beispiele mit MySQL vorgestellt, wie ein Linux-Dienst nach einem Absturz oder Neustart automatisch gestartet werden kann.

Wir haben gesehen, wie dies in drei verschiedeneninit-Modi gemacht wird: System V, Upstart und systemd. Lesen Siefirst tutorial, um zu erfahren, welche Distributionen standardmäßig welches Init-System verwenden.

In diesem Tutorial machen wir einen Schritt zurück und erklären, warum wir die Befehle ausgeführt und die von uns erstellten Konfigurationsdateien bearbeitet haben. Wir beginnen mit dem System V-Init-Daemon. Wir werden auch sehen, warum es im Laufe der Zeit durch neuere Init-Modi ersetzt wurde.

Voraussetzungen

Um diesem Tutorial zu folgen, benötigen Sie die drei DigitalOcean Droplets, die Siebefore erstellt haben.

Wir hatten:

  • Ein Debian 6-Server, auf dem MySQL ausgeführt wird

  • Ein Ubuntu 14.04 Server mit MySQL

  • Ein CentOS 7-Server, auf dem MySQL ausgeführt wird

Wir empfehlen Ihnen, zu Teil 1 dieser Serie zurückzukehren und zuerst die Droplets zu erstellen.

Außerdem müssen Sie der Root-Benutzer sein oder über die Berechtigung sudo auf den Servern verfügen. Um zu verstehen, wie Sudo-Berechtigungen funktionieren, siehethis DigitalOcean tutorial about sudo.

Sie sollten in diesem Lernprogramm keine Befehle, Abfragen oder Konfigurationen aus diesem Lernprogramm auf einem Linux-Produktionsserver ausführen.

Runlevel

Einrunlevel repräsentiert den aktuellen Status eines Linux-Systems.

Das Konzept stammt von System V init, bei dem das Linux-System bootet, den Kernel initialisiert und dann einen (und nur einen) Runlevel eingibt.

Ein Runlevel kann beispielsweise der Herunterfahrstatus eines Linux-Servers, ein Einzelbenutzermodus, der Neustartmodus usw. sein. Jeder Modus bestimmt, welche Dienste in diesem Zustand ausgeführt werden können.

Einige Dienste können in einem oder mehreren Runlevels ausgeführt werden, andere jedoch nicht.

Runlevel werden durch einzelne Ziffern gekennzeichnet und können einen Wert zwischen 0 und 6 haben. Die folgende Liste zeigt, was jede dieser Ebenen bedeutet:

  • Runlevel 0: System herunterfahren

  • Runlevel 1: Einzelbenutzer-Rettungsmodus

  • Runlevels 2, 3, 4: Mehrbenutzer-Textmodus mit aktiviertem Netzwerk

  • Runlevel 5: Mehrbenutzer-, netzwerkfähiger, grafischer Modus

  • Runlevel 6: Systemneustart

Die Runlevel 2, 3 und 4 variieren je nach Verteilung. Beispielsweise implementieren einige Linux-Distributionen Runlevel 4 nicht, während andere dies tun. Einige Distributionen unterscheiden deutlich zwischen diesen drei Ebenen. Im Allgemeinen bedeutet Runlevel 2, 3 oder 4 einen Zustand, in dem Linux im netzwerkfähigen Mehrbenutzer-Textmodus gestartet wurde.

Wenn wir den automatischen Start eines Dienstes aktivieren, fügen wir ihn tatsächlich einem Runlevel hinzu. In System V startet das Betriebssystem mit einem bestimmten Runlevel. Beim Start wird versucht, alle Dienste zu starten, die diesem Runlevel zugeordnet sind.

Runlevels werden in systemd zutargets, was im Abschnitt systemd erläutert wird.

Init und PID 1

init ist der erste Prozess, der in einem Linux-System gestartet wird, nachdem der Computer gestartet und der Kernel in den Speicher geladen wurde.

Unter anderem wird festgelegt, wie ein Benutzerprozess oder ein Systemdienst in welcher Reihenfolge geladen werden soll und ob er automatisch gestartet werden soll.

Jeder Prozess unter Linux hat eine Prozess-ID (PID) undinit hat eine PID von 1. Es ist das übergeordnete Element aller anderen Prozesse, die anschließend beim Einschalten des Systems auftreten.

Geschichte von Init

Mit der Entwicklung von Linux hat sich auch das Verhalten des init-Daemons geändert. Ursprünglich begann Linux mit System V init, das auch unter UNIX verwendet wurde. Seitdem hat Linux den Init-DaemonUpstart(erstellt von Ubuntu) und jetzt den Init-Daemonsystemd(zuerst von Fedora implementiert) implementiert.

Die meisten Linux-Distributionen sind nach und nach von System V oder auf dem Weg, es auslaufen zu lassen, migriert und behalten es nur aus Gründen der Abwärtskompatibilität bei. FreeBSD, eine Variante von UNIX, verwendet eine andere Implementierung von System V, die als BSD init bezeichnet wird. Ältere Versionen von Debian verwenden ebenfalls SysVinit.

Jede Version des init-Daemons verfügt über unterschiedliche Methoden zum Verwalten von Diensten. Der Grund für diese Änderungen war die Notwendigkeit eines robusten Dienstverwaltungstools, das nicht nur Dienste, sondern auch Geräte, Ports und andere Ressourcen handhabt. das würde Ressourcen parallel laden und sich nach einem Absturz ordnungsgemäß erholen.

System V Init Sequence

System V verwendet eineinittab-Datei, die spätere Init-Methoden wie Upstart aus Gründen der Abwärtskompatibilität beibehalten haben.

Lassen Sie uns die Startsequenz von System V durchgehen:

  1. Der init-Daemon wird aus der Binärdatei/sbin/init erstellt

  2. Die erste Datei, die der Init-Daemon liest, ist/etc/inittab

  3. Einer der Einträge in dieser Datei bestimmt den Runlevel, in den der Computer booten soll. Wenn der Wert für das Runlevel beispielsweise 3 ist, wird Linux im Mehrbenutzer-Textmodus mit aktiviertem Netzwerk gestartet. (Dieser Runlevel wird als Standard-Runlevel bezeichnet.)

  4. Als Nächstes untersucht der Init-Daemon die Datei/etc/inittabweiter und liest, welcheinit scripts für diese Runlevel ausgeführt werden müssen

Wenn der init-Daemon also herausfindet, welche init-Skripte er für den angegebenen Runlevel benötigt, muss er im Wesentlichen herausfinden, welche Dienste er starten muss. In diesen Init-Skripten können Sie das Startverhalten für einzelne Dienste konfigurieren, wie wir es im ersten Tutorial für MySQL getan haben.

Schauen wir uns als nächstes die Init-Skripte im Detail an.

System V-Konfigurationsdateien: Init-Skripte

Ein Init-Skript steuert einen bestimmten Dienst wie MySQL Server in System V.

Init-Skripte für Dienste werden entweder vom Hersteller der Anwendung bereitgestellt oder mit der Linux-Distribution (für native Dienste) geliefert. Wir können auch eigene Init-Skripte für benutzerdefinierte Dienste erstellen.

Wenn ein Prozess oder Dienst wie MySQL Server gestartet wird, muss seine Binärprogrammdatei in den Speicher geladen werden.

Abhängig von der Konfiguration des Dienstes muss dieses Programm möglicherweise ständig im Hintergrund ausgeführt werden (und Clientverbindungen akzeptieren). Der Job zum Starten, Stoppen oder erneuten Laden dieser Binäranwendung wird vom Init-Skript des Dienstes ausgeführt. Es wird als Init-Skript bezeichnet, da esinitializesder Dienst ist.

In System V ist ein Init-Skript ein Shell-Skript.

Init-Skripte werden auch alsrc-Skripte (Befehl ausführen) bezeichnet.

Verzeichnisaufbau

Das Verzeichnis/etc ist das übergeordnete Verzeichnis für Init-Skripte.

Der tatsächliche Speicherort für Init-Shell-Skripte liegt unter/etc/init.d. Diese Skripte sind mit den Verzeichnissen vonrcverknüpft.

Innerhalb des Verzeichnisses/etchaben wir eine Reihe von Verzeichnissenrc, von denen jedes eine Nummer im Namen hat.

Die Zahlen stehen für verschiedene Runlevel. Wir haben also/etc/rc0.d,/etc/rc1.d,/etc/rc2.d und so weiter.

Dann haben wir in jedemrcn.d-Verzeichnis Dateien, deren Dateiname entweder mitK oderS beginnt, gefolgt von zwei Ziffern. Hierbei handelt es sich um symbolische Verknüpfungsdateien, die auf die eigentlichen Init-Shell-Skripte verweisen. Warum dieK undS? K bedeutet Kill (d. H. stop) und "S" steht für Start.

Die zwei Ziffern geben die Ausführungsreihenfolge des Skripts an. Wenn wir also eine Datei mit dem Namen K25some_script haben, wird sie vor K99another_script ausgeführt.

Anlaufen

Lassen Sie uns mit unserer Startsequenz fortfahren. Wie heißen die Init-Skripte? Wer ruft sie an?

Die K- und S-Skripte werden nicht direkt vom init-Daemon aufgerufen, sondern von einem anderen Skript: dem/etc/init.d/rc-Skript.

Wenn Sie sich erinnern, teilt die Datei/etc/inittabdem Init-Daemon mit, welchen Runlevel das System standardmäßig eingeben soll. Für jeden Runlevel ruft eine Zeile in der Datei/etc/inittab das Skript/etc/init.d/rcauf und gibt diesen Runlevel als Parameter weiter. Basierend auf diesem Parameter ruft das Skript dann die Dateien im entsprechenden Verzeichnis/etc/rcn.dauf. Wenn der Server mit Runlevel 2 startet, werden Skripte unter/etc/rc2.d aufgerufen. Für Runlevel 3 werden Skripte unter/etc/rc3.d ausgeführt und so weiter.

Innerhalb einesrc-Verzeichnisses werden zuerst alle K-Skripte in numerischer Reihenfolge mit dem Argument "stop" ausgeführt, und dann werden alle S-Skripte auf ähnliche Weise mit dem Argument "start" ausgeführt. Hinter den Kulissen werden die entsprechenden Init-Shell-Skripte mit Stopp- bzw. Startparametern aufgerufen.

Da die Dateien in den Verzeichnissen/etc/rcn.d (Knn undSnn) nur symbolische Links sind, bedeutet das Aufrufen, dass die tatsächlichen Init-Shell-Skripte mit Stopp- und Startparametern aufgerufen werden.

Zusammenfassend lässt sich sagen, dass beim Aufrufen eines Runlevels durch den Linux-Server bestimmte Skripts ausgeführt werden, um einige Dienste zu stoppen, während andere ausgeführt werden, um andere Dienste zu starten.

[.Hinweis]##

Dieser Aufruf von Init-Skripten erfolgt auch immer dann, wenn das System auf eine neue Runlevel wechselt: Die entsprechenden Verzeichnisskripte von/etc/rc<n>.dwerden ausgeführt. Und da diese K- und S-Dateien nichts anderes als Links sind, werden die eigentlichen Shell-Skripte im Verzeichnis/etc/init.dmit dem entsprechenden Start- oder Stoppargument ausgeführt.

Der gesamte Prozess stellt sicher, dass alle Dienste, die nicht auf diesem Runlevel ausgeführt werden sollen, gestoppt werden und alle Dienste, die auf diesem Runlevel ausgeführt werden sollen, gestartet werden.

System V Autostart

Da ein Dienst beim Booten automatisch gestartet werden kann, wird das Init-Verhalten geändert.

Wenn wir beispielsweise einen Dienst aktivieren, der auf Runlevel 3 automatisch gestartet wird, erstellt der Prozess hinter den Kulissen die entsprechenden Links im Verzeichnis/etc/rc3.d.

Wenn dies verwirrend klingt, machen Sie sich keine Sorgen - wir werden gleich sehen, was das alles bedeutet.

System V Beispiel

Wir kehren zu unserem MySQL-Dienstbeispiel zurück, diesmal mit mehr Theorie.

[[Schritt 1 - Anmelden bei Debian Droplet]] === Schritt 1 - Anmelden bei Debian Droplet

In diesem Teil des Tutorials kehren wir zu dem Debian 6-Droplet zurück, das wir in Teil 1 erstellt haben. Verwenden Sie den SSH-Befehl, um eine Verbindung zum Server herzustellen (Windows-Benutzer können eine Verbindung mit einem Tool wie PuTTy herstellen).

ssh sammy@your_server_ip

[[Schritt-2 - Betrachten von Inittab]] === Schritt 2 - Betrachten von Inittab

Führen Sie den folgenden Befehl aus, um den Dateiinhalt voninittabanzuzeigen:

cat /etc/inittab | grep initdefault

Die Ausgabe sollte ungefähr so ​​aussehen:

Outputid:2:initdefault:

Das Feld 2 nach der ID zeigt an, dass das System so konfiguriert ist, dass es mit Runlevel 2 startet. Dies ist der Standard-Runlevel. In diesem Fall bezeichnet Debian 2 als Mehrbenutzer-Textmodus. Wenn Sie den folgenden Befehl ausführen:

cat /etc/inittab | grep Runlevel

Die Ausgabe bestätigt dies:

Output# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.

[[Schritt-3 - Anzeigen der RC-Verzeichnisse]] === Schritt 3 - Betrachten der RC-Verzeichnisse

Führen Sie den folgenden Befehl aus, um die Verzeichnisse vonrcaufzulisten. Sie sollten sehen, dass es sechs davon gibt:

ls -ld /etc/rc*.d
Outputdrwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc0.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc1.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc2.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc3.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc4.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc5.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc6.d
drwxr-xr-x 2 root root 4096 Jul 23  2012 /etc/rcS.d

Da das System in Runlevel 2 (Standardinit aus der inittab-Datei) startet, werden Skripts im Verzeichnis/etc/rc2.d beim Systemstart ausgeführt.

Listen Sie den Inhalt dieses Verzeichnisses auf:

ls -l /etc/rc2.d

Dies zeigt, dass die Dateien nichts anderes als symbolische Links sind, die jeweils auf Skriptdateien unter /etc/init.d verweisen:

Output. . .
lrwxrwxrwx 1 root root  17 Jul 23  2012 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root  22 Jul 23  2012 S02acpi-support -> ../init.d/acpi-support
lrwxrwxrwx 1 root root  15 Jul 23  2012 S02acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root  17 Jul 23  2012 S02anacron -> ../init.d/anacron
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02atd -> ../init.d/atd
lrwxrwxrwx 1 root root  14 Jul 23  2012 S02cron -> ../init.d/cron
lrwxrwxrwx 1 root root  15 Jul 31 07:09 S02mysql -> ../init.d/mysql
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02ssh -> ../init.d/ssh
. . .

Wir können sehen, dass es hier keine K-Skripte gibt, nur S-Skripte (Start-Skripte). Die Skripte starten bekannte Dienste wiersyslog,cron oderssh.

Denken Sie daran, dass die beiden Ziffern nach S die Startreihenfolge bestimmen: Beispielsweise startet rsyslog vor dem Cron-Dämon. Wir können auch sehen, dass MySQL hier aufgelistet ist.

[[Schritt 4 - Betrachten eines Init-Skripts]] === Schritt 4 - Betrachten eines Init-Skripts

Wir wissen jetzt, dass ein System V-kompatibler Dienst bei der Installation ein Shell-Skript im Verzeichnis/etc/init.derstellt. Überprüfen Sie das Shell-Skript für MySQL:

ls -l /etc/init.d/my*
Output-rwxr-xr-x 1 root root 5437 Jan 14  2014 /etc/init.d/mysql

Um zu sehen, wie das Startskript tatsächlich aussieht, lesen Sie die Datei:

cat /etc/init.d/mysql | less

In der Ausgabe sehen Sie, dass es sich um ein großes Bash-Skript handelt.

[[Schritt-5 -—- mit-chkconfig-oder-sysv-rc-conf]] === Schritt 5 - mit chkconfig oder sysv-rc-conf

In RHEL-basierten Distributionen wie CentOS kann ein Befehl namenschkconfig verwendet werden, um einen Dienst in System V zu aktivieren oder zu deaktivieren. Es kann auch installierte Dienste und deren Runlevel auflisten.

[.Hinweis]##

Die Syntax zum Überprüfen des Status eines Dienstes für alle Runlevel auf einem CentOS-System lautet:

chkonfig --list | grep service_name

Kein solches Dienstprogramm wird nativ mit Debian ausgeliefert (update-rc.d installiert oder entfernt nur Dienste von Runlevels). Wir können jedoch ein benutzerdefiniertes Tool namenssysv-rc-conf installieren, um die Verwaltung von Diensten zu unterstützen.

Führen Sie den folgenden Befehl aus, umsysv-rc-conf zu installieren:

sudo apt-get install sysv-rc-conf -y

Führen Sie nach der Installation des Tools einfach diesen Befehl aus, um das Runlevel-Verhalten für verschiedene Dienste anzuzeigen:

sudo sysv-rc-conf

Die Ausgabe wird ein hübsches Grafikfenster sein, wie unten gezeigt. Von hier aus können wir deutlich sehen, welche Dienste für welche Runlevel aktiviert sind (markiert mit X).

sysv-rc-conf Window showing X marks for various services for each runlevel

Mit den Pfeiltasten undSPACEBAR können wir einen Dienst für eine oder mehrere Runlevel aktivieren oder deaktivieren.

Verlassen Sie vorerst den Bildschirm, indem SieQ drücken.

[[Schritt-7 - Testen des MySQL-Startverhaltens beim Booten]] === Schritt 7 - Testen des MySQL-Startverhaltens beim Booten

Wie Sie dem Screenshot im vorherigen Abschnitt und unseren Tests in Teil 1 des Tutorials entnehmen können, ist MySQL derzeit auf den Runlevels 2-5 aktiviert.

Führen Sie den folgenden Befehl aus, umdisabledes MySQL-Dienstes zu erreichen:

sudo update-rc.d mysql disable
Outputupdate-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `mysql' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `mysql' overwrites defaults (0 1 6).

Führen Sie nun den Befehl aus:

ls -l /etc/rc2.d

Die Ausgabe sollte zeigen, dass sich der Symlink von/etc/rc2.d zu/etc/init.d/mysql zuK geändert hat:

Output. . .
lrwxrwxrwx 1 root root  15 Jul 31 07:09 K02mysql -> ../init.d/mysql
. . .

Mit anderen Worten, MySQL startet nicht mehr mit dem Standard-Runlevel (2).

Dies geschieht hinter den Kulissen von System V, wenn wir einen Dienst aktivieren und deaktivieren. Solange sich ein S-Skript im Standard-Runlevel-Verzeichnis für den Dienst befindet, startet init diesen Dienst beim Booten.

Aktivieren Sie den Dienst erneut:

sudo update-rc.d mysql enable

[[Schritt 8 - Testen des MySQL-Startverhaltens beim Absturz]] === Schritt 8 - Testen des MySQL-Startverhaltens beim Absturz

Schauen wir uns an, wie System V mit Dienstabstürzen umgeht.

Denken Sie daran, dass wir in Teil 1 dieses Tutorials eine Änderung an der/etc/inittab-Datei vorgenommen haben, damit MySQL nach einem Absturz automatisch gestartet werden kann. Wir haben folgende Zeile hinzugefügt:

/etc/inittab

ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe

Dies sollte sicherstellen, dass der MySQL-Dienst nach einem Absturz startet. Um dies zu überprüfen, starten Sie zuerst den Server neu:

sudo reboot

Sobald der Server zurückkommt, starten Sie SSH und überprüfen Sie die MySQL-Prozess-IDs wie zuvor:

ps -ef | grep mysql

Notieren Sie die Prozess-IDs fürmysqld_safe undmysqld. In unserem Fall waren dies 895 bzw. 1019:

Outputroot       907     1  0 07:30 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql     1031   907  0 07:30 ?        00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306
root      1032   907  0 07:30 ?        00:00:00 logger -t mysqld -p daemon.error
root      2550  2532  0 07:31 pts/0    00:00:00 grep mysql

Beenden Sie die Prozesse erneut mit einem-9-Schalter (ersetzen Sie die PIDs durch die Ihres Debian-Systems):

sudo kill -9 907
sudo kill -9 1031

Warten Sie ungefähr fünf Minuten und führen Sie dann den folgenden Befehl aus:

sudo service mysql status

Die Ausgabe zeigt, dass der MySQL-Dienst ausgeführt wird, beginnend mit der folgenden Zeile:

Output/usr/bin/mysqladmin  Ver 8.42 Distrib 5.1.73, for debian-linux-gnu on x86_64

Wenn Sie den Befehlps -ef | grep mysql erneut ausführen, werden Sie feststellen, dass sowohl die Prozessemysqld_safe als auchmysqld gestartet wurden.

Versuchen Sie, den Vorgang noch einige Male abzubrechen. In jedem Fall sollte er nach fünf Minuten erneut auftreten.

Aus diesem Grund haben wir diese zusätzliche Zeile in/etc/inittab hinzugefügt: Auf diese Weise konfigurieren Sie einen System V-Dienst so, dass er bei einem Absturz erneut angezeigt wird. Es gibt eine detaillierte Erklärung der Syntax für diese Zeile inPart 1.

Seien Sie jedoch vorsichtig, wenn Sie einen automatischen Neustart für einen Dienst hinzufügen: Wenn ein Dienst mehr als zehn Mal innerhalb von zwei Minuten versucht, erneut zu starten, wird der Respawn von Linux für die nächsten fünf Minuten deaktiviert. Auf diese Weise bleibt das System stabil und es gehen nicht die Rechenressourcen aus.

Wenn Sie in der Konsole eine Meldung über ein solches Ereignis erhalten oder diese in den Systemprotokollen finden, wissen Sie, dass ein Problem mit der Anwendung vorliegt, das behoben werden muss, da sie immer wieder abstürzt.

Upstart-Einführung

Classic SysVinit war lange Zeit Teil der Mainstream-Linux-Distributionen, bevor Upstart auf den Markt kam.

Mit dem Wachstum des Linux-Marktes wurden die Möglichkeiten zum Laden von Jobs und Diensten immer zeitaufwändiger und komplexer. Gleichzeitig stellte sich heraus, dass immer mehr moderne Geräte wie hot-plug-fähige Speichermedien nicht mehr in der Lage sind, diese schnell zu handhaben.

Die Notwendigkeit eines schnelleren Ladens des Betriebssystems, einer ordnungsgemäßen Bereinigung abgestürzter Dienste und einer vorhersehbaren Abhängigkeit zwischen Systemdiensten führte zu der Notwendigkeit eines besseren Dienstmanagers. Die Entwickler von Ubuntu haben sich eine andere Methode zur Initialisierung ausgedacht, den Upstart-Daemon.

Upstart init ist in einigen Punkten besser als System V init:

  • Upstart befasst sich nicht mit arkanen Shell-Skripten zum Laden und Verwalten von Diensten. Stattdessen werden einfache Konfigurationsdateien verwendet, die einfach zu verstehen und zu ändern sind

  • Upstart lädt keine Dienste seriell wie System V. Dies verkürzt die Systemstartzeit

  • Upstart verwendet ein flexiblesevent-System, um die Handhabung von Diensten in verschiedenen Zuständen anzupassen

  • Upstart kann besser damit umgehen, wie ein abgestürzter Dienst wiederhergestellt werden soll

  • Es ist nicht erforderlich, mehrere redundante symbolische Links zu führen, die alle auf dasselbe Skript verweisen

  • Upstart ist abwärtskompatibel mit System V. Das/etc/init.d/rc-Skript wird weiterhin ausgeführt, um native System V-Dienste zu verwalten

Upstart-Ereignisse

Beim Upstart können mehrereevents einem Dienst zugeordnet werden. Durch diese ereignisbasierte Architektur kann Upstart das Service-Management flexibel behandeln.

Jedes Ereignis kann ein Shell-Skript auslösen, das sich um dieses Ereignis kümmert.

Upstart-Ereignisse umfassen:

  • Beginnend

  • Gestartet

  • Anhalten

  • Gestoppt

Zwischen diesen Ereignissen kann sich ein Dienst in einer Anzahl vonstates befinden, wie z.

  • warten

  • Vorstart

  • beginnend

  • Laufen

  • Pre-Stop

  • anhalten

  • etc.

Upstart kann auch für jeden dieser Zustände Maßnahmen ergreifen und so eine sehr flexible Architektur schaffen.

Initialisierungssequenz starten

Wie System V führt Upstart auch das Skript/etc/init.d/rcbeim Start aus. Dieses Skript führt alle System V-Init-Skripten normal aus.

Upstart sucht auch im Verzeichnis/etc/initund führt die Shell-Befehle in jeder Dienstkonfigurationsdatei aus.

Upstart-Konfigurationsdateien

Upstart verwendet Konfigurationsdateien, um Dienste zu steuern.

Upstart verwendet keine Bash-Skripte wie System V. Stattdessen verwendet Upstartservice configuration-Dateien mit einem Namensstandard vonservice_name.conf.

Die Dateien haben einfachen Textinhalt mit verschiedenen Abschnitten, die alsstanzas bezeichnet werden. Jede Zeilengruppe beschreibt einen anderen Aspekt des Dienstes und wie er sich verhalten sollte.

Unterschiedliche Strophen steuern unterschiedliche Ereignisse für den Dienst, z. B.pre-start,start,pre-stop oderpost-stop.

Die Strophen selbst enthalten Shell-Befehle. Daher ist es möglich, für jeden Dienst mehrere Aktionen für jedes Ereignis aufzurufen.

Jede Konfigurationsdatei enthält außerdem zwei Angaben:

  • Auf welchen Runleveln soll der Dienst starten und stoppen?

  • Gibt an, ob der Dienstrespawn sein soll, wenn er abstürzt

Verzeichnisaufbau

Die Upstart-Konfigurationsdateien befinden sich im Verzeichnis/etc/init (nicht zu verwechseln mit/etc/init.d).

Upstart-Beispiel

Schauen wir uns noch einmal an, wie Upstart mit MySQL Server umgeht, diesmal mit mehr Hintergrundwissen.

[[Schritt 1 - Anmelden bei Ubuntu-Droplet]] === Schritt 1 - Anmelden bei Ubuntu Droplet

Kehren Sie zu dem in Teil 1 erstellten Ubuntu 14.04 Droplet zurück.

Verwenden Sie den SSH-Befehl, um eine Verbindung zum Server herzustellen (Windows-Benutzer können eine Verbindung mit einem Tool wie PuTTy herstellen).

ssh sammy@your_server_ip

[[Schritt 2 - Betrachten der Verzeichnisse init und rc]] === Schritt 2 - Betrachten der Verzeichnisse init und rc

Die meisten Konfigurationsdateien von Upstart befinden sich im Verzeichnis/etc/init. Dies ist das Verzeichnis, das Sie beim Erstellen neuer Dienste verwenden sollten.

Führen Sie nach dem Anmelden am Server den folgenden Befehl aus:

sudo ls -l /etc/init/ | less

Das Ergebnis zeigt eine große Anzahl von Dienstkonfigurationsdateien auf einmal an. Dies sind Dienste, die nativ unter Upstart ausgeführt werden:

Outputtotal 356
. . .
-rw-r--r-- 1 root root  297 Feb  9  2013 cron.conf
-rw-r--r-- 1 root root  489 Nov 11  2013 dbus.conf
-rw-r--r-- 1 root root  273 Nov 19  2010 dmesg.conf
. . .
-rw-r--r-- 1 root root 1770 Feb 19  2014 mysql.conf
-rw-r--r-- 1 root root 2493 Mar 20  2014 networking.conf

Drücken SieQ, umless zu verlassen.

Vergleichen Sie dies mit den systemeigenen System V init-Diensten im System:

sudo ls -l /etc/rc3.d/* | less

Es wird nur eine Handvoll geben:

Output-rw-r--r-- 1 root root 677 Jun 14 23:31 /etc/rc3.d/README
lrwxrwxrwx 1 root root  15 Apr 17  2014 /etc/rc3.d/S20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root  24 Apr 17  2014 /etc/rc3.d/S20screen-cleanup -> ../init.d/screen-cleanup
lrwxrwxrwx 1 root root  19 Apr 17  2014 /etc/rc3.d/S70dns-clean -> ../init.d/dns-clean
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S70pppd-dns -> ../init.d/pppd-dns
lrwxrwxrwx 1 root root  26 Apr 17  2014 /etc/rc3.d/S99digitalocean -> ../init.d//rc.digitalocean
lrwxrwxrwx 1 root root  21 Apr 17  2014 /etc/rc3.d/S99grub-common -> ../init.d/grub-common
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S99ondemand -> ../init.d/ondemand
lrwxrwxrwx 1 root root  18 Apr 17  2014 /etc/rc3.d/S99rc.local -> ../init.d/rc.local

[[Schritt-3 - Anzeigen einer Upstart-Datei]] === Schritt 3 - Betrachten einer Upstart-Datei

Wir haben diemysql.conf-Datei bereits in Teil 1 dieses Tutorials gesehen. Öffnen wir also eine andere Konfigurationsdatei: die für den Cron-Daemon.

sudo nano /etc/init/cron.conf

Wie Sie sehen können, ist dies eine ziemlich einfache Konfigurationsdatei für den Cron-Daemon:

/etc/init/cron.conf

# cron - regular background program processing daemon
#
# cron is a standard UNIX program that runs user-specified programs at
# periodic scheduled times

description     "regular background program processing daemon"

start on runlevel [2345]
stop on runlevel [!2345]

expect fork
respawn

exec cron

Die wichtigen Felder, die hier beachtet werden müssen, sindstart on,stop on undrespawn.

Die Anweisungstart on weist Ubuntu an, den Dämoncrond zu starten, wenn das System die Runlevel 2, 3, 4 oder 5 betritt. 2, 3 und 4 sind Mehrbenutzer-Textmodi mit aktiviertem Netzwerk, und 5 sind Mehrbenutzer-Grafikmodi. Der Dienst kann nicht auf anderen Runleveln (wie 0,1 oder 6) ausgeführt werden.

Die Anweisungfork teilt Upstart mit, dass der Prozess von der Konsole getrennt und im Hintergrund ausgeführt werden soll.

Als nächstes kommt dierespawn-Richtlinie. Dies teilt dem System mit, dass cron automatisch gestartet werden soll, wenn es aus irgendeinem Grund abstürzt.

Beenden Sie den Editor, ohne Änderungen vorzunehmen.

Die Cron-Konfigurationsdatei ist eine ziemlich kleine Konfigurationsdatei. Die MySQL-Konfigurationsdatei ist strukturell der Cron-Konfigurationsdatei ähnlich. Es gibt auch Strophen für Start, Stopp und Respawn. Darüber hinaus verfügt es über zwei Skriptblöcke für Pre-Start- und Post-Start-Ereignisse. Diese Codeblöcke teilen dem System mit, was ausgeführt werden soll, wenn der mysqld-Prozess gestartet wird oder bereits gestartet wurde.

Praktische Hilfe zum Erstellen Ihrer eigenen Upstart-Datei finden Sie unterthis tutorial about Upstart.

[[Schritt-4 - Testen des MySQL-Startverhaltens beim Booten]] === Schritt 4 - Testen des MySQL-Startverhaltens beim Booten

Wir wissen, dass die MySQL-Instanz auf unserem Ubuntu 14.04-Server standardmäßig so eingestellt ist, dass sie beim Booten automatisch startet. Mal sehen, wie wir es deaktivieren können.

In Upstart hängt das Deaktivieren eines Dienstes vom Vorhandensein einer Datei unter/etc/init/ ab, die alsservice_name.override bezeichnet wird. Der Inhalt der Datei sollte ein einfaches Wort sein:manual.

Um zu sehen, wie wir diese Datei zum Deaktivieren von MySQL verwenden können, führen Sie den folgenden Befehl aus, um diese Überschreibungsdatei für MySQL zu erstellen:

sudo nano /etc/init/mysql.override

Fügen Sie diese einzelne Zeile hinzu:

/etc/init/mysql.override

manual

Speichern Sie Ihre Änderungen.

Starten Sie als Nächstes den Server neu:

sudo reboot

Wenn der Server wieder online ist, überprüfen Sie den Status des Dienstes

sudo initctl status mysql

Die Ausgabe sollte sein:

Outputmysql stop/waiting

Dies bedeutet, dass MySQL nicht gestartet wurde.

Überprüfen Sie, ob sich die Anweisungstartin der Konfigurationsdatei des MySQL-Dienstes geändert hat:

sudo cat /etc/init/mysql.conf | grep start\ on

Es sollte immer noch dasselbe sein:

Outputstart on runlevel [2345]

Dies bedeutet, dass das Überprüfen der.conf-Datei iminit-Verzeichnis nicht der einzige Faktor ist, um festzustellen, ob der Dienst auf den entsprechenden Ebenen gestartet wird. Sie müssen auch sicherstellen, dass die Datei.overridenicht vorhanden ist.

Um MySQL wieder zu aktivieren, löschen Sie die Überschreibungsdatei und starten Sie den Server neu:

sudo rm -f /etc/init/mysql.override
sudo reboot

Stellen Sie nach dem Neustart des Servers eine Remoteverbindung her.

Wenn Sie den Befehlsudo initctl status mysqlausführen, wird angezeigt, dass der Dienst automatisch gestartet wurde.

[[Schritt 5 - Testen des MySQL-Startverhaltens beim Absturz]] === Schritt 5 - Testen des MySQL-Startverhaltens beim Absturz

Standardmäßig wird MySQL nach einem Absturz automatisch gestartet.

Öffnen Sie die Dienstkonfigurationsdatei von/etc/init/mysql.conf, um MySQL zu stoppen:

sudo nano /etc/init/mysql.conf

Kommentieren Sie beiderespawn-Richtlinien aus.

/etc/init/mysql.conf

# respawn
# respawn limit 2 5

Führen Sie die folgenden Befehle aus, um den Dienst neu zu starten:

sudo initctl stop mysql
sudo initctl start mysql

Wir stoppen und starten den Dienst explizit, da unser Test ergab, dassinitctl restart oderinitctl reload hier nicht funktionieren würden.

Der zweite Befehl zum Starten des Dienstes zeigt die PID, mit der MySQL gestartet wurde:

Outputmysql start/running, process 1274

Notieren Sie die PID für Ihre Instanz von MySQL. Wenn Sie den Prozess vonmysqljetzt zum Absturz bringen, wird er nicht automatisch gestartet. Beende den Prozess OF (ersetze ihn durch deine eigene Nummer):

sudo kill -9 1274

Überprüfen Sie nun den Status:

sudo initctl status mysql
Outputmysql stop/waiting

Versuchen Sie, den Status noch einige Male zu ermitteln, und geben Sie zwischen den beiden eine Weile Zeit. In jedem Fall wird MySQL weiterhin gestoppt. Dies geschieht, weil die Dienstkonfigurationsdatei nicht mehr die Anweisungenrespawnenthält.

Part 1 des Tutorials enthält eine detailliertere Erläuterung der Direktiven vonrespawn.

[.Hinweis]##

Wann möchten Sienot, dass ein Upstart-Dienst nach einem Neustart oder Absturz gestartet wird?

Angenommen, Sie haben Ihren Linux-Kernel aktualisiert oder den neuesten Patch installiert. Du willst kein Drama; Sie nur der Server zu kommen. Sie können Risiken weitgehend ausschließen, indem Sie den automatischen Start für jeden Upstart-Prozess deaktivieren.

Wenn Ihr Dienst startet, aber weiterhin abstürzt, können Sie ihn zuerst stoppen und dann auch sein Respawn-Verhalten ändern.

systemd Einführung

Die neuesten Linux-Init-Daemons sind systemd. Tatsächlich ist es mehr als ein Init-Daemon: systemd ist ein völlig neues Framework, das viele Komponenten eines modernen Linux-Systems umfasst.

Eine seiner Funktionen besteht darin, alssystem and service manager für Linux zu arbeiten. In dieser Eigenschaft steuert systemd unter anderem, wie sich ein Dienst verhalten soll, wenn er abstürzt oder der Computer neu startet. Sie können ungefährsystemd’s systemctl here lesen.

systemd ist abwärtskompatibel mit System V-Befehlen und Initialisierungsskripten. Das bedeutet, dass jeder System V-Dienst auch unter systemd ausgeführt wird. Dies ist möglich, da die meisten Verwaltungsbefehle für Upstart und System V so geändert wurden, dass sie unter systemd funktionieren.

Wenn wir den Befehlps -ef | grep systemd in einem Betriebssystem ausführen, das ihn unterstützt, wird nichts angezeigt, da sichsystemd beim Booten ininit umbenennt. Es gibt eine/sbin/init-Datei, die eine symbolische Verknüpfung zu/bin/systemd darstellt.

Systemd-Konfigurationsdateien: Einheitendateien

Das Herzstück von systemd sindunit files. Jede Unit-Datei repräsentiert eine Systemressource. Der Hauptunterschied zwischen systemd und den beiden anderen init-Methoden besteht darin, dass systemd nicht nur für die Initialisierung von Service-Daemons verantwortlich ist, sondern auch für andere Arten von Ressourcen wie Sockets, Gerätebetriebssystempfade, Mount-Punkte, Sockets usw. Eine Ressource kann eine beliebige davon sein.

Informationen über die Ressource werden in der Einheitendatei gespeichert.

Jede Einheitendatei stellt eine bestimmte Systemressource dar und hat einen Namensstil vonservice name.unit type.

Wir haben also Dateien wiedbus.service,sshd.socket oderhome.mount.

Wie wir später sehen werden, sind Service Unit-Dateien einfache Textdateien (wie Upstart.conf Dateien) mit einer deklarativen Syntax. Diese Dateien sind ziemlich einfach zu verstehen und zu ändern.

Verzeichnisaufbau

In Red Hat-basierten Systemen wie CentOS befinden sich Unit-Dateien an zwei Stellen. Der Hauptstandort ist/lib/systemd/system/.

Benutzerdefinierte oder von Systemadministratoren geänderte Einheitendateien werden unter/etc/systemd/system gespeichert.

Wenn an beiden Speicherorten eine Einheitendatei mit demselben Namen vorhanden ist, verwendet systemd die unter/etc. Wenn ein Dienst zum Starten zum Startzeitpunkt oder zu einem anderen Ziel / Runlevel aktiviert ist, wird für diese Diensteinheitendatei unter den entsprechenden Verzeichnissen in/etc/systemd/system eine symbolische Verknüpfung erstellt. Einheitendateien unter/etc/systemd/system sind eigentlich symbolische Links zu Dateien mit demselben Namen unter/lib/systemd/system.

systemd Init-Sequenz: Zieleinheiten

Ein spezieller Typ einer Einheitendatei isttarget unit.

Ein Dateiname der Zieleinheit wird mit.target versehen. Zieleinheiten unterscheiden sich von anderen Einheitendateien, da sie keine bestimmte Ressource darstellen. Sie repräsentieren vielmehr den Zustand des Systems zu einem beliebigen Zeitpunkt.

Zieleinheiten tun dies, indem sie mehrere Einheitendateien gruppieren und starten, die Teil dieses Status sein sollen. systemdtargets kann daher lose mit System V-Runlevels verglichen werden, obwohl sie nicht gleich sind.

Jedes Ziel hat einen Namen anstelle einer Nummer. Zum Beispiel haben wirmulti-user.target anstelle von Runlevel 3 oderreboot.target anstelle von Runlevel 6.

Wenn ein Linux-Server beispielsweise mitmulti-user.target startet, wird der Server im Wesentlichen auf Runlevel 2, 3 oder 4 gebracht. Dies ist der Mehrbenutzer-Textmodus mit aktiviertem Netzwerk.

Wie es den Server auf diese Stufe bringt, ist der Unterschied. Im Gegensatz zu System V ruft systemd die Dienste nicht nacheinander auf. Unterwegs kann es prüfen, ob andere Dienste oder Ressourcen vorhanden sind, und die Reihenfolge des Ladens festlegen. Dadurch können Dienste parallel geladen werden.

Ein weiterer Unterschied zwischen Zieleinheiten und Runleveln besteht darin, dass in System V ein Linux-System nur in einem Runlevel vorhanden sein kann. Sie könnten den Runlevel ändern, aber das System würde nur in diesem neuen Runlevel existieren. Mit systemd können Zieleinheiteninclusive sein. Wenn eine Zieleinheit aktiviert wird, kann sichergestellt werden, dass andere Zieleinheiten als Teil davon geladen werden.

Bei einem Linux-System, das mit einer grafischen Benutzeroberfläche startet, sind beispielsweisegraphical.target aktiviert, wodurch automatisch sichergestellt wird, dassmulti-user.target ebenfalls geladen und aktiviert wird.

(In System V würde dies bedeuten, dass die Runlevel 3 und 5 gleichzeitig aktiviert werden.)

Die folgende Tabelle vergleicht Runlevel und Ziele:

Runlevel (System V init) Zieleinheiten (Systemd)

Runlevel 0

poweroff.target

Runlevel 1

resuce.target

Runlevel 2, 3, 4

multi-user.target

Runlevel 5

graphical.target

Runlevel 6

reboot.target

systemd default.target

default.target entspricht dem Standard-Runlevel.

In System V wurde der Standard-Runlevel in einer Datei namensinittab definiert. In systemd wird diese Datei durchdefault.target ersetzt. Die Standarddatei der Zieleinheit befindet sich im Verzeichnis/etc/systemd/system. Dies ist eine symbolische Verknüpfung zu einer der Dateien der Zieleinheit unter/lib/systemd/system.

Wenn wir das Standardziel ändern, erstellen wir diese symbolische Verknüpfung im Wesentlichen neu und ändern den Runlevel des Systems.

In der inittab-Datei in System V wurde auch angegeben, aus welchem ​​Verzeichnis Linux seine Init-Skripte ausführen soll: Es kann sich um eines der Verzeichnisse rcn.d handeln. In systemd bestimmt die Standardzieleinheit, welche Ressourceneinheiten beim Booten geladen werden.

Alle diese Einheiten werden aktiviert, jedoch nicht alle parallel oder alle nacheinander. Wie eine Ressourceneinheit geladen wird, hängt möglicherweise von anderen Ressourceneinheiten ab, diewants oderrequires sind.

systemd Abhängigkeiten: Wünscht und Erfordert

Der Grund für diese Diskussion über Einheitendateien und Zieleinheiten besteht darin, herauszufinden, wie systemd die Abhängigkeit zwischen seinen Daemons behebt.

Wie wir bereits gesehen haben, stellt Upstart das parallele Laden von Diensten mithilfe von Konfigurationsdateien sicher. In System V kann ein Dienst in bestimmten Runleveln gestartet werden, es kann jedoch auch abgewartet werden, bis ein anderer Dienst oder eine andere Ressource verfügbar wird. Auf ähnliche Weise können systemd-Dienste veranlasst werden, ein oder mehrere Ziele zu laden oder zu warten, bis ein anderer Dienst oder eine andere Ressource aktiv wurde.

In systemd startet eine Einheit, dierequireseine andere Einheit ist, erst, wenn die erforderliche Einheit geladen und aktiviert ist. Wenn die erforderliche Einheit aus irgendeinem Grund ausfällt, während die erste Einheit aktiv ist, stoppt auch die erste Einheit.

Wenn Sie darüber nachdenken, sorgt dies für Systemstabilität. Ein Dienst, der das Vorhandensein eines bestimmten Verzeichnisses erfordert, kann daher so lange warten, bis der Bereitstellungspunkt für dieses Verzeichnis aktiv ist. Andererseits wird eine Einheit, diewantseine andere Einheit ist, solche Einschränkungen nicht auferlegen. Es wird nicht angehalten, wenn die gewünschte Einheit anhält, wenn der Anrufer aktiv ist. Ein Beispiel hierfür wären die nicht wesentlichen Dienste, die im grafischen Zielmodus ausgeführt werden.

systemd Beispiel

Es ist Zeit, uns eingehend mit dem Startverhalten von MySQL unter systemd zu befassen.

[[Schritt-1 -—- Anmelden bei Centos-Droplet]] === Schritt 1 - Anmelden bei CentOS Droplet

Um alle diese Konzepte und ihre Beziehung zum automatischen Start eines Dienstes zu verstehen, kehren wir zu dem in Teil 1 erstellten CentOS 7-Droplet zurück.

Verwenden Sie den SSH-Befehl, um eine Verbindung zum Server herzustellen (Windows-Benutzer können eine Verbindung mit einem Tool wie PuTTy herstellen).

ssh sammy@your_server_ip

[[Schritt-2 - Betrachten der Standard-Zieldatei und -abhängigkeiten]] === Schritt 2 - Betrachten der Standard-Zieldatei und der Abhängigkeiten

Dies ist ein langer Abschnitt, da wir so weit wie möglich dem Kaninchenpfad von.targetfolgen werden. Die Startsequenz von systemd folgt einer langen Kette von Abhängigkeiten.

defaul.target

Die Dateidefault.target steuert, welche Dienste während eines normalen Serverstarts gestartet werden.

Führen Sie den folgenden Befehl aus, um die Standardzieleinheitendatei aufzulisten:

sudo ls -l /etc/systemd/system/default.target

Dies zeigt die Ausgabe wie folgt:

Outputlrwxrwxrwx. 1 root root 37 Jul  8  2014 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target

Wie wir sehen können, ist das Standardziel tatsächlich eine symbolische Verknüpfung zur Mehrbenutzer-Zieldatei unter/lib/systemd/system/. Das System soll also untermulti-user.target booten, was Runlevel 3 ähnelt.

multi-user.target.wants

Führen Sie als Nächstes den folgenden Befehl aus, um alle Dienste dermulti-user.target-Dateiwants zu überprüfen:

sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service

Dies sollte eine Ausgabe wie diese zeigen:

Output. . .
lrwxrwxrwx. 1 root root  37 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/crond.service -> /usr/lib/systemd/system/crond.service
. . .
lrwxrwxrwx  1 root root  38 Jul 31 22:02 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service
lrwxrwxrwx. 1 root root  46 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service
lrwxrwxrwx. 1 root root  39 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/postfix.service -> /usr/lib/systemd/system/postfix.service
lrwxrwxrwx. 1 root root  39 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
lrwxrwxrwx. 1 root root  36 Jul  8  2014 /etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service
. . .

Wir können sehen, dass dies alles symbolische Linkdateien sind, die auf tatsächliche Einheitendateien unter/lib/systemd/system/ verweisen. Wir können auch sehen, dassmysqld.service Teil vonmulti-user.target ist.

Dieselben Informationen finden Sie, wenn Sie diesen Befehl ausführen, um die Ausgabe zu filtern:

sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql
Outputmysqld.service

Außermulti-user.target gibt es verschiedene Arten von Zielen wiesystem-update.target oderbasic.target.

Führen Sie den folgenden Befehl aus, um festzustellen, von welchen Zielen unser Mehrbenutzerziel abhängt:

sudo systemctl show --property "Requires" multi-user.target | fmt -10
OutputRequires=basic.target

Um das System im Modusmulti-user.target zu starten, mussbasic.target zuerst geladen werden.

basic.target

Führen Sie den folgenden Befehl aus, um zu sehen, von welchen anderen Zielenbasic.target abhängt:

sudo systemctl show --property "Requires" basic.target | fmt -10

Die Ausgabe wird sein:

OutputRequires=sysinit.target

sysinit.target

Wenn wir rekursiv vorgehen, können wir sehen, ob fürsysinit.target erforderliche Einheiten vorhanden sind. Da sind keine. Wir können jedoch sehen, welche Dienstewanted vonsysinit.target sind:

sudo systemctl show --property "Wants" sysinit.target | fmt -10

Dies zeigt eine Reihe von Diensten, die von sysinit gewünscht werden.

OutputWants=local-fs.target
swap.target
cryptsetup.target
systemd-udevd.service
systemd-update-utmp.service
systemd-journal-flush.service
plymouth-read-write.service
. . .

Wie Sie sehen, bleibt das System nicht nur auf einem Ziel. Beim Übergang zwischen Zielen werden Dienste in abhängiger Weise geladen.

[[Schritt 3 - Betrachten einer Einheitendatei]] === Schritt 3 - Betrachten einer Einheitendatei

Gehen wir noch einen Schritt weiter und schauen wir uns eine Service-Unit-Datei an. Wir haben die MySQL-Service-Unit-Datei in Teil 1 dieses Tutorials gesehen und werden sie in Kürze wieder verwenden. Öffnen wir jedoch zunächst eine andere Service-Unit-Datei, die für sshd:

sudo nano /etc/systemd/system/multi-user.target.wants/sshd.service

Es sieht aus wie das:

Output[Unit]
Description=OpenSSH server daemon
After=syslog.target network.target auditd.service

[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStartPre=/usr/sbin/sshd-keygen
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

Genau wie eine Upstart-Daemon-Konfigurationsdatei ist diese Service-Unit-Datei sauber und leicht zu verstehen.

Das erste wichtige Bit, das zu verstehen ist, ist dieAfter-Klausel. Dies besagt, dass der SSHD-Dienst geladen werden muss, nachdem die System- und Netzwerkziele und der Überwachungsprotokollierungsdienst geladen wurden.

Die Datei zeigt auch, dass der Dienstwanted malmulti-user.target ist. Dies bedeutet, dass das Ziel diesen Dienst lädt, ihn jedoch nicht herunterfährt oder abstürzt, wenn sshd fehlschlägt.

Damulti-user.target das Standardziel ist, soll der sshd-Daemon beim Start starten.

Beenden Sie den Editor.

[[Schritt-4 - Testen des MySQL-Startverhaltens beim Booten]] === Schritt 4 - Testen des MySQL-Startverhaltens beim Booten

In Teil 1 des Tutorials haben wir den MySQL-Dienst aktiviert und ausgeführt. Mal sehen, wie man das ändert.

Im letzten Abschnitt haben wir einen Befehl ausgeführt, um zu bestätigen, dassmysqld.service vonmulti-user.target gewünscht wird. Als wir den Inhalt des Verzeichnisses/etc/systemd/system/multi-user.target.wants/ auflisteten, sahen wir unter/usr/lib/systemd/system/ einen symbolischen Link, der auf die ursprüngliche Serviceeinheit zurückführte.

Führen Sie den folgenden Befehl aus, um den Dienst zu deaktivieren, damit er beim Start nicht automatisch gestartet wird:

sudo systemctl disable mysqld.service

Führen Sie nun diesen Befehl aus, um zu überprüfen, ob MySQL vonmulti-user.target noch gewünscht wird:

sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql

Nichts wird zurückgegeben. Führen Sie den folgenden Befehl aus, um zu überprüfen, ob der symbolische Link noch vorhanden ist:

sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*

Der Link existiert nicht:

Outputls: cannot access /etc/systemd/system/multi-user.target.wants/mysql*: No such file or directory

Wenn Sie möchten, starten Sie den Server neu. MySQL sollte nicht gestartet werden.

Aktivieren Sie nun den Dienst:

sudo systemctl enable mysqld.service

Der Link wird zurückkommen:

sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
Outputlrwxrwxrwx 1 root root 38 Aug  1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service

(Wenn Sie zuvor neu gestartet haben, sollten Sie MySQL erneut starten.)

Wie Sie sehen können, wird durch Aktivieren oder Deaktivieren eines systemd-Dienstes die symbolische Verknüpfung aus demwants-Verzeichnis des Standardziels erstellt oder entfernt.

[[Schritt 5 - Testen des MySQL-Startverhaltens beim Absturz]] === Schritt 5 - Testen des MySQL-Startverhaltens beim Absturz

MySQL wird derzeit nach einem Absturz automatisch gestartet. Mal sehen, wie man das deaktiviert.

Öffnen Sie die MySQL Service Unit-Datei in einem Editor:

sudo nano /etc/systemd/system/multi-user.target.wants/mysqld.service

Nach den Header-Informationen sieht der Inhalt der Datei folgendermaßen aus:

/etc/systemd/system/multi-user.target.wants/mysqld.service

[Unit]
Description=MySQL Community Server
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target
Alias=mysql.service

[Service]
User=mysql
Group=mysql

# Execute pre and post scripts as root
PermissionsStartOnly=true

# Needed to create system tables etc.
ExecStartPre=/usr/bin/mysql-systemd-start pre

# Start main service
ExecStart=/usr/bin/mysqld_safe

# Don't signal startup success before a ping works
ExecStartPost=/usr/bin/mysql-systemd-start post

# Give up if ping don't get an answer
TimeoutSec=600

Restart=always
PrivateTmp=false

Wie wir in Teil 1 gesehen haben, wird der Wert des ParametersRestart aufalways gesetzt (für sshd wurde dies nur aufon-failure gesetzt). Dies bedeutet, dass der MySQL-Dienst für saubere oder unsaubere Exit-Codes oder Timeouts neu gestartet wird.

man page for systemd service zeigt die folgende Tabelle für Neustartparameter:

Einstellungen neu starten / Ursachen beenden no immer auf Erfolg bei Ausfall anormal On-Abort Wachhund

Exit-Code oder Signal reinigen

X

X

Unsauberer Exit-Code

X

X

Unreines Signal

X

X

X

X

Auszeit

X

X

X

Wachhund

X

X

X

X

In einer systemd Service Unit-Datei steuern die beiden ParameterRestart undRestartSec das Absturzverhalten. Der erste Parameter gibt an, wann der Dienst neu gestartet werden soll, und der zweite Parameter legt fest, wie lange er vor dem Neustart warten soll.

Kommentieren Sie die Restart-Direktive aus, speichern Sie die Datei und beenden Sie den Editor. Dadurch wird das Neustartverhalten deaktiviert.

/etc/systemd/system/multi-user.target.wants/mysqld.service

# Restart=always

Laden Sie als Nächstes den systemd-Daemon neu, gefolgt von einem Neustart desmysqld-Dienstes:

sudo systemctl daemon-reload
sudo systemctl restart mysqld.service

Suchen Sie als Nächstes die Haupt-PID des Dienstes, indem Sie diesen Befehl ausführen:

sudo systemctl status mysqld.service
Output. . .
Main PID: 11217 (mysqld_safe)

Beenden Sie mit dem Befehlkill -9 die Haupt-PID mit Ihrer eigenen Nummer.

sudo kill -9 11217

Wenn Siesudo systemctl status mysqld.service erneut ausführen, wird angezeigt, dass der Dienst fehlgeschlagen ist:

sudo systemctl status mysqld.service
Outputmysqld.service - MySQL Community Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
   Active: failed (Result: signal) since Sun 2015-06-21 02:28:17 EDT; 1min 33s ago
  Process: 2566 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)
  Process: 2565 ExecStart=/usr/bin/mysqld_safe (code=killed, signal=KILL)
  Process: 2554 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
 Main PID: 2565 (code=killed, signal=KILL)

Jun 21 02:20:09 test-centos7 systemd[1]: Starting MySQL Community Server...
Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Logging to '/var/log/mysqld.log'.
Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
Jun 21 02:20:10 test-centos7 systemd[1]: Started MySQL Community Server.
Jun 21 02:28:16 test-centos7 systemd[1]: mysqld.service: main process exited, code=killed, status=9/KILL
Jun 21 02:28:17 test-centos7 systemd[1]: Unit mysqld.service entered failed state.

Versuchen Sie einige Male, den Dienststatus zu ermitteln, und jedes Mal wird der Dienst als fehlgeschlagen angezeigt.

Wir haben also einen Absturz emuliert, bei dem der Dienst angehalten wurde und nicht zurückgekehrt ist. Dies liegt daran, dass wir systemd angewiesen haben, den Dienst nicht neu zu starten.

Wenn Sie nun die Unit-Dateimysqld.serviceerneut bearbeiten, den ParameterRestart auskommentieren, speichern, den systemctl-Daemon neu laden und schließlich den Dienst starten, sollte er wieder auf dem vorherigen Stand sein.

Auf diese Weise kann ein systemeigener Dienst so konfiguriert werden, dass er nach einem Absturz automatisch gestartet wird. Alles, was wir tun müssen, ist, eine zusätzliche Direktive fürRestart (und optionalRestartSec) im Abschnitt[Service] der Serviceeinheitendatei hinzuzufügen.

Fazit

So handhabt Linux den Start von Diensten. Wir haben gesehen, wie System V-, Upstart- und systemd init-Prozesse funktionieren und wie sie sich auf das automatische Starten eines Dienstes nach einem Neustart oder Absturz beziehen.

Die deklarative Syntax von Upstart-Konfigurationsdateien oder systemd-Unit-Dateien ist eine Verbesserung gegenüber den geheimen System V-Init-Skripten.

Überprüfen Sie bei der Arbeit mit Ihrer eigenen Linux-Umgebung die Version Ihrer Distribution und stellen Sie fest, welcher init-Daemon unterstützt wird.

Es lohnt sich zu überlegen, wo Sie einen Dienst aktivieren und wo Sie ihn deaktivieren möchten. In den meisten Fällen müssen Sie für Anwendungen von Drittanbietern oder native Linux-Daemons keine Änderungen vornehmen. Nur wenn Sie Ihre eigenen dienstbasierten Anwendungen erstellen, müssen Sie über das Startverhalten und das Respawn-Verhalten nachdenken.