Comprendere i Target di Systemd: Concetti Essenziali Spiegati
Comprendi i target di systemd, i target di avvio predefiniti, le mappature dei runlevel, l'isolamento, i target personalizzati e i comandi per la risoluzione dei problemi.
Comprendere i Target di Systemd: Concetti Essenziali Spiegati
I target di systemd sono più facili da capire se smetti di pensarli come servizi. Un servizio avvia un processo. Un target raggruppa unità in uno stato di sistema denominato. Quando una macchina si avvia in multi-user.target, systemd non sta avviando un programma chiamato "multi-utente". Sta cercando di raggiungere uno stato in cui le unità desiderate da quel target sono state avviate o almeno hanno avuto tentativi di avvio.
Questa distinzione aiuta quando si eseguono debug di problemi di avvio. Se graphical.target è lento, il target stesso è raramente il problema. Una delle unità di visualizzazione, login, rete, mount o applicazione inserite in quel target è lenta o fallisce. I target ti forniscono la mappa.
Cosa sono i Target di Systemd?
Nell'ecosistema systemd, un target è un tipo speciale di file unit (come i file .service o .socket) che svolge una funzione organizzativa critica. A differenza delle unità di servizio che definiscono come avviare o fermare un processo specifico, le unità target definiscono uno stato di sistema o una collezione di unità che dovrebbero essere attive insieme. Agiscono come punti di raggruppamento logico e punti di sincronizzazione per altre unità systemd.
Pensa ai target come tappe nel percorso operativo del sistema. Quando systemd si avvia, non lancia semplicemente un elenco di servizi in modo arbitrario; lavora per raggiungere un target specifico. Questo target, a sua volta, richiama tutti i servizi, socket, punti di mount e altri target necessari per raggiungere quello stato. Questo approccio basato sulle dipendenze garantisce un processo di avvio prevedibile ed efficiente.
Per chi ha familiarità con i vecchi sistemi init Linux come SysVinit, i target di systemd sono l'equivalente moderno dei runlevel. Mentre SysVinit aveva un insieme fisso di runlevel (ad esempio, runlevel 3 per la modalità testo multi-utente, runlevel 5 per la modalità grafica multi-utente), i target di systemd sono più flessibili. Sono nominati, non numerati, e puoi definire target personalizzati, offrendo maggiore granularità ed estensibilità.
Come Funzionano i Target: Raggruppamento e Dipendenze
I target raggiungono le loro capacità di raggruppamento e definizione dello stato attraverso dipendenze esplicite definite nei loro file unit. Le direttive principali utilizzate per questo sono Wants=, Requires=, After=, e Before=.
Wants=: Specifica dipendenze "deboli". Setarget AWants=unità B, systemd proverà ad avviareunità Bquandotarget Aviene attivato. Tuttavia,target Asi avvierà comunque anche seunità Bnon riesce ad avviarsi. Questo è comunemente usato per raggruppare servizi correlati che sono desiderabili ma non strettamente essenziali.Requires=: Specifica dipendenze "forti". Setarget ARequires=unità B, alloraunità Bdeve essere avviata con successo affinchétarget Asi attivi. Seunità Bfallisce, anchetarget Afallirà o non si avvierà. Questo è usato per dipendenze critiche.After=: Definisce una dipendenza di ordinamento. Setarget AhaAfter=unità B, alloratarget Asi avvierà solo dopo cheunità Bsi è avviata. Questo non implica una dipendenza dal successo, solo dall'ordine.Before=: L'inverso diAfter=. Setarget AhaBefore=unità B, alloraunità Bsi avvierà solo dopo chetarget Asi è avviato.Conflicts=: Assicura che certe unità non siano attive simultaneamente. Setarget AConflicts=unità B, allora attivaretarget Afermeràunità Bse è in esecuzione, e viceversa.
Queste direttive permettono ai target di agire come orchestratori robusti, richiamando servizi e altri target secondo necessità e definendo l'ordine in cui dovrebbero avviarsi. Ad esempio, multi-user.target tipicamente Wants= network.target e vari altri servizi, assicurando che siano attivi quando il sistema raggiunge uno stato multi-utente.
Puoi ispezionare il contenuto di un file unit target per vedere le sue dipendenze:
systemctl cat multi-user.target
Questo comando restituirà il contenuto del file unit multi-user.target, mostrando la sua Description, Documentation, e, crucialmente, le sue direttive Wants=, Requires=, After=, e altre che definiscono cosa costituisce lo stato multi-utente.
Spiegazione dei Target Comuni di Systemd
Systemd fornisce una varietà di target predefiniti, ciascuno corrispondente a uno stato o funzionalità specifica del sistema. Comprenderli è cruciale per l'amministrazione del sistema:
default.target: Questo è il target più importante poiché definisce lo stato predefinito in cui il sistema si avvierà. Di solito è un collegamento simbolico agraphical.target(per desktop) omulti-user.target(per server).graphical.target: Questo target è tipicamente usato per sistemi con un ambiente desktop grafico. Richiamamulti-user.targete poi aggiunge i servizi necessari per il gestore di login grafico e il server di visualizzazione (ad esempio, GDM, LightDM, Xorg, Wayland).multi-user.target: Questo è lo stato standard per sistemi multi-utente senza interfaccia grafica. È comune per i server e fornisce tutti i servizi necessari per l'accesso da riga di comando, la rete e la maggior parte delle operazioni dei demone.basic.target: Uno stato minimale che include i servizi di sistema di base necessari per le operazioni fondamentali, ma prima dimulti-user.target. Tipicamente richiamasysinit.targete altri servizi essenziali.sysinit.target: Questo target viene raggiunto molto presto nel processo di avvio. È responsabile delle attività di inizializzazione del sistema di base come il montaggio dei filesystem di/etc/fstab(esclusi quelli remoti), la configurazione dello swap e altre inizializzazioni relative all'hardware.local-fs.target: Assicura che tutti i filesystem locali specificati in/etc/fstabsiano montati.remote-fs.target: Assicura che tutti i filesystem remoti (ad esempio, NFS, CIFS) specificati in/etc/fstabsiano montati.network.target: Indica che la connettività di rete di base è disponibile (ad esempio, le interfacce di rete sono attive). Non garantisce la piena connettività Internet o l'assegnazione dell'indirizzo IP.network-online.target: Un punto di sincronizzazione per i servizi che vogliono attendere fino a quando il gestore di rete considera la rete online. Non prova che Internet, DNS o un'API remota siano raggiungibili, e funziona come previsto solo quando il relativo servizio wait-online è abilitato.rescue.target: Fornisce una shell per singolo utente con servizi minimi in esecuzione e filesystem locali montati. Utile per il recupero del sistema e la risoluzione dei problemi.emergency.target: Un ambiente ancora più minimale direscue.target. Fornisce una shell sul filesystem di root, che è tipicamente montato in sola lettura. Nessun altro servizio viene avviato. Per situazioni di emergenza critiche.poweroff.target,reboot.target,halt.target: Questi target sono usati rispettivamente per spegnere, riavviare o arrestare il sistema. Quando attivati, fermano la maggior parte dei servizi e preparano il sistema per lo stato di alimentazione desiderato.
Gestione dei Target di Systemd
Interagire con i target di systemd coinvolge principalmente l'utilità da riga di comando systemctl.
Visualizzare i Target Attivi e Predefiniti
Per vedere in quale target il tuo sistema è attualmente in esecuzione:
systemctl get-default
Per elencare tutte le unità target attualmente caricate:
systemctl list-units --type=target
Questo comando mostra i target attivi, caricati e statici, insieme alle loro descrizioni.
Cambiare il Target di Avvio Predefinito
Puoi cambiare il target in cui il sistema si avvia per impostazione predefinita. Ad esempio, per impostare multi-user.target come predefinito:
sudo systemctl set-default multi-user.target
Per tornare a graphical.target:
sudo systemctl set-default graphical.target
Questo comando crea un collegamento simbolico da /etc/systemd/system/default.target al file target desiderato.
Avviare Temporaneamente in un Target Diverso
A volte è necessario avviare in un target specifico solo una volta (ad esempio, per la risoluzione dei problemi). Puoi ottenere questo aggiungendo un parametro del kernel durante l'avvio. Quando appare il menu di avvio GRUB, modifica la voce di avvio (di solito premendo e) e aggiungi systemd.unit=nome_target.target alla riga di comando del kernel.
Ad esempio, per avviare in modalità di ripristino:
systemd.unit=rescue.target
Cambiare Target Durante l'Esecuzione
Puoi passare a un target diverso mentre il sistema è in esecuzione usando il comando systemctl isolate. Questo comando fermerà tutti i servizi non richiesti dal nuovo target e avvierà tutti i servizi richiesti da esso.
Attenzione: Usare systemctl isolate può interrompere il funzionamento del sistema, specialmente se passi a un target di livello molto più basso come multi-user.target da graphical.target su una macchina desktop. Usa con cautela.
Per passare da graphical.target a multi-user.target:
sudo systemctl isolate multi-user.target
Per tornare a graphical.target (supponendo che fosse lo stato precedente):
sudo systemctl isolate graphical.target
Creare Target Personalizzati
Mentre systemd fornisce molti target utili, potresti trovare situazioni in cui creare un target personalizzato è vantaggioso. Questo è particolarmente vero per distribuzioni di applicazioni complesse dove devi raggruppare diversi servizi che dovrebbero sempre avviarsi e fermarsi insieme, o per definire un ambiente specifico per la tua applicazione.
Per creare un target personalizzato:
- Crea un file
.target: Posizionalo in/etc/systemd/system/. Ad esempio,my-application.target.# /etc/systemd/system/my-application.target [Unit] Description=Target Applicazione Personalizzata Wants=my-database.service my-webserver.service After=my-database.service my-webserver.serviceDescription: Una descrizione leggibile dall'uomo.Wants=: Elenca i servizi o altri target che questo target dovrebbe richiamare.After=: Definisce l'ordine. Il target si avvierà dopo queste unità.
- Crea i servizi: Assicurati che
my-database.serviceemy-webserver.service(o qualsiasi servizio elenchi) esistano e siano configurati correttamente. - Ricarica systemd: Informa systemd del nuovo file unit.
sudo systemctl daemon-reload
4. **Abilita e Avvia**: Ora puoi abilitare e avviare il tuo target personalizzato, che a sua volta avvierà i servizi desiderati. bash
sudo systemctl enable my-application.target
sudo systemctl start my-application.target
```
Questo ti permette di gestire un gruppo di servizi correlati come una singola unità logica, semplificando distribuzioni di applicazioni complesse.
Runlevel e Target Senza Giri di Parole
Se provieni da SysVinit, la mappatura approssimativa è:
| Vecchia idea di runlevel | Target systemd comune |
|---|---|
| Modalità di riparazione singolo utente | rescue.target |
| Modalità testo multi-utente | multi-user.target |
| Modalità grafica multi-utente | graphical.target |
| Riavvio | reboot.target |
| Spegnimento | poweroff.target |
Trattalo come un aiuto alla traduzione, non un modello perfetto. I runlevel SysV erano un piccolo insieme fisso di stati numerati. I target di systemd sono unità nominate con dipendenze, e possono essercene molti. Un pacchetto può installare il proprio target. Puoi crearne uno per un flusso di lavoro di distribuzione. Alcuni target sono destinati ad essere isolati; altri sono solo punti di raggruppamento usati durante l'avvio.
Puoi vedere quali target permettono l'isolamento con:
systemctl show multi-user.target -p AllowIsolate
systemctl show basic.target -p AllowIsolate
Questo è importante perché systemctl isolate non è un comando "cambia vista" innocuo. Ferma le unità che non fanno parte della transazione del nuovo target. Su un desktop, isolare multi-user.target di solito fermerà la sessione grafica. Su un server remoto, isolare il target sbagliato può fermare i servizi di rete o di login e bloccarti fuori.
Come i Servizi Diventano Parte di un Target
La maggior parte dell'appartenenza ai target nella vita quotidiana proviene dalla sezione [Install] di un file di servizio:
[Install]
WantedBy=multi-user.target
Quando esegui:
sudo systemctl enable myapp.service
systemd crea un collegamento simbolico sotto una directory come:
/etc/systemd/system/multi-user.target.wants/myapp.service
Quel collegamento simbolico è ciò che fa sì che multi-user.target voglia il servizio durante l'avvio. Il file di servizio può esistere ed essere perfettamente valido senza essere abilitato. In tal caso, avviare multi-user.target non lo richiamerà automaticamente.
Questo è il motivo per cui systemctl start myapp.service e systemctl enable myapp.service risolvono problemi diversi. start lo esegue ora. enable lo collega a un target di avvio futuro. enable --now fa entrambe le cose.
Per verificare se un servizio è abilitato per un target:
systemctl is-enabled myapp.service
systemctl list-dependencies multi-user.target | grep myapp
Se un servizio si avvia manualmente ma non all'avvio, questa è una delle prime cose da controllare.
Un Piccolo Target Personalizzato Che È Effettivamente Utile
I target personalizzati sono più utili quando danno agli operatori un comando per un gruppo di unità correlate. Immagina un semplice stack applicativo:
app-api.service
app-worker.service
app-scheduler.service
Puoi creare:
# /etc/systemd/system/app-stack.target
[Unit]
Description=Stack applicativo
Wants=app-api.service app-worker.service app-scheduler.service
After=network-online.target
Wants=network-online.target
AllowIsolate=no
Poi aggiungi ogni servizio al target:
[Install]
WantedBy=app-stack.target
Dopo daemon-reload, abilita i servizi o il target a seconda del comportamento desiderato:
sudo systemctl daemon-reload
sudo systemctl enable app-api.service app-worker.service app-scheduler.service
sudo systemctl start app-stack.target
Questo ti dà un raggruppamento leggibile senza fingere che il target sia un supervisore di processo. Se app-worker.service fallisce, ispeziona quel servizio. Il target è solo il punto di raggruppamento.
Se vuoi che fermare il target fermi tutti i servizi dello stack, aggiungi PartOf=app-stack.target a ogni servizio:
[Unit]
PartOf=app-stack.target
Ora systemctl stop app-stack.target si propaga ai servizi membri. Questo è spesso il pezzo mancante negli esempi di target personalizzati.
Risoluzione dei Problemi con i Target
I target sono anche preziosi per risolvere problemi di avvio o guasti dei servizi:
- Identificare le dipendenze: Se un servizio non riesce ad avviarsi, ispezionare il target a cui appartiene può rivelare dipendenze mancanti o fallite. Usa
systemctl status <nome_servizio>esystemctl list-dependencies <nome_target>. - Avviare in target minimi: Se il tuo sistema non riesce ad avviarsi in
graphical.targetomulti-user.target, prova ad avviare inrescue.targetoemergency.targetusando il metodo del parametro del kernel. Questo fornisce un ambiente minimale dove puoi diagnosticare i problemi senza la complessità di molti servizi in esecuzione. - Controllare i log: Dopo aver tentato di avviare un target o un servizio, controlla sempre i log di
journalctlper errori:journalctl -b -u <nome_target_o_servizio>
Migliori Pratiche e Suggerimenti
- Usa
network-online.targetcon attenzione: Se il tuo servizio ha bisogno della configurazione di rete prima dell'avvio, combinaAfter=network-online.targetconWants=network-online.targete conferma che l'appropriata unità wait-online sia abilitata. Mantieni comunque la logica di ripetizione nell'applicazione per le dipendenze remote. - Comprendi l'ordine di avvio: Familiarizza con il flusso generale da
sysinit.targetabasic.target, poimulti-user.target/graphical.target. Questo aiuta nel debug dei servizi che falliscono all'inizio del processo di avvio. - Sii cauto con
default.target: Cambiaredefault.targetpuò alterare significativamente il comportamento di avvio del sistema. Testa sempre le configurazioni personalizzate in un ambiente non di produzione prima. - Usa
Wants=per dipendenze non critiche: Per servizi che sono utili ma non strettamente necessari affinché un target sia considerato "su", usaWants=invece diRequires=. Questo impedisce che un singolo guasto di un servizio opzionale si propaghi e impedisca l'attivazione dell'intero target.
Il Modello Mentale da Tenere
Un target è uno stato nominato, non un demone. default.target decide la destinazione normale di avvio. multi-user.target è lo stato usuale del server. graphical.target aggiunge lo stack di visualizzazione. rescue.target e emergency.target sono strumenti di riparazione. I target personalizzati sono strumenti di raggruppamento quando rendono le operazioni più chiare.
Quando qualcosa relativo a un target si rompe, evita di incolpare prima il target. Chiedi quale unità è stata richiamata, quale regola di ordinamento l'ha ritardata e quale dipendenza è fallita. systemctl cat, systemctl list-dependencies, systemctl show e journalctl -b di solito risponderanno a queste domande più velocemente che leggere diagrammi di avvio generici.