systemd

Linux.fista
Versio hetkellä 4. kesäkuuta 2019 kello 16.30 – tehnyt Raspi (keskustelu | muokkaukset) (+ IP, DHCP, .link udev)
Siirry navigaatioon Siirry hakuun

systemd on käyttöjärjestelmän ja siinä ajettavien palveluiden käynnistymistä ja sammuttamista ohjaava ns. init-järjestelmä. Useimmat jakelut ovat siirtyneet käyttämään systemd-järjestelmää.

Ominaisuuksia

  • Nopeuttaa järjestelmän käynnistymistä suorittamalla toisistaan riippumattomia tehtäviä rinnakkaisesti
  • Tarjoaa valmiita toimintoja joilla voidaan korvata pitkiä perinteisten init-järjestelmien komentosarjoja
  • Käyttää Linuxin control group -toimintoa prosessien seuraamiseen
  • Yhteensopiva System V init -komentosarjojen kanssa
  • Tarvittaessa viivästää palveluiden aktivointia siihen asti että joku yrittää niitä käyttää

Yksiköt

Tavallisimmin systemd:n tarjoamia työkaluja käytetään palveluiden, kuten sshd tai Cups, hallintaan. Systemd hallitsee palveluiden lisäksi myös muutamaa muunlaista asiaa. Erilaisille systemd:lla käsiteltäville asioille yhteinen termi on yksikkö (englanniksi unit).

Erityyppiset yksiköt erottaa toisistaan helposti nimen loppuosan perusteella. Palvelut päättyvät aina .service-merkkijonoon, kun taas esimerkiksi tiedostojärjestelmien liitospisteitä vastaavien yksiköiden nimien lopussa on aina .mount.

Erityyppisten yksiköiden olemassaolo kannattaa huomioida systemd:n työkaluja käyttäessä. Usein järjestelmää hallittaessa tarvitsee käsitellä lähinnä .service- ja .socket -tyyppisiä yksiköitä.

systemctl

systemctl-työkalua käytetään systemd:n ohjaamiseen. Sen avulla voidaan varsinkin hallita palveluiden käynnistymistä ja sammuttamista. Tässä on käytetty esimerkkinä Avahi-palvelun mukana tulevaa avahi-daemon.serviceä, mutta komennot toimivat vastaavasti myös monille muille palveluille.

Tietoa palveluista

systemctl:n list-units -komennolla saa listauksen kaikista järjestelmän palveluista. Ilman --all -valitsinta saa listauksen vain aktiivisista yksiköistä. Lisäksi --full -valitsin on usein tarpeellinen jotta pitkät yksikönnimet saa kokonaan näkyviin.

systemctl list-units --all

systemctl:n status-komennolla saa selvitettyä tärkeimmät yhteen yksikköön liittyvät tiedot.

systemctl status avahi-daemon.service

Tämän tulisi tulostaa jotain seuraavanlaista:

avahi-daemon.service - Avahi mDNS/DNS-SD Stack
Loaded: loaded (/lib/systemd/system/avahi-daemon.service; enabled)
Active: active (running) since Thu, 27 Oct 2011 10:15:57 +0300; 7h ago
Main PID: 889 (avahi-daemon)
Status: "avahi-daemon 0.6.30 starting up."
CGroup: name=systemd:/system/avahi-daemon.service

Show-komennolla puolestaan saa pidemmän listauksen avahi-daemon.serviceen liittyvistä tiedoista. Se voi olla hyödyllistä esimerkiksi yksikkötiedostoja kirjoitettaessa.

systemctl show avahi-daemon.service

Palveluiden käynnistäminen ja pysäyttäminen

# Käynnistä Avahi-palvelu
systemctl start avahi-daemon.service
# Pysäyttäminen vastaavasti stop-käskyllä:
systemctl stop avahi-daemon.service

Automaattisesti käynnistettävät palvelut

Edellämainitut start- ja stop-komennot käynnistävät ja pysäyttävät yksikön, mutta ne eivät vaikuta siihen, mitä käynnistetään automaattisesti. Tähän sen sijaan käytettäisiin systemctl:n enable- ja disable-komentoja.

