
Wie kann ich mit SystemD bestimmte Dienste davon abhängig machen, dass bestimmte Netzwerkschnittstellen aktiv sind?
Nehmen wir beispielsweise an, ich habe eine 802.1ad-Bond-Schnittstelle, auf die ich warten muss, bis ich Zugriff auf mein SAN/NAS habe, bevor ich es hochfahre libvirtd
, obwohl mir möglicherweise über eine andere Schnittstelle Netzwerkzugriff zur Verfügung steht. Oder nehmen wir an, ich habe eine sshfs
Mount-Verbindung, die ich abhängig von einer VPN-Verbindung automatisch hochfahren (und automatisch wieder herunterfahren) möchte?
Was ist die idiomatische Art und Weise, mit feinkörnigen Abhängigkeiten von Netzwerkschnittstellen umzugehen?
Derzeit verwende ich NetworkManager unter Ubuntu und CentOS7, bin aber offen für andere plattformgerechte Mechanismen zur Verwaltung des Netzwerkstatus.
Antwort1
Ich glaube nicht, dass es dafür einen wirklich standardmäßigen integrierten Ansatz gibt, aber es gibt ein paar Dinge, die Sie nutzen können systemd
.
Zusätzliche Befehle, die jeweils vor dem Befehl in ExecStart= ausgeführt werden. Die Syntax ist dieselbe wie bei ExecStart=, außer dass mehrere Befehlszeilen zulässig sind und die Befehle nacheinander ausgeführt werden.
Wenn einer dieser Befehle (ohne das Präfix "-") fehlschlägt, werden die übrigen nicht ausgeführt und die Einheit gilt als ausgefallen.
Konfiguriert, ob der Dienst neu gestartet werden soll, wenn der Dienstprozess beendet wird, abgebrochen wird oder ein Timeout erreicht wird.
Wenn die Option auf „Bei Fehler“ eingestellt ist, wird der Dienst neu gestartet, wenn der Prozess mit einem Exit-Code ungleich Null beendet wird, durch ein Signal beendet wird (einschließlich bei einem Core Dump, jedoch mit Ausnahme der oben genannten vier Signale), wenn eine Operation (wie etwa das Neuladen eines Dienstes) eine Zeitüberschreitung verursacht und wenn das konfigurierte Watchdog-Timeout ausgelöst wird.
Befehle gelten als fehlgeschlagen, wenn sie Exitcodes ungleich Null zurückgeben. Wenn Sie also einen Wert festlegen, ExecStartPre
der beweist, dass Ihre Schnittstelle aktiv ist, können Sie sicher sein, dass Ihr Dienst dies erfordert.
Einige Beispiele:
ExecStartPre=/usr/bin/ping -c 1 ${SAN_IP}
ExecStartPre=/usr/sbin/iscsiadm -m session
Mir persönlich gefällt die iscsiadm
Variante für Ihren Anwendungsfall. Wenn iscsi-Verbindungen bestehen, ist der Rückgabewert 0, andernfalls wird 21 zurückgegeben (was zu einem Ausfall des Dienstes führen würde). Die ping
Variante kann für eine größere Vielfalt von Anwendungen verwendet werden, aber ich würde sagen, in den meisten Fällen möchten Sie vielleicht einen geeigneteren Befehl finden, um den Netzwerkstatus zu überprüfen. Sie könnten sogar versuchen, es zu verwenden, ssh
wenn Sie Schlüssel eingerichtet haben, um Dinge auf einem anderen Host zu überprüfen.
Der Punkt ist, dass ExecStartPre
Sie Ihren Dienst auf der Grundlage beliebiger Befehle zum Absturz bringen können. Stellen Sie einfach sicher, dass alle von Ihnen verwendeten Befehle Exit-Codes ungleich Null zurückgeben, wenn Sie dies wünschen (zum Beispiel cat
gibt die Ausführung einer leeren Datei 0 zurück, während cat
die Ausführung einer nicht vorhandenen Datei 1 zurückgibt).
Nach einiger Überlegung und dem Kommentar des Fragestellers würde ich sagen, dieam bestenEine Möglichkeit, eine komplexe Bedingung für einen Dienst zu definieren, besteht darin, einen anderen Dienst zu erstellen, von dem er abhängig ist.
Erstellen Sie einen neuen Dienst, der den Befehl zum Überprüfen des Status als verwendet ExecStart
. Geben Sie ihm das Restart=on-failure
. Erstellen Sie dann Ihren ursprünglichen Dienst Require
und After
ihn.
Das ExecStartPre
Beispiel, das ich oben verwendet habe, verdreht gewissermaßen seinen ursprünglichen Zweck, nämlich die Einrichtung der Dinge für den ordnungsgemäßen Betrieb des Dienstes. Es kann immer noch angewendet werden und das Wissen ist immer noch nützlich, also lasse ich es unverändert.