Gestire le risorse con cgroups in systemd
I Cgroup gestiscono le risorse per applicazione anziché per i singoli processi che compongono un'applicazione.
Per me, come amministratore di sistema, non c'è niente di più frustrante dell'esaurire inaspettatamente una risorsa informatica. In più di un'occasione, ho riempito tutto lo spazio disponibile su disco in una partizione, ho esaurito la RAM e non ho avuto abbastanza tempo della CPU per eseguire le mie attività in un periodo di tempo ragionevole. La gestione delle risorse è uno dei compiti più importanti svolti dagli amministratori di sistema.
Lo scopo della gestione delle risorse è garantire che tutti i processi abbiano un accesso relativamente uguale alle risorse di sistema di cui hanno bisogno. La gestione delle risorse implica anche garantire che la RAM, lo spazio sul disco rigido e la capacità della CPU vengano aggiunti quando necessario o razionati quando ciò non è possibile. Inoltre, agli utenti che monopolizzano le risorse di sistema, intenzionalmente o accidentalmente, dovrebbe essere impedito di farlo.
Esistono strumenti che consentono agli amministratori di sistema di monitorare e gestire varie risorse di sistema. Ad esempio, gli strumenti principali e simili consentono di monitorare l'utilizzo di memoria, I/O, spazio di archiviazione (disco, SSD, ecc.), rete, spazio di scambio, utilizzo della CPU e altro ancora. Questi strumenti, in particolare quelli incentrati sulla CPU, si basano principalmente sul paradigma secondo cui il processo in esecuzione è l'unità di controllo. Nella migliore delle ipotesi, forniscono un modo per modificare il numero corretto e, attraverso questo, la priorità, o per interrompere un processo in esecuzione. (Per informazioni sui numeri interessanti, vedere Monitoraggio degli host Linux e Windows con Glances.)
Altri strumenti basati sulla gestione tradizionale delle risorse in un ambiente SystemV sono gestiti dal file /etc/security/limits.conf
e dai file di configurazione locale situati in /etc/security/limits.d directory . Le risorse possono essere limitate in modo abbastanza grezzo ma utile dall'utente o dal gruppo. Le risorse che possono essere gestite includono vari aspetti della RAM, tempo totale della CPU al giorno, quantità totale di dati, priorità, numero valido, numero di accessi simultanei, numero di processi, dimensione massima del file e altro ancora.
Utilizzo di cgroups per la gestione dei processi
Una delle principali differenze tra systemd e SystemV è il modo in cui gestiscono i processi. SystemV tratta ogni processo come un'entità a sé stante. systemd raccoglie i processi correlati in gruppi di controllo, chiamati cgroups (abbreviazione di control groups), e gestisce le risorse di sistema per il cgroup nel suo insieme. Ciò significa che le risorse possono essere gestite per applicazione anziché dai singoli processi che compongono un'applicazione.
Le unità di controllo per i cgroup sono chiamate unità slice. Le sezioni sono una concettualizzazione che consente a systemd di ordinare i processi in un formato ad albero per una facile gestione.
Visualizzazione dei cgroup
Inizierò con alcuni comandi che permettono di visualizzare vari tipi di informazioni sui cgroup. Il comando systemctl status
visualizza le informazioni sulla sezione su un servizio specificato, inclusa la relativa sezione. Questo esempio mostra il demone at
:
[root@testvm1 ~]# systemctl status atd.service
● atd.service - Deferred execution scheduler
Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-09-23 12:18:24 EDT; 1 day 3h ago
Docs: man:atd(8)
Main PID: 1010 (atd)
Tasks: 1 (limit: 14760)
Memory: 440.0K
CPU: 5ms
CGroup: /system.slice/atd.service
└─1010 /usr/sbin/atd -f
Sep 23 12:18:24 testvm1.both.org systemd[1]: Started Deferred execution scheduler.
[root@testvm1 ~]#
Questo è un eccellente esempio del motivo per cui trovo systemd più utilizzabile di SystemV e del vecchio programma init. Ci sono molte più informazioni qui di quelle che SystemV potrebbe fornire. La voce cgroup include la struttura gerarchica in cui system.slice
è systemd (PID 1) e atd.service
è un livello inferiore e parte del system .slice
. La seconda riga della voce cgroup mostra anche l'ID del processo (PID) e il comando utilizzato per avviare il demone.
Il comando systemctl
mostra più voci cgroup. L'opzione --all
mostra tutte le porzioni, comprese quelle che non sono attualmente attive:
[root@testvm1 ~]# systemctl -t slice --all
UNIT LOAD ACTIVE SUB DESCRIPTION
-.slice loaded active active Root Slice
system-getty.slice loaded active active system-getty.slice
system-lvm2\x2dpvscan.slice loaded active active system-lvm2\x2dpvscan.slice
system-modprobe.slice loaded active active system-modprobe.slice
system-sshd\x2dkeygen.slice loaded active active system-sshd\x2dkeygen.slice
system-systemd\x2dcoredump.slice loaded inactive dead system-systemd\x2dcoredump.slice
system-systemd\x2dfsck.slice loaded active active system-systemd\x2dfsck.slice
system.slice loaded active active System Slice
user-0.slice loaded active active User Slice of UID 0
user-1000.slice loaded active active User Slice of UID 1000
user.slice loaded active active User and Session Slice
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
11 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.
[root@testvm1 ~]#
La prima cosa da notare su questi dati è che mostrano le sezioni utente per gli UID 0 (root) e 1000, che è il mio login utente. Vengono mostrate solo le sezioni e non i servizi che fanno parte di ciascuna sezione. Questi dati mostrano che viene creata una sezione per ciascun utente nel momento in cui effettua l'accesso. Ciò può fornire un modo per gestire tutte le attività di un utente come una singola entità cgroup.
Esplora la gerarchia di cgroup
Finora tutto va bene, ma i cgroup sono gerarchici e tutte le unità di servizio funzionano come membri di uno dei cgroup. Visualizzare quella gerarchia è semplice e utilizza un vecchio comando e uno nuovo che fa parte di systemd.
Il comando ps
può essere utilizzato per mappare i processi e le loro posizioni nella gerarchia del cgroup. Tieni presente che è necessario specificare le colonne di dati desiderate quando si utilizza il comando ps
. Ho ridotto in modo significativo il volume di output di questo comando di seguito, ma ho provato a lasciarne abbastanza in modo che tu possa avere un'idea di cosa potresti trovare sui tuoi sistemi:
[root@testvm1 ~]# ps xawf -eo pid,user,cgroup,args
PID USER CGROUP COMMAND
2 root - [kthreadd]
3 root - \_ [rcu_gp]
4 root - \_ [rcu_par_gp]
6 root - \_ [kworker/0:0H-kblockd]
9 root - \_ [mm_percpu_wq]
10 root - \_ [ksoftirqd/0]
11 root - \_ [rcu_sched]
12 root - \_ [migration/0]
13 root - \_ [cpuhp/0]
14 root - \_ [cpuhp/1]
<SNIP>
625406 root - \_ [kworker/3:0-ata_sff]
625409 root - \_ [kworker/u8:0-events_unbound]
1 root 0::/init.scope /usr/lib/systemd/systemd --switched-root --system --deserialize 30
588 root 0::/system.slice/systemd-jo /usr/lib/systemd/systemd-journald
599 root 0::/system.slice/systemd-ud /usr/lib/systemd/systemd-udevd
741 root 0::/system.slice/auditd.ser /sbin/auditd
743 root 0::/system.slice/auditd.ser \_ /usr/sbin/sedispatch
764 root 0::/system.slice/ModemManag /usr/sbin/ModemManager
765 root 0::/system.slice/NetworkMan /usr/sbin/NetworkManager --no-daemon
767 root 0::/system.slice/irqbalance /usr/sbin/irqbalance --foreground
779 root 0::/system.slice/mcelog.ser /usr/sbin/mcelog --ignorenodev --daemon --foreground
781 root 0::/system.slice/rngd.servi /sbin/rngd -f
782 root 0::/system.slice/rsyslog.se /usr/sbin/rsyslogd -n
<SNIP>
893 root 0::/system.slice/sshd.servi sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
1130 root 0::/user.slice/user-0.slice \_ sshd: root [priv]
1147 root 0::/user.slice/user-0.slice | \_ sshd: root@pts/0
1148 root 0::/user.slice/user-0.slice | \_ -bash
1321 root 0::/user.slice/user-0.slice | \_ screen
1322 root 0::/user.slice/user-0.slice | \_ SCREEN
1323 root 0::/user.slice/user-0.slice | \_ /bin/bash
498801 root 0::/user.slice/user-0.slice | | \_ man systemd.resource-control
498813 root 0::/user.slice/user-0.slice | | \_ less
1351 root 0::/user.slice/user-0.slice | \_ /bin/bash
123293 root 0::/user.slice/user-0.slice | | \_ man systemd.slice
123305 root 0::/user.slice/user-0.slice | | \_ less
1380 root 0::/user.slice/user-0.slice | \_ /bin/bash
625412 root 0::/user.slice/user-0.slice | | \_ ps xawf -eo pid,user,cgroup,args
625413 root 0::/user.slice/user-0.slice | | \_ less
246795 root 0::/user.slice/user-0.slice | \_ /bin/bash
625338 root 0::/user.slice/user-0.slice | \_ /usr/bin/mc -P /var/tmp/mc-root/mc.pwd.246795
625340 root 0::/user.slice/user-0.slice | \_ bash -rcfile .bashrc
1218 root 0::/user.slice/user-1000.sl \_ sshd: dboth [priv]
1233 dboth 0::/user.slice/user-1000.sl \_ sshd: dboth@pts/1
1235 dboth 0::/user.slice/user-1000.sl \_ -bash
<SNIP>
1010 root 0::/system.slice/atd.servic /usr/sbin/atd -f
1011 root 0::/system.slice/crond.serv /usr/sbin/crond -n
1098 root 0::/system.slice/lxdm.servi /usr/sbin/lxdm-binary
1106 root 0::/system.slice/lxdm.servi \_ /usr/libexec/Xorg -background none :0 vt01 -nolisten tcp -novtswitch -auth /var/run/lxdm/lxdm-:0.auth
370621 root 0::/user.slice/user-1000.sl \_ /usr/libexec/lxdm-session
370631 dboth 0::/user.slice/user-1000.sl \_ xfce4-session
370841 dboth 0::/user.slice/user-1000.sl \_ /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
370911 dboth 0::/user.slice/user-1000.sl \_ xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
370930 dboth 0::/user.slice/user-1000.sl \_ xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
370942 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libsystray.so 6 23068680 systr
ay Notification Area Area where notification icons appear
370943 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libpulseaudio-plugin.so 8 2306
8681 pulseaudio PulseAudio Plugin Adjust the audio volume of the PulseAudio sound system
370944 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libxfce4powermanager.so 9 2306
8682 power-manager-plugin Power Manager Plugin Display the battery levels of your devices and control the brightness of your display
370945 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libnotification-plugin.so 10 2
3068683 notification-plugin Notification Plugin Notification plugin for the Xfce panel
370948 dboth 0::/user.slice/user-1000.sl | \_ /usr/lib64/xfce4/panel/wrapper-2.0 /usr/lib64/xfce4/panel/plugins/libactions.so 14 23068684 acti
ons Action Buttons Log out, lock or other system actions
370934 dboth 0::/user.slice/user-1000.sl \_ Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
370939 dboth 0::/user.slice/user-1000.sl \_ xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
370962 dboth 0::/user.slice/user-1000.sl \_ nm-applet
<SNIP>
Puoi visualizzare l'intera gerarchia con il comando systemd-cgls
, che è un po' più semplice perché non richiede opzioni complesse.
Ho accorciato considerevolmente questa visualizzazione ad albero. ma ne ho lasciato abbastanza per darti un'idea della quantità di dati e dei tipi di voci che dovresti vedere quando esegui questa operazione sul tuo sistema. L'ho fatto su una delle mie macchine virtuali ed è lunga circa 200 righe; la quantità di dati dalla mia postazione di lavoro principale è di circa 250 righe:
[root@testvm1 ~]# systemd-cgls
Control group /:
-.slice
├─user.slice
│ ├─user-0.slice
│ │ ├─session-1.scope
│ │ │ ├─ 1130 sshd: root [priv]
│ │ │ ├─ 1147 sshd: root@pts/0
│ │ │ ├─ 1148 -bash
│ │ │ ├─ 1321 screen
│ │ │ ├─ 1322 SCREEN
│ │ │ ├─ 1323 /bin/bash
│ │ │ ├─ 1351 /bin/bash
│ │ │ ├─ 1380 /bin/bash
│ │ │ ├─123293 man systemd.slice
│ │ │ ├─123305 less
│ │ │ ├─246795 /bin/bash
│ │ │ ├─371371 man systemd-cgls
│ │ │ ├─371383 less
│ │ │ ├─371469 systemd-cgls
│ │ │ └─371470 less
│ │ └─user@0.service …
│ │ ├─dbus-broker.service
│ │ │ ├─1170 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1171 dbus-broker --log 4 --controller 12 --machine-id 3bccd1140fca488187f8a1439c832f07 --max-bytes 100000000000000 --max-fds 25000000000000 --max->
│ │ ├─gvfs-daemon.service
│ │ │ └─1173 /usr/libexec/gvfsd
│ │ └─init.scope
│ │ ├─1137 /usr/lib/systemd/systemd --user
│ │ └─1138 (sd-pam)
│ └─user-1000.slice
│ ├─user@1000.service …
│ │ ├─dbus\x2d:1.2\x2dorg.xfce.Xfconf.slice
│ │ │ └─dbus-:1.2-org.xfce.Xfconf@0.service
│ │ │ └─370748 /usr/lib64/xfce4/xfconf/xfconfd
│ │ ├─dbus\x2d:1.2\x2dca.desrt.dconf.slice
│ │ │ └─dbus-:1.2-ca.desrt.dconf@0.service
│ │ │ └─371262 /usr/libexec/dconf-service
│ │ ├─dbus-broker.service
│ │ │ ├─1260 /usr/bin/dbus-broker-launch --scope user
│ │ │ └─1261 dbus-broker --log 4 --controller 11 --machine-id
<SNIP>
│ │ └─gvfs-mtp-volume-monitor.service
│ │ └─370987 /usr/libexec/gvfs-mtp-volume-monitor
│ ├─session-3.scope
│ │ ├─1218 sshd: dboth [priv]
│ │ ├─1233 sshd: dboth@pts/1
│ │ └─1235 -bash
│ └─session-7.scope
│ ├─370621 /usr/libexec/lxdm-session
│ ├─370631 xfce4-session
│ ├─370805 /usr/bin/VBoxClient --clipboard
│ ├─370806 /usr/bin/VBoxClient --clipboard
│ ├─370817 /usr/bin/VBoxClient --seamless
│ ├─370818 /usr/bin/VBoxClient --seamless
│ ├─370824 /usr/bin/VBoxClient --draganddrop
│ ├─370825 /usr/bin/VBoxClient --draganddrop
│ ├─370841 /usr/bin/ssh-agent /bin/sh -c exec -l bash -c "/usr/bin/startxfce4"
│ ├─370910 /bin/gpg-agent --sh --daemon --write-env-file /home/dboth/.cache/gpg-agent-info
│ ├─370911 xfwm4 --display :0.0 --sm-client-id 2dead44ab-0b4d-4101-bca4-e6771f4a8ac2
│ ├─370923 xfsettingsd --display :0.0 --sm-client-id 261b4a437-3029-461c-9551-68c2c42f4fef
│ ├─370930 xfce4-panel --display :0.0 --sm-client-id 2ce38b8ef-86fd-4189-ace5-deec1d0e0952
│ ├─370934 Thunar --sm-client-id 2cfc809d8-4e1d-497a-a5c5-6e4fa509c3fb --daemon
│ ├─370939 xfdesktop --display :0.0 --sm-client-id 299be0608-4dca-4055-b4d6-55ec6e73a324
<SNIP>
└─system.slice
├─rngd.service
│ └─1650 /sbin/rngd -f
├─irqbalance.service
│ └─1631 /usr/sbin/irqbalance --foreground
├─fprintd.service
│ └─303383 /usr/libexec/fprintd
├─systemd-udevd.service
│ └─956 /usr/lib/systemd/systemd-udevd
<SNIP>
├─systemd-journald.service
│ └─588 /usr/lib/systemd/systemd-journald
├─atd.service
│ └─1010 /usr/sbin/atd -f
├─system-dbus\x2d:1.10\x2dorg.freedesktop.problems.slice
│ └─dbus-:1.10-org.freedesktop.problems@0.service
│ └─371197 /usr/sbin/abrt-dbus -t133
├─sshd.service
│ └─893 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─vboxservice.service
│ └─802 /usr/sbin/VBoxService -f
├─crond.service
│ └─1011 /usr/sbin/crond -n
├─NetworkManager.service
│ └─765 /usr/sbin/NetworkManager --no-daemon
├─switcheroo-control.service
│ └─787 /usr/libexec/switcheroo-control
<SNIP>
Questa visualizzazione ad albero mostra tutte le sezioni utente e sistema, nonché i servizi e i programmi in esecuzione in ciascun cgroup. Notare le unità chiamate "ambiti", che raggruppano programmi correlati in un'unità di gestione, all'interno di user-1000.slice
nell'elenco sopra. Il cgroup user-1000.slice/session-7.scope
contiene la gerarchia del programma desktop della GUI, a partire dalla sessione del display manager LXDM e tutte le sue attività secondarie, incluse cose come la shell Bash e la GUI Thunar gestore di file.
Le unità di ambito non sono definite nei file di configurazione ma vengono generate a livello di codice come risultato dell'avvio di gruppi di programmi correlati. Le unità ambito non creano né avviano i processi in esecuzione come parte di quel cgroup. Tutti i processi nell'ambito sono uguali e non esiste una gerarchia interna. La vita di un ambito inizia quando viene creato il primo processo e termina quando l'ultimo processo viene distrutto.
Apri diverse finestre sul desktop, come emulatori di terminale, LibreOffice o qualunque cosa tu voglia, quindi passa a una console virtuale disponibile e avvia qualcosa come top
o Midnight Commander. Esegui il comando systemd-cgls
sul tuo host e prendi nota della gerarchia generale e delle unità di ambito.
Il comando systemd-cgls
fornisce una rappresentazione più completa della gerarchia del cgroup (e dei dettagli delle unità che lo compongono) rispetto a qualsiasi altro comando che ho trovato. Preferisco la sua rappresentazione più pulita dell'albero rispetto a quella fornita dal comando ps
.
Con un piccolo aiuto dai miei amici
Dopo aver trattato queste nozioni di base, avevo programmato di entrare più in dettaglio sui cgroup e su come usarli, ma ho scoperto una serie di quattro eccellenti articoli di Steve Ovens di Red Hat sul sito gemello di Opensource.com, Enable Sysadmin. Piuttosto che riscrivere sostanzialmente gli articoli di Steve, ho deciso che sarebbe stato molto meglio sfruttare la sua esperienza su cgroup collegandoli ad essi:
- Un'introduzione ai cgroup da parte di un amministratore di sistema Linux
- Come gestire i cgroup con CPUShares
- Gestire i cgroup nel modo più difficile: manualmente
- Gestire i cgroup con systemd
Divertitevi e imparate da loro, come ho fatto io.
Altre risorse
Ci sono molte informazioni su systemd disponibili su Internet, ma molte sono concise, ottuse o addirittura fuorvianti. Oltre alle risorse menzionate in questo articolo, le seguenti pagine Web offrono informazioni più dettagliate e affidabili sull'avvio di systemd. Questo elenco è cresciuto da quando ho iniziato questa serie di articoli per riflettere la ricerca che ho svolto.
- Il progetto Fedora ha una buona guida pratica a systemd. Ha praticamente tutto ciò che devi sapere per configurare, gestire e mantenere un computer Fedora utilizzando systemd.
- Il progetto Fedora ha anche un buon cheat sheet che fa riferimenti incrociati ai vecchi comandi SystemV con quelli systemd comparabili.
- La pagina man systemd.unit(5) contiene un bell'elenco delle sezioni del file unit e delle relative opzioni di configurazione insieme a descrizioni concise di ciascuna.
- La documentazione di Red Hat contiene una buona descrizione della struttura dei file Unit oltre ad altre informazioni importanti.
- Per informazioni tecniche dettagliate su systemd e le ragioni per crearlo, consulta la descrizione di systemd di Freedesktop.org. Questa pagina è una delle migliori che ho trovato perché contiene molti collegamenti ad altra documentazione importante e accurata.
- La sezione "More systemd fun" di Linux.com offre informazioni e suggerimenti più avanzati su systemd.
- Vedere la pagina man per systemd.resource-control(5).
- Nella Guida per l'utente e l'amministratore del kernel Linux, vedere la voce Control Group v2.
C'è anche una serie di articoli profondamente tecnici per amministratori di sistema Linux scritti da Lennart Poettering, il progettista e sviluppatore principale di systemd. Questi articoli sono stati scritti tra aprile 2010 e settembre 2011, ma sono attuali tanto quanto lo erano allora. Gran parte di tutto ciò che di buono è stato scritto su systemd e sul suo ecosistema si basa su questi documenti.
- Ripensare il PID 1
- systemd per amministratori, parte I
- systemd per amministratori, parte II
- systemd per amministratori, parte III
- systemd per amministratori, parte IV
- systemd per amministratori, parte V
- systemd per amministratori, parte VI
- systemd per amministratori, parte VII
- systemd per amministratori, parte VIII
- systemd per amministratori, parte IX
- systemd per amministratori, parte X
- systemd per amministratori, parte XI