# Käynnistä sshd.service automaattisesti järjestelmän käynnistyessä
systemctl enable sshd.service
# Poista sshd.service automaattisesti käynnistettävien yksiköiden joukosta
systemctl disable sshd.service

Journal

systemd:n mukana tulee journaliksi kutsuttu lokivarasto, johon kerätään muun muassa dmesg -komennonkin tulostama kernelin loki, syslog -viestit ja palveluiden ns. stdout/stderr -viestit.

Viestit tallentuvat normaalisti /var/log/journal/ -hakemistossa sijaitseviin tiedostoihin. Toisin kuin monet muut lokitiedostot, journalin tiedostot eivät ole tekstitiedostoja. Tämän takia esimerkiksi perinteinen grep -työkalu ei suoraan sovellu niiden käsittelyyn yhtä hyvin kuin perinteisten syslog-palveluiden ylläpitämien tekstimuitoisten lokien käsittelyyn.

Journalin sisältöä voi tarkastella systemd:n journalctl -komennolla. Yksinkertaisimmillaan komennon voi ajaa ilman parametreja:

journalctl

Näin kutsuttuna journalctl näyttää kaikki journaliin tallennetut viestit. Oletuksena viestit näytetään tekstinä, jonka asettelu muistuttaa perinteistä syslog-lokitiedostoissa käytettyä asettelua. Vaikka journalctl normaalisti terminaalissa ajettuna automaattisesti avaa lokiviestit lessin sisään, voi sen tulosteen myös putkittaa muille prosesseille:

journalctl | grep avahi-daemon

Näin voisi esimerkiksi hakea lokista vain viestejä, jotka liittyvät Avahi-palveluun. Mikäli journalctl:n stdout ei ole terminaali, se ei käynnistä lessiä.

Haku yksikön perusteella

Edellä esitettiin, kuinka grepin avulla voisi hakea journalista kaikki avahiin liittyvät viestit. Esitetty tapa kuitenkin on jonkin verran epätarkka, sillä myös muut kuin jonkun palvelun tekemät viestit voivat sisältää hakuun liittyvän palvelun nimen.

Jokaiseen journaliin kirjattuun viestiin kuitenkin erikseen merkitään, mistä yksiköstä viesti on peräisin. Journalctl voi pyydettässä hyödyntää tätä tietoa näytettävien lokitietojen rajaamiseen:

journalctl -u avahi-daemon

Nyt journalctl:n pitäisi näyttää vain oikeasti avahi-daemon.servicesta peräisin olevat viestit, vaikka journalissa olisi muitakin merkkijonon avahi-daemon sisältäviä viestejä.

Haku käynnistyskierroksen perusteella

Usein halutaan katsoa vain lokeja alkaen vain siitä hetkestä, kun kone viimeksi käynnistettiin. Tähän voi hyödyntää journalctl:n -b -valitsinta:

journalctl -b

Tämä näyttää kaikki nykyiseen käynnistyskierrokseen liittyvät viestit. Valitsimen voi yhdistää myös esimerkiksi edellä esiteltyyn -u -valitsimeen:

journalctl -b -u avahi-daemon

Oletuksena -b -valitsin näyttää nykyisen käynnistyskierroksen, mutta se voi myös ottaa vastaan parametrin, jolla valitaan joku muu käynnistyskierros. Parametrista ehkä tavallisimmin tarpeellinen on negatiivinen numero, joilla saa valittua uusia käynnistyskierroksia:

journalctl -b -1
journalctl -b -2

Komennoista ylempi näyttää nykyistä edeltävän käynnistyskierroksen viestit ja jälkimmäinen sitä edeltävän kierroksen viestit.

Myös positiivisia numeroita voi käyttää. Niissä esimerkiksi 1 vastaa vanhinta journaliin tallentunutta käynnistyskierrosta, ja 2 toiseksi vanhinta.

Mikäli on vaikea tietää tai muistaa, monenko käynnistyskerran takana joku kiinnostava osa lokia on mutta haettu ajankohta on tiedosssa, voi ajankohtaa vastaavan käynnistyskierrosnumeron selvittää --list-boots -valitsimella:

