systemd vs. OpenRC vs. runit: Init Systeme im Vergleich für Server und Container
AI generated
$
/etc
Linux
systemd, OpenRC, runit
Init Systeme im Vergleich für Server und Container

PID 1 entscheidet über weit mehr als nur den Boot Vorgang: Service Supervision, Dependency Auflösung und Logging Architektur hängen direkt am gewählten Init System. systemd dominiert auf klassischen Servern, während OpenRC und runit gerade in schlanken Container Basis Images wie Alpine und Void Linux ihre Nische behaupten, aus guten technischen Gründen.

10 Min. Lesezeit Linux systemd Init System

1. Was PID 1 eigentlich leistet

Der Kernel startet nach Abschluss der eigenen Initialisierung genau einen Userspace Prozess mit der Prozess ID 1, der ab diesem Moment die Wurzel des gesamten Prozessbaums bildet. Dieser Prozess bekommt eine besondere Verantwortung übertragen: Er muss verwaiste Kindprozesse einsammeln, sogenannte Zombies vermeiden, Systemdienste in der richtigen Reihenfolge starten und im Idealfall auch überwachen, ob ein Dienst unerwartet beendet wird.

Historisch übernahm auf den meisten Unix artigen Systemen SysVinit diese Rolle, mit sequentiell abgearbeiteten Shell Skripten in nummerierten Runlevel Verzeichnissen. Moderne Init Systeme wie systemd, OpenRC und runit unterscheiden sich vor allem darin, wie viel dieser Verantwortung tatsächlich in PID 1 selbst steckt und wie sehr Service Supervision, Logging und Dependency Handling als eigenständige, gut definierte Bausteine statt als lose Sammlung von Shell Skripten umgesetzt werden.

2. systemd Architektur: Units und paralleler Start

systemd beschreibt Dienste, Mount Punkte, Geräte, Timer und Sockets einheitlich als Units in deklarativen Konfigurationsdateien, statt als ausführbare Skripte. Ein Service Unit File legt über Directives wie After, Requires und Wants die Abhängigkeiten zu anderen Units fest, woraus systemd beim Boot einen vollständigen Dependency Graphen aufbaut und Dienste ohne feste Abhängigkeit zueinander parallel statt sequentiell startet.

Diese parallele Start Strategie verkürzt die Boot Zeit gegenüber einem strikt sequentiellen SysVinit Ansatz spürbar, bringt aber auch eine deutlich größere Angriffsfläche und Code Basis mit sich, weil systemd neben der reinen Prozessverwaltung auch Logging über journald, Netzwerkkonfiguration über systemd-networkd, Geräteverwaltung über udev und zahlreiche weitere Komponenten im selben Projekt bündelt.


# Abhängigkeiten eines Service Units einsehen
systemctl show -p After -p Requires -p Wants nginx.service

# Vollständigen Dependency Graphen als Textbaum ausgeben
systemd-analyze critical-chain nginx.service

# Boot Zeit Aufschlüsselung je Unit
systemd-analyze blame

3. OpenRC Architektur: Shell Skripte mit Dependency System

OpenRC setzt weiterhin auf klassische Shell Skripte für einzelne Dienste, ergänzt diese aber um ein eigenständiges Dependency System, das über die Direktiven need, use und after in jedem Skript beschrieben wird und beim Start eine korrekte Reihenfolge sowie teilweise Parallelität ermöglicht, ohne die Einfachheit reiner Shell Skripte vollständig aufzugeben.

Da OpenRC kein Big Bang Neuentwurf wie systemd ist, sondern bewusst auf einer schlanken, POSIX nahen Basis aufbaut, bleibt der Ressourcenverbrauch von PID 1 selbst minimal, während die eigentliche Prozessüberwachung optional über das separate Werkzeug s6 oder OpenRCs eigenes supervise-daemon Kommando läuft, statt fest in PID 1 verankert zu sein.


# OpenRC Service Skript, gekürztes Beispiel (/etc/init.d/myapp)
#!/sbin/openrc-run
name="myapp"
command="/usr/bin/myapp"
command_args="--config /etc/myapp/config.yml"
command_background=true
pidfile="/run/myapp.pid"

