Che cos'è systemd?


systemd server dedicato linux
Systemd è un gestore di sistema e di servizi per Linux, compatibile con gli initscript SysV e LSB. Esso fornisce una grande capacità di parallelizzazione, usa socket e D-Bus per l'avvio dei demoni, offre un avvio su richiesta dei demoni, tiene traccia dei processi con l'utilizzo del control groups di Linux, supporta lo snapshotting e il restore dello stato del sistema, ed inoltre implementa un elaborato servizio di controllo logico basato sulle relazioni delle dipendenze.

Il principale comando per l’uso di systemd è systemctl.

Sostanzialmente, systemd inizializza e supervisiona l'intero sistema ed è basato sul concetto di units composto da nome/tipo stessi del file di configurazione da maneggiare.

Ci sono sette differenti tipi di units:


  • service: esistono tipologìe ovvie di unità: demoni che possono essere avviati, fermati, riavviati, ricaricati.
  • socket: questa unità contiene un socket nel file-system o su Internet. systemd attualmente supporta i socket AF_INET, AF_INET6, AF_UNIX di tipo stream, datagram esequential packet. Può inoltre supportare i classici FIFO come transport. Ogni unità socket ha un servizio corrispondente, che viene inizializzato se la prima connessione avviene sul socket o FIFO (ad esempio nscd.socket inizializza nscd.service su una connessione in ingresso).
  • device: questa unità incapsula un dispositivo nell'albero dei dispositivi Linux. Se uno di loro viene contrassegnato attraverso una regola udev (udev rules), sarà esposto come unità dispositivo in systemd. Le proprietà impostate con udev possono essere usate come configurazione per impostare le dipendenze per le device units.
  • mount: questa unità incapsula un punto di montaggio (mount point) nel filesystem.
  • automount: questo tipo di unità incapsula un punto di automontaggio nel filesystem. Ogni unità automount corrisponde ad una unità mount, che viene avviata (montata) non appena la directory automount è accessibile.
  • target: questo tipo di unità per il logical grouping: invece di fare qualcosa autonomamente, semplicemente fa riferimento ad altre unità che possono essere controllate in gruppo. (ad esempio multi-user.target, che è un target che svolge praticamente il ruolo di run-level 5 nel classico sistema SysV; o bluetooth.target richiesto appena un dispositivo bluetooth è disponibile e che semplicemente avvìa di conseguenza i servizi relativi altrimenti non necessari: bluetoothd e obexd e simili).
  • snapshot: simile alle unità target, attualmente non fanno nulla se nonché essere un riferimento per altre unità.


Caratteristiche systemd

Systemd dispone di diverse caratteristiche estremamente utili e particolari, vediamone qualcuna in dettaglio: attivazione di D-Bus per avviare i servizi; avvìo on-demand dei demoni; aggressive capacità di parallelizzazione usando il socket; supporta lo snapshotting e il ripristino dello stato del sistema; monitora tutti i punti di montaggio e può essere usato per modificarli. /etc/fstab può essere usato come configurazione addizionale. Usando l'opzione comment= di fstab, è possibile persino marcare le voci in /etc/fstab per lasciare a systemd il controllo dei punti di montaggio; implementa una logica di controllo del servizio basata sulle dipendenze. Inoltre, per ogni processo generato, systemd controlla: L'ambiente, i limiti delle risorse, directory working e root, umask, OOM killer adjustment, nice level, IO class and priority, CPU policy and priority, CPU affinity, timer slack, user id, group id, group id supplementari, directory leggibili/scrivibili/inaccessibili, mount flags condivise/private/secondarie, capabilities/bounding set, secure bits, CPU scheduler reset of fork, /tmp name-space privati, controllo cgroup per vari sottosistemi. Inoltre, è possibile connettere facilmentestdin/stdout/stderr dei servizi a syslog, /dev/kmsg, arbitrary TTYs. Se connesso ad un TTY per input, systemd farà in modo che un processo ottenga un accesso esclusivo, opzionalmente attendendo o forzando. Ed ancora: compatibilità con /dev/initctl. Questa compatibilità è infatti implementata con il servizio FIFO-activated, che semplicemente traduce queste richieste ereditate in richieste D-Bus; Compatibilità con SysV init scripts: Si avvantaggia di LSB e degli headers Red Hat chkconfig se disponibili, altrimenti usa le informazioni disponibili, come le priorità di avv'o in /etc/rc.d. Questi script init vengono semplicemente considerati una fonte di configurazione differente, facilitano il percorso d'aggiornamento ai servizi systemd; file di configurazione /etc/fstab: solo un'altra fonte di configurazione. Usando l'opzione comment= di fstab, è possibile marcare le voci in /etc/fstab per far controllare a systemd i punti di automontaggio.