journalctl --list-boots

Haku päivämäärän mukaan

Esimerkiksi tietyn viikon viestit voi hakea --since -valitsimen ja --until -valitsimen avulla:

journalctl --since 2014-04-07 --until 2014-04-13

Omat yksikkötiedostot

Suurin osa käyttäjistä tulee toimeen ohjelmien mukana tulevilla yksikkötiedostoilla, mutta toisinaan on tarvetta joko muokata olemassaolevia yksiköitä tai luoda kokonaan uusia. Kumpikin on suhteellisen helppoa, sillä yksikkötiedostot ovat yksinkertaisehkoja tekstitiedostoja. Tiedostoformaatti on dokumentoitu systemd.unit-nimisessä man-sivussa.

Systemd-yksiköitä voivat tehdä myös muut kuin ylläpitäjäkäyttäjät. Lisäämällä hakemistoon ~/.config/systemd/user/ yksikkötiedostoja, käyttäjä voi asettaa omia prosesseja käynnistettäväksi esimerkiksi järjestelmän käynnistyksen yhteydessä tai ajastimella. Käyttäjän omien systemd-yksiköiden ohjaamiseen käytetään komentojen nimissä aina --user-parametria:

 systemctl --user start oma-palvelu.service
 journalctl --user

Järjestelmän yksikkötiedostojen muokkaaminen

Järjestelmän mukana toimitettavat yksikkötiedostot sijaitsevat luultavasti /lib/systemd/system/-hakemistossa. Niitä on mahdollista muokata suoraan sielläkin, mutta mieluummin kannattaa ottaa siellä sijaitsevasta yksiköstä kopio /etc/systemd/system/-hakemistoon ja muokata sitä siellä. Tällöin systemd /etc:n alla sijaitsevaa yksikköä ennemmin kuin /lib:n alla olevaa, ja ohjelmiston päivittyminen ei ylikirjoita paikallisesti tehtyjä muutoksia.

Kokonaan uusien yksikkötiedostojen kirjoittaminen

Joskus on tarpeen luoda kokonaan uusia yksikköjä, esimerkiksi ajamaan joku komento aina koneen käynnistyessä tai pitämään käynnissä jotain ohjelmistoa jonka mukana ei tullut yksikköä systemd:lle.

Myös itse kirjoitetut yksiköt kannattaa sijoittaa /etc/systemd/system/-hakemistoon.

Allaoleva esimerkkiyksikkö ajaa yksikköä käynnistettäessä yksinkertaisen komennon. Sitä voi kokeilla esimerkiksi kopioimalla sen sisällön /etc/systemd/system/hello.service-nimiseen tiedostoon.

[Unit]
Description=A simple example service unit that runs a command when started
[Service]
Type=oneshot
ExecStart=/bin/echo Hello!

Yksikkötiedostoformaatissa erilaisia direktiivejä on kymmeniä, mutta jossain tapauksissa ihan muutama niistä riittää. Usein kannattaa katsoa mallia järjestelmän mukana toimituista yksiköistä /lib/systemd/system/ -hakemistosta ja systemd:n dokumentaatiosta.

Ajastimet

Systemd tarjoaa perinteisen cron-palvelun tapaiset toiminnot komentojen ajastamiseen. Esimerkiksi edellisessä kohdassa tehty hello-palvelu voitaisiin ajastaa käynnistymään kymmenen minuutin välein luomalla tiedosto /etc/systemd/system/hello.timer tähän tapaan:

[Unit]
Description=Ajetaan hello-palvelu kymmenen minuutin välein

[Timer]
# Ensimmäinen ajo 10 minuuttia järjestelmän käynnistyksen jälkeen
OnBootSec=10min
# Ajetaan uudelleen 10 minuuttia edellisen ajon päätyttyä jälkeen
OnUnitInactiveSec=10min
Unit=hello.service

[Install]
WantedBy=default.target

Näin luodut uudet yksiköt on sitten tarpeellista kytkeä päälle ja käynnistää:

systemctl enable hello.service
systemctl enable hello.timer
systemctl start hello.timer

