Nebojte se systemd: co to je a co umí?

23. 5. 2016
Doba čtení: 5 minut

Sdílet

Systemd je stále více používaný init systém. V tomto seriálu se postupně seznámíme se systemd, jeho konfigurací základními odlišnostmi od System V init (zkráceně sysvinit).

System V byl původně jeden z UNIXů. System V init tedy odkazuje na init tohoto UNIXu. Odsud byl později převzat do většiny linuxových distribucí a stal se de facto standardem. Protože se od svého počátku výrazně nezměnil, trpí několika neduhy, které se snažily mnohé projekty tak či onak napravit. Z tohoto důvodu vznikl i systemd. Název vznikl z původně UNIXové konvence pojmenovávat démony malými písmeny s přidaným d na konec. Proto je název psán malými písmeny.

Systemd vytvořil v roce 2010 zaměstnanec Red Hatu Lennart Poettering ve spolupráci s Kay Sieversem a několika dalšími lidmi. Již od začátků se distancují od jakékoliv závislosti na Red Hatu a označují systemd jako nezávislý projekt, který vznikl z osobního popudu. Od té doby příspělo kódem přes pět set lidí a systemd rozšířil se do většiny hlavních distribucí (bez systemd je např. Gentoo, Slackware nebo fork Debianu Devuan).

Hlavní nevýhody sysvinit, a tedy důvody vzniku systemd, jsou podle autorů především nulová paralelizace při startu, nemožnost dynamického spouštění úloh, sledování procesů a jejich omezování. Systemd využívá mnoho specifik nového jádra (jako např. cgroups), takže není a nebude kompatibilní se staršími linuxovými jádry.

Init obecně

Po zavedení jádra systému se spustí /sbin/init (popř. cesta specifikovaná v boot parametru init) s PID 1, jehož úkolem je spustit init skripty, které se starají o samotný chod systému; tedy připojují disky, obsluhují démony apod. Init skript bývá buď shellový skript, jak v případě sysvinit či runit, nebo binární spustitelný soubor v případě systemd.

Service manažer je program, který se stará o sledování a ovládání procesů (tedy je spouští, ukončuje, sleduje, jestli neselhaly, omezuje jejich dobu běhu…). Init, init skript a service manažer dohromady tvoří init systém. Proto je systemd init systém: obsahuje init, který spustí init skript, který se již stará o chod systém včetně dohledu nad démony.

Démon je proces běžící na pozadí bez přímé obsluhy uživatelem. V sysvinit jsou démoni v adresáři /etc/init.d, ve kterém má každý svůj obslužný skript. Tento skript je typicky jednoduchý switch v shellu, který podle předaného parametru provede spuštění, zastavení či restart.

Stav systému je definován pomocí očíslovaných běhových úrovní (runlevels). Každá úroveň má složku /etc/rc#.d/ (kde # je číslo úrovně), ve které jsou všechny skripty, které se mají spustit pro dosažení dané běhové úrovně. Na démony, které chceme spouštět automaticky na nějaké běhové úrovni, vytvoříme symbolický odkaz ze složky  /etc/rc#.d.

Systemd sjednocuje tyto pojmy do abstrace pojmenované jednotka. Jednotky slouží několika účelům a podle nich se dělí na typy. Typ služba má stejnou funkcionalitu jako démon. Má za úkol ovládat nějaký proces běžící na pozadí. Běhové úrovně nahrazuje typ cíl. Princip zůstává stejný. Každý cíl má definované jednotky, které se mají spustit pro dosažení konkrétního stavu počítače. Cíle nejsou očíslované, ale pojmenované. Např. graphical.target pro nastartování grafického prostředí. Pro zpětnou kompatibilitu odpovídají původní očíslované běhové úrovně pojmenovaným cílům. Tedy telinit 5 má stejný efekt jako systemctl isolate graphical.target. Opačně to neplatí, některé cíle nemají číselný ekvivalent.

Protože cíle, služby a několik dalších typů jsou sjednocené do termínu jednotky, systemd nahrazuje původní shellové skripty vlastním deklarovaným jazykem, který je pro všechny typy jednotek stejný. Samozřejmě různé typy mají různé možnosti konfigurace, ale o tom se dozvíme v následujících dílech. Díky tomuto jazyku vytvořenému přímo na míru odpadá nutnost psát opakovaně stejné kusy kódu. Syntaxe je podobná desktop souborům a je tak snadno čitelná a parsovatelná. Příklad jednotky viz dále.

Co systemd umí?