Strumenti systemd

systemd is a suite of system management daemons

All'avvio systemd attiva (come predefinito), l'unità target default.target il cui compito è quello di attivare i servizi ed altre unità a seconda delle dipendenze richieste. Per gestire l'unità da attivare, systemd analizza gli argomenti della propria linea di comando kernel attraverso l'opzione systemd.unit=. Quest'ultima può essere usata per avvii temporanei differenti. I classici run-level sono rimpiazzati come di seguito: systemd.unit=rescue.target è uno speciale target per impostare un sistema base e la rescue shell (similli al run-level 1); systemd.unit=emergency.target è molto simile al init=/bin/sh ma con l'opzione d'avvìo per l'intero sistema; systemd.unit=multi-user.target per impostare un sistema multi utente non grafico;systemd.unit=graphical.target per impostare il login grafico. systemctl è lo strumento principale da usare. Combina le fuzionalità dei servizi e di chkconfig per abilitarli/disabilitarli permanentemente o solo per la connessione corrente.

Vediamo ora come avviare/fermare o abilitare/disabilitare i servizi:

Attiva un servizio immediatamente:

systemctl start foo.service


Disattiva un servizio immediatamente:

systemctl stop foo.service


Riavvia un servizio:

systemctl restart foo.service


Mostra lo stato di un servizio o se è avviato o meno:

systemctl status foo.service


Abilita un servizio per essere inizializzato all'avvìo:

systemctl enable foo.service


Controlla se un servizio è già abilitato o meno:

systemctl is-enabled foo.service; echo $?


HOSTNAME: L'hostname è configurato in /etc/hostname. Il file può contenere il nome del dominio di sistema, se esiste, tuttavia nel momento di scrivere hostnamectl non si può configurare il FQDN.

Per configurare l'hostname corto:

# hostnamectl set-hostname myhostname


La console virtuale è configurata in /etc/vconsole.conf:

/etc/vconsole.conf
KEYMAP=it FONT= FONT_MAP=


MODULI DEL KERNEL E MODULI EXTRA DI SYSTEMD

I moduli necessari da caricare sono gestiti automaticamente da udev, cosicché, se non si vuole usare qualcuno dei moduli fuori dal kernel, non c'è bisogno di mettere i moduli che dovrebbero essere caricati al boot in nessun file di configurazione. Tuttavia, ci sono casi in cui si vuole caricare un modulo extra durante il processo di avvio oppure evitare il caricamento di un altro perché il computer funzioni correttamente.

I moduli extra al kernel da caricare durante il boot sono configurati in una lista statica in /etc/modules-load.d/. Ogni file di configurazione ha il nome nello stile di /etc/modules-load.d/[programma].conf/. I files di configurazione dovrebbero semplicemente contenere una lista con i nomi dei moduli da caricare, separati dal tasto INVIO. Le linee vuote o quelle dove il primo carattere che non è uno spazio è # oppure ; sono ignorate.


Gestire le dipendenze di systemd

systemd linux demone gestione processi