depend() {
    need net
    after firewall
}

# Dienst aktivieren und Status prüfen
rc-update add myapp default
rc-service myapp status

4. runit Architektur: Supervision Trees als Grundprinzip

runit verfolgt einen radikal minimalistischen Ansatz nach dem Vorbild von daemontools: Jeder überwachte Dienst besitzt ein eigenes Verzeichnis mit einem einfachen run Skript, das den Dienst im Vordergrund startet, während der Supervisor Prozess runsv permanent daneben läuft und den Dienst bei einem unerwarteten Absturz sofort neu startet, ohne dass dafür eine komplexe Konfigurationssprache nötig wäre.

Diese Supervision Trees genannte Struktur macht runit besonders vorhersehbar: Es gibt praktisch keinen versteckten globalen Zustand, jeder Dienst lässt sich isoliert mit sv start, sv stop oder sv status steuern, und das gesamte Init System besteht aus wenigen tausend Zeilen C Code, was Audits und ein vollständiges Verständnis des Verhaltens erheblich erleichtert.


# runit Service Verzeichnis, minimales Beispiel
mkdir -p /etc/sv/myapp
cat <<'EOF' > /etc/sv/myapp/run
#!/bin/sh
exec 2>&1
exec /usr/bin/myapp --config /etc/myapp/config.yml
EOF
chmod +x /etc/sv/myapp/run
ln -s /etc/sv/myapp /var/service/myapp

# Dienst Status abfragen und neu starten
sv status myapp
sv restart myapp

5. Service Supervision im direkten Vergleich

Bei systemd ist die Supervision fest in PID 1 integriert: Über Restart Direktiven im Unit File entscheidet systemd selbst, ob und wie oft ein abgestürzter Dienst automatisch neu gestartet wird, inklusive konfigurierbarer Backoff Strategie über StartLimitIntervalSec und StartLimitBurst, ohne dass ein zusätzlicher Prozess dafür nötig wäre.

runit erreicht dasselbe Ziel über einen dedizierten runsv Prozess pro Dienst, der strukturell unabhängig von PID 1 selbst arbeitet, während OpenRC die eigentliche Überwachung optional an supervise-daemon delegiert und ohne diese explizite Konfiguration einen abgestürzten Dienst nicht automatisch neu startet, sondern lediglich beim nächsten manuellen oder geplanten Aufruf als gestoppt meldet.

6. Warum systemd auf Servern zum Standard wurde

systemd hat sich vor allem deshalb als Standard etabliert, weil es weit über reine Prozessverwaltung hinausgeht und mit journald, systemd-networkd, systemd-resolved, systemd-timers und Cgroup basierter Ressourcenkontrolle ein durchgängiges Ökosystem liefert, das viele Aufgaben abdeckt, für die klassische Init Systeme separate, lose gekoppelte Werkzeuge wie cron, syslog oder NetworkManager benötigten.

Für Ops Teams bedeutet das eine einheitliche Kommandozeile über systemctl und journalctl für praktisch alle Systemaspekte, gute Dokumentation, breite Distributions Unterstützung von Debian über RHEL bis SUSE, und ein riesiges Ökosystem an fertigen Unit Files, was den praktischen Aufwand gegenüber dem theoretisch schlankeren, aber fragmentierteren Werkzeugkasten von OpenRC oder runit deutlich reduziert.

7. Wann Alpine und Void für schlanke Container Images gewählt werden

Alpine Linux setzt bewusst auf OpenRC statt systemd, weil musl libc und BusyBox als Basis ohnehin schon auf minimale Größe optimiert sind und ein vollwertiges systemd mit seinem Cgroup, DBus und Journal Unterbau diesem Ziel fundamental widersprechen würde. Für Container Basis Images, bei denen jedes zusätzliche Megabyte Image Größe und jede zusätzliche Angriffsfläche zählt, passt OpenRCs schlanker Fußabdruck deutlich besser.

Void Linux geht mit runit als Standard Init System noch einen Schritt weiter in Richtung Minimalismus und Vorhersagbarkeit, während in der Praxis viele Container ohnehin überhaupt kein vollständiges Init System benötigen: Ein einzelner Prozess pro Container mit einem schlanken Signal Handler wie tini reicht für die meisten containerisierten Anwendungen bereits aus, sodass sich die Init System Debatte in Container Umgebungen oft eher auf Nebenprozesse wie Cron Jobs innerhalb eines Containers beschränkt.


# Alpine Container: OpenRC Dienst innerhalb eines Docker Images einrichten
FROM alpine:3.20
RUN apk add --no-cache openrc myapp
RUN rc-update add myapp default
CMD ["/sbin/openrc-run"]

# Alternative: minimaler Signal Handler statt vollem Init System
CMD ["tini", "--", "/usr/bin/myapp"]

8. Praktische Auswirkungen für den täglichen Ops Alltag

Logging unterscheidet sich deutlich: systemd sammelt strukturierte Logs binär über journald mit journalctl als Abfragewerkzeug, während OpenRC und runit klassisch auf Textdateien oder externe Logger wie syslog-ng setzen, was zwar weniger komfortabel durchsuchbar ist, aber ohne zusätzliche Journal Rotation und Binärformat Abhängigkeit auskommt und sich einfacher in bestehende Log Aggregation Pipelines einspeisen lässt.

Debugging Befehle unterscheiden sich entsprechend: systemctl status liefert unter systemd sofort Exit Code, letzte Log Zeilen und Abhängigkeitsstatus in einer Ausgabe, während unter OpenRC rc-service status und unter runit sv status jeweils nur den reinen Laufzeitstatus zeigen und für Details ein separater Blick in die jeweilige Log Datei nötig ist.

9. Empfehlung je nach Einsatzzweck

Für klassische virtuelle oder physische Server mit gemischten Diensten, Netzwerkkonfiguration und komplexen Abhängigkeiten bleibt systemd die pragmatische Standardwahl, schon allein wegen der breiten Distributions Unterstützung und des riesigen Ökosystems an vorgefertigten Unit Files für praktisch jede gängige Serversoftware.

Für schlanke Container Basis Images, minimalistische Embedded Systeme oder Umgebungen, in denen Vorhersagbarkeit und ein möglichst kleiner Audit Umfang wichtiger sind als Feature Reichtum, liefern OpenRC und runit einen bewussten, gut begründeten Gegenentwurf, der in seiner jeweiligen Nische seit Jahren zuverlässig funktioniert und dort keineswegs als veraltet gelten sollte.

Merkmal systemd OpenRC runit
Konfigurationsform Deklarative Unit Files Shell Skripte mit Dependency Direktiven Einfache run Skripte pro Dienst
Service Supervision Fest in PID 1 integriert Optional über supervise-daemon Dedizierter runsv Prozess pro Dienst
Logging Binär über journald Textdateien oder externer Logger Textdateien oder externer Logger
Typischer Einsatz Klassische Server, große Distributionen Alpine Linux, Gentoo Void Linux, minimalistische Setups
Code Umfang Sehr groß, viele Zusatzkomponenten Klein bis mittel Sehr klein, wenige tausend Zeilen

Mironsoft

Server-Administration, Docker-Hosts und Performance-Tuning

Linux-Server, die niemand im Team richtig versteht?

Wir übernehmen Setup, Absicherung und Performance-Tuning von Linux-Servern und Docker-Hosts für Magento-Deployments, dokumentiert und nachvollziehbar statt gewachsen und unklar.

Server-Audit

Bestehende Server-Konfiguration auf Sicherheitslücken und Performance-Bremsen prüfen.

Docker-Host-Setup

Produktionsreife Docker-Umgebungen für Magento sauber aufsetzen und absichern.

Monitoring & Tuning

Ressourcenverbrauch messen und Systemd, Kernel und Dienste gezielt optimieren.

10. Zusammenfassung

Init Systeme

systemd

Feature reicher Standard für klassische Server mit vielen Diensten

OpenRC