Systemd obsluhuje jednotky, sleduje jejich stav, umí je restartovat při pádu, logovat chyby. Umožňuje omezovat zdroje, jako dostupnou paměť, využití procesoru apod. Dále sleduje procesy pomocí cgroups namísto klasického PID, díky čemuž se nemohou vyvázat ani při tzv. double-forking, a proto vždy víme, které procesy daná jednotka vlastní. Systemd také zprostředkovává komunikaci mezi procesy a umožňuje nastavit spouštění jednotek až ve chvíli, kdy jsou opravdu potřeba (tzv. on demand loading).

Místo psaní konkrétních konfiguračních souborů je možné používat šablony, tedy například je možné mít pro více terminálů getty jen jednu šablonu getty@.service. Další terminál pak snadno přidáme jen použitím šablony s dalším číslem.

Systemd umí řešit závislosti mezi démony a to i v případě vzniku cyklů. Princip si demonstrujeme na příkladu. Máme jednotku cups-browsed.service, která potřebuje pro svůj běh jednotky org.cups.cupsd.service a avahi-daemon.service, proto má ve své konfiguraci uveden parametr Wants=org.cups.cupsd.service avahi-daemon.service. Zároveň předpokládá, že démoni, které vyžaduje, jsou již nastartovaní, což zajistí parametr After=org.cups.cupsd.service avahi-daemon.service. Systemd díky tomu ví, že nejdříve je nutné spustit tyto dvě závislost, proto je přidá do fronty jednotek ke spuštění a až poté přidá naši požadovanou jednotku. Protože jednotky mohou mít rekurzivní závislosti, může být graf závislostí poměrně složitý. Vždy se nejdříve zkontroluje celá transakce. Pokud by nebylo možné jednotky spustit, např. z důvodu nevyřešitelných cyklů, je celá transakce odmítnuta ještě před samotným spuštěním a nestane se tak, že by systemd skončil v nějakém nedefinovaném stavu.

cups-browsed.service

[Unit]
Description=Make remote CUPS printers available locally
After=org.cups.cupsd.service avahi-daemon.service
Wants=org.cups.cupsd.service avahi-daemon.service

[Service]
ExecStart=/usr/bin/cups-browsed

[Install]
WantedBy=multi-user.target

org.cups.cupsd.service

[Unit]
Description=CUPS Scheduler
Documentation=man:cupsd(8)

[Service]
ExecStart=/usr/bin/cupsd -l
Type=simple

[Install]
Also=org.cups.cupsd.socket org.cups.cupsd.path
WantedBy=printer.target

avahi-daemon.service

[Unit]
Description=Avahi mDNS/DNS-SD Stack
Requires=avahi-daemon.socket

[Service]
Type=dbus
BusName=org.freedesktop.Avahi
ExecStart=/usr/bin/avahi-daemon -s
ExecReload=/usr/bin/avahi-daemon -r
NotifyAccess=main

[Install]
WantedBy=multi-user.target
Also=avahi-daemon.socket
Alias=dbus-org.freedesktop.Avahi.service

Kromě toho jsou se systemd dodávaní démoni, jako např. journald pro logování nebo logind pro správu přihlašování uživatelů. Dále také zprostředkovává některá rozhraní mezi kernelem a aplikacemi.

bitcoin_skoleni

Hlavní výhody a nevýhody oproti sysvinit

Ještě se v kostce podíváme na hlavní výhody a nevýhody. Konkrétně si je přiblížíme v následujících článcích:

  • konfigurační soubory – odpadá nutnost psaní redundantního kódu démonů
  • automatické řešení závislostí
  • standardizace napříč distribucemi – dnes je jako výchozí ve většině distribucí
  • pokročilá práce s démony – spouštění až když jsou opravdu potřeba, jejich sledování a omezování
  • paralelizace při startu
  • do jisté míry kompatibilita s sysvinit (např. fstab, skripty v /etc/init.d jsou spouštěny také)
  • nekompatibilta se starším kernelem a jinými OS než Linux

Systemd je často vytýkána snaha pokrýt velkou část úloh, které dříve mělo na starosti více programů. Na druhou stranu poskytuje standardizované, jednoduché a efektivní rozhraní pro řešení administátorských úloh. V následujících článcích rozebereme jednotlivé části systemd a ukážeme si nějaké příklady.

Odkazy

  1. Oficiální web
  2. Dokumentace Red Hat
  3. Anglická Wikipedie
  4. Manuálová stránka
    man systemd

Autor článku

Autor studuje na Matematicko-fyzikální fakultě. Ve svém volném čase se kromě Linuxu věnuje také vlastní 3D tiskárně.