Con systemd le dipendenze possono essere risolte progettando le unità correttamente. Il caso più tipico è che l'unità A richieda l'unità B per poter funzionare prima che A parta. In questo caso aggiungere Requires=B e After=B alla sezione [Unit] di A. Se la dipendenza è opzionale aggiungere, invece, Wants=B e After=B. Notare che Wants= e Requires= non includono After=, il che significa che se After= non è specificato, le due unità saranno avviate in parallelo.

Le dipendenze sono di solito posizionate sui .service e non sui .target. Per esempio, network.target è richiamato qualsiasi sia il servizio che configuri l'interfaccia di rete, quindi avviare successivamente la propria unità personalizzata è sufficiente in quanto network.target è avviato comunque. TYPE: ci sono parecchi tipi differenti di avvio da considerare quando si scrive un servizio personalizzato. Ciò è configurato tramite il parametro Type= nella sezione [Service]. Vedere man systemd.service per una spiegazione più dettagliata.

  • Type=simple(default): systemd presuppone che il servizio deve essere avviato immediatamente. Il processo non può essere suddiviso. Non usare questo tipo se altri servizi hanno bisogno di essere disposti con questo servizio, a meno che non sia attivato dal socket.
  • Type=forking: systemd presuppone che il servizio deve essere avviato prima il processo sia suddiviso e il genitore sia concluso. Per i classici demoni usare questo tipo a meno che non si sappia che non è necessario, come la maggior parte dei demoni usa il double-forking per segnalare che sono pronti.
  • Type=oneshot: E' utile per scripts che eseguono un singolo lavoro e si concludono. Si può configurare pure con RemainAfterExit=yes in modo che systemd consideri il servizio ancora attivo anche dopo che il processo si è concluso.
  • Type=notify: Identico a Type=simple, ma con l'accorgimento che il demone invierà un segnale a systemd quando sarà pronto. L'implementazione di riferimento per questa notifica è fornita da libsystemd-daemon.so.
  • Type=dbus: Il servizio è considerato pronto quando lo specificato BusName appare nel sistema di bus si DBus.

Target

"Runlevels" è un concetto superato in systemd che ha invece il concetto di target (lett. "bersagli") che adempiono uno scopo simile a quello dei runlevel, ma che hanno un comportamento differente. Ogni target ha un nome anziché un numero ed è usato per raggiungere uno specifico scopo con la possibilità di averne più di uno attivo nello stesso momento. Ci sono target che simulano i runlevel di SystemVinit, è così possibile passare da un target all'altro utilizzando il comando telinit RUNLEVEL.

CAMBIARE IL TARGET PREDEFINITO ALL'AVVIO: il target standard è default.target, che è abbinato in modo predefinito a graphical.target (che corrisponde al vecchio runlevel 5). Per cambiare il target predefinito al boot, aggiungere uno dei seguenti parametri del kernel alla linea nel bootloader:

  • systemd.unit=multi-user.target (che corrisponde al vecchio runevel 3);
  • systemd.unit=rescue.target (che corrisponde al vecchio runevel 1).

JOURNAL: systemd possiede un proprio sistema di log chiamato journal. Tuttavia, far funzionare il demone syslog non è più richiesto. Per leggere il log si usa:

# journalctl


Di default (quando Storage= è configurato a auto in /etc/systemd/journald.conf), il journal scrive in /var/log/journal/. La directory /var/log/journal/ è parte di core/systemd. Se si è cancellata intenzionalmente o se qualche programma lo ha fatto systemd non lo riicreerà automaticamente, tuttavia sarà ricreata durante il prossimo aggiornamento di systemd. Fino a quel momento i log saranno scritti in /run/systemd/journal. Ciò significa che i log saranno persi al riavvio. Se il journal è persistente (non volatile) la sua dimensione è fissata al 10% della dimensione del rispettivo file system. Per esempio con /var/log/journal allocato su una partizione di root di 50 GiB comporterebbe 5 GiB di dati nel journal.

La dimensione massima del journal persistente può essere controllata attraverso SystemMaxUse in /etc/systemd/journald.conf, così per limitarla ad esempio a 50 MiB decommentare ed editare la linea corrispondente linea:

SystemMaxUse=50M