Shell Skripte plus Dependency System, Standard bei Alpine Linux

runit

Minimalistische Supervision Trees, Standard bei Void Linux

Faustregel

Server: systemd, schlanke Container Images: OpenRC oder runit

11. FAQ: Init Systeme

1Was genau ist PID 1 und warum ist die Wahl des Init Systems wichtig?
PID 1 ist der erste Userspace Prozess nach dem Kernel Start und bildet die Wurzel des gesamten Prozessbaums. Er ist verantwortlich für das Einsammeln verwaister Kindprozesse, das Starten der Systemdienste und je nach Init System auch deren Überwachung, weshalb seine Architektur weitreichende praktische Konsequenzen hat.
2Warum dominiert systemd auf den meisten Linux Servern?
systemd bündelt Prozessverwaltung, Logging über journald, Netzwerkkonfiguration und Timer in einem durchgängigen Ökosystem mit einheitlicher Kommandozeile, breiter Distributions Unterstützung und einem riesigen Angebot an vorgefertigten Unit Files, was den praktischen Aufwand für Ops Teams deutlich reduziert.
3Warum setzt Alpine Linux auf OpenRC statt systemd?
Alpine ist auf minimale Image Größe optimiert und nutzt musl libc sowie BusyBox als schlanke Basis. Ein vollwertiges systemd mit Cgroup, DBus und Journal Unterbau würde diesem Ziel widersprechen, während OpenRCs kleinerer Fußabdruck deutlich besser zu Container Basis Images passt.
4Was unterscheidet runit grundlegend von systemd?
runit setzt auf minimalistische Supervision Trees mit einem dedizierten runsv Prozess pro Dienst und einem einfachen run Skript, während systemd deklarative Unit Files mit einem umfangreichen Dependency Graphen und zahlreichen integrierten Zusatzkomponenten wie journald verwendet.
5Wie funktioniert Service Supervision bei OpenRC?
OpenRC delegiert die eigentliche Überwachung optional an das Kommando supervise-daemon. Ohne diese explizite Konfiguration startet OpenRC einen abgestürzten Dienst nicht automatisch neu, sondern meldet ihn erst beim nächsten manuellen oder geplanten rc-service Aufruf als gestoppt.
6Brauchen Docker Container überhaupt ein vollständiges Init System?
Meist nicht: Ein einzelner Prozess pro Container mit einem schlanken Signal Handler wie tini reicht für die meisten containerisierten Anwendungen aus. Ein vollständiges Init System wie OpenRC oder runit lohnt sich erst, wenn mehrere Prozesse innerhalb desselben Containers verwaltet werden müssen.
7Wie unterscheidet sich das Logging zwischen systemd und OpenRC oder runit?
systemd sammelt strukturierte Logs binär über journald mit journalctl als Abfragewerkzeug, während OpenRC und runit klassisch auf Textdateien oder externe Logger wie syslog-ng setzen, was einfacher in bestehende Log Aggregation Pipelines passt, aber weniger komfortabel durchsuchbar ist.
8Ist runit für Produktionsserver geeignet, nicht nur für Container?
Ja, Void Linux nutzt runit als vollwertiges Init System auf regulären Servern, nicht nur in Containern. Für komplexe Serverlandschaften mit vielen Abhängigkeiten fehlen aber Komfortfunktionen wie ein automatischer Dependency Graph, wie ihn systemd bietet.
9Wie starte und überwache ich einen Dienst unter runit?
Ein Dienst bekommt ein eigenes Verzeichnis unter /etc/sv mit einem ausführbaren run Skript, das über einen Symlink in /var/service aktiviert wird. Status und Neustart erfolgen über die Kommandos sv status und sv restart gegen dieses Verzeichnis.
10Kann ich systemd und OpenRC auf demselben System parallel nutzen?
Nicht sinnvoll als PID 1, da nur ein Init System diese Rolle gleichzeitig übernehmen kann. In Containern lässt sich aber ein OpenRC oder runit Setup innerhalb eines Images unabhängig vom Host Init System des darunterliegenden systemd basierten Servers betreiben.