Ajastimet voidaan listata systemctl list-timers -komennolla. Esimerkkituloste:

# systemctl list-timers
NEXT                          LEFT          LAST                          PASSED       UNIT                         ACTIVATES
Mon 2018-08-27 18:20:15 EEST  1h 23min left Mon 2018-08-27 12:16:49 EEST  4h 39min ago certbot.timer                certbot.service
Mon 2018-08-27 23:31:44 EEST  6h left       Sun 2018-08-26 23:31:44 EEST  17h ago      systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Tue 2018-08-28 00:00:00 EEST  7h left       Mon 2018-08-27 00:00:01 EEST  16h ago      logrotate.timer              logrotate.service
Tue 2018-08-28 00:00:00 EEST  7h left       Mon 2018-08-27 00:00:01 EEST  16h ago      man-db.timer                 man-db.service
Tue 2018-08-28 00:00:00 EEST  7h left       Mon 2018-08-27 00:00:01 EEST  16h ago      shadow.timer                 shadow.service

5 timers listed.
Pass --all to see loaded but inactive timers, too.

Verkon hallinta

Kiinteä IP-osoite

/etc/systemd/network/eth0.network:

[Match]
# Verkkokortin nimi
Name=eth0

[Network]
Description=eth0:n kiinteä verkko
Address=192.168.1.11/24
# Gateway IP Address
Gateway=192.168.1.1
# DNS server address
DNS=192.168.1.1
#Domains=home.lan

DHCP

/etc/systemd/network/eth0.network:

[Match]
# Verkkokortin nimi
Name=eth0

[Network]
Description=eth0:n verkko DHCP:lla
# DHCP no|yes|ipv4|ipv6
DHCP=ipv4
# DNS server address
#DNS=192.168.101.1
#Domains=home.lan

Verkkokortin nimen vaihtaminen (.link)

Verkkokorttien nimiä voidaan vaihtaa SystemD:n .link-tiedostoilla. Verkkokortin uudelleennimeäminen on hyödyksi silloin, kun esimerkiksi palomuurisääntöjä pitää voida helpommin siirtää järjestelmästä toiseen. Tässä esimerkissä verkkokortti nimeltä eno1 uudelleennimetään phy0-nimiseksi.

Listataan verkkokortit:

# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 74:d0:2b:2c:6e:d7 brd ff:ff:ff:ff:ff:ff

Luodaan /etc/systemd/network/10-phy0.link:

[Match]
# Käytetään MAC-osoitetta tunnistamaan verkkokortti
MACAddress=74:d0:2b:2c:6e:d7

[Link]
# Uusi nimi
Name=phy0
Description=USB-portin vasemmalla puolella oleva ylempi verkkokortti
MACAddressPolicy=persistent
# Käännä verkkokortin rautakiihdytettyjä ominaisuuksia pois päältä (offloading)
# ethtool-ohjelmalla näitä voidaan hallita vielä monipuolisimmin
#TCPSegmentationOffload=off
#TCP6SegmentationOffload=off
#GenericSegmentationOffload=off
#GenericReceiveOffload=off
#LargeReceiveOffload=off

Lisätietoa: https://www.freedesktop.org/software/systemd/man/systemd.link.html

Muita Init-järjestelmiä

Vaikka Systemd on aika laajasti käytössä, ei se silti ole ainoa init-järjestelmä. Esimerkiksi perinteinen Sysvinit, uudempi OpenRC tai daemontools ovat tapoja hoitaa järjestelmän käynnistäminen. Helpointa on käyttää Linux-jakelua, josta kyseinen init-järjestelmä löytyy. Esimerkiksi Gentoo käyttää OpenRC:tä.

Katso myös

v  k  m
Palvelin
 Ylläpito  SSH | Tietoturva | Käyttäjien hallinta | Systemd | iptables | Security-Enhanced Linux | AppArmor
 Palvelintyypit  Web-palvelin | Sähköposti | Tietokanta | NFS | Samba
 Komentorivi  Komentorivin perusteet | Komentorivikomennot | Bash-skriptaus
 Tekstieditoreja  nano | vi | emacs
Palvelin-luokka