Limita l'utilizzo di CPU e memoria di un comando con Ubuntu cgroups

Se un comando rallenta il desktop di Ubuntu o causa un esaurimento della memoria su un server, inserisci il comando e i relativi processi figli in un cgroup gestito da systemd con una quota di CPU e un limite di memoria. Nelle versioni attuali di Ubuntu, systemd-run --scopequesta è la soluzione più rapida: il comando viene avviato in un ambito temporaneo e systemd applica i limiti tramite i controlli del cgroup.

L'esempio seguente limita il carico di lavoro a metà della capacità di una CPU e a 1 GiB di memoria. Questi limiti si applicano all'intero ambito, inclusi i processi figli; non garantiscono che il programma verrà eseguito a una velocità specifica.

Perché un processo necessita di un limite cgroup

Un processo che consuma molta memoria può entrare in conflitto con le applicazioni interattive, mentre un processo che richiede molta memoria può portare il sistema a un'interruzione della memoria o a un esaurimento della memoria stessa. Un cgroup raggruppa un processo con i suoi discendenti, consentendo al kernel di gestirlo e limitarne l'utilizzo. Il sistema systemd di Ubuntu fornisce un'interfaccia intuitiva per questi controlli.

Le impostazioni di CPU e memoria si comportano in modo diverso. CPUQuota=50%Limita il tempo della CPU alla metà della capacità di una CPU, calcolata come media su un periodo di pianificazione. Un valore di 200%rappresenta il tempo di due CPU, quando disponibili. Si tratta di un limite massimo, non di una priorità della CPU o di una prenotazione. MemoryMax=1GImposta un limite massimo rigido per la memoria allocata al cgroup; se il carico di lavoro non può rimanere al di sotto di tale limite, il kernel può recuperare memoria o avviare un'interruzione per esaurimento della memoria per un processo in quel cgroup. Scegliere un limite con un margine sufficiente per l'applicazione e i suoi processi figli.

1. Verifica che Ubuntu utilizzi cgroup v2

I sistemi Ubuntu che utilizzano systemd impiegano comunemente la gerarchia unificata cgroup v2. Prima di fare affidamento sui percorsi mostrati in seguito, verificare la configurazione attiva:

stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1

Il primo comando dovrebbe riportare cgroup2fs. Se riporta un altro tipo di filesystem, i percorsi dei file cgroup v2 di questo articolo non sono validi così come sono scritti. Le proprietà di systemd potrebbero comunque essere supportate con una gerarchia diversa, ma in tal caso utilizzare la documentazione della distribuzione corrispondente anziché copiare i percorsi v2.

Verifica anche la versione esatta di systemd se una proprietà viene rifiutata. La documentazione di Noble per Ubuntu descrive CPUQuota=e MemoryMax=come impostazioni di controllo delle risorse; le versioni precedenti di Ubuntu potrebbero includere versioni diverse di systemd.

2. Avviare il carico di lavoro all'interno di un ambito limitato

Esegui il programma tramite systemd-run, sostituendo il suo eseguibile e gli argomenti reali. Per un comando nella directory corrente, usa ./e passa tutti gli argomenti dopo --:

systemd-run --scope \
  -p CPUQuota=50% \
  -p MemoryMax=1G \
  -- ./my-program --input data.csv
Terminale Ubuntu con systemd-run in esecuzione con CPUQuota impostato al 50% e MemoryMax impostato a 1G per un comando
Avvia un comando all'interno di un ambito systemd temporaneo con limiti di CPU e memoria.

Per un comando di proprietà dell'utente, prova sudoprima senza. Se systemd segnala che un controller o una proprietà richiesti non sono disponibili, il gestore utenti potrebbe non avere l'autorizzazione per delegarli; riprovare come root potrebbe essere appropriato per un carico di lavoro a livello di sistema, ma modifica il contesto di sicurezza del comando. Non eseguire casualmente un programma non attendibile come root. Se è necessario utilizzare il gestore di sistema come root, utilizzarlo sudo systemd-run --scope ...solo dopo aver tenuto conto di tale modifica.

Il terminale rimane collegato all'ambito mentre il comando è in esecuzione. Premendo Ctrl+Csi interrompe l'operazione in primo piano. L'ambito è temporaneo e normalmente scompare al termine dei processi. È un modo pratico per avviare un comando entro dei limiti, piuttosto che adottare una politica persistente per gli avvii futuri.

3. Individuare l'ambito di applicazione e verificarne i limiti.

systemd-runstampa il nome dell'unità che crea, in genere qualcosa del tipo run-….scope. Mentre il comando è ancora in esecuzione, elenca l'albero cgroup:

systemd-cgls

Individua l'ambito transitorio e verifica che il programma di destinazione e i suoi figli appaiano al di sotto di esso. Questo è importante perché un figlio che viene eseguito al di fuori dell'ambito non sarà coperto dallo stesso limite del cgroup.

Albero cgroup terminale che mostra un ambito di esecuzione transitorio contenente un programma e due processi worker.
Utilizzare l'albero cgroup per confermare che il programma e i suoi worker siano raggruppati nell'ambito transient.

Utilizzare il nome dell'ambito stampato nel comando successivo. Sostituire run-abc.scopecon il nome effettivo:

systemctl show run-abc.scope \
  -p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax

CPUQuotaPerSecUSec=50000è coerente con una quota del 50% quando il periodo di quota di systemd è di 100 ms; MemoryMax=1073741824corrisponde a 1 GiB in byte. I valori in tempo reale sono più utili rispetto al presupposto che ogni host accetti ogni richiesta senza modifiche, poiché i cgroup padre e i controller disponibili possono limitare il risultato effettivo.

Il comando systemctl show restituisce l'output con i valori di ControlGroup, quota CPU e valori massimi di memoria per un ambito transitorio.
Verificare il gruppo di controllo segnalato dall'oscilloscopio e i limiti configurati per CPU e memoria.

4. Verificare i file cgroup del kernel e regolarli in modo sicuro

La ControlGroupproprietà specifica il percorso cgroup relativo a /sys/fs/cgroup. Memorizzalo in una variabile di shell in modo che i comandi seguano il percorso effettivamente assegnato sulla tua macchina:

UNIT=run-abc.scope
CG=$(systemctl show "$UNIT" -p ControlGroup --value)
printf 'Group: %s\n' "$CG"
cat "/sys/fs/cgroup$CG/cpu.max"
cat "/sys/fs/cgroup$CG/memory.max"

Su cgroup v2, cpu.maxcontiene una quota e un periodo in microsecondi. Ad esempio, 50000 100000significa 50 ms di tempo CPU in ogni periodo di 100 ms. memory.maxmostra il limite di memoria in byte. Se i file non sono presenti, verificare che l'ambito sia ancora attivo e che il kernel stia utilizzando cgroup v2.

Lettura da terminale di cpu.max e memory.max dall'ambito systemd sotto sysfs cgroup v2
Leggere i file cgroup v2 del kernel per verificare la quota e il limite di memoria configurati.

Se hai avviato un'unità a lunga esecuzione denominata e devi regolarne i limiti, systemd supporta la modifica delle proprietà delle risorse su un'unità attiva, ad esempio sudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1G. Questo si applica al cgroup di quel servizio e richiede i privilegi appropriati. Non collega un processo già in esecuzione arbitrario solo perché il suo PID è noto; per un processo singolo, arrestalo correttamente e riavvialo tramite l'ambito limitato. Per un servizio persistente, configura le proprietà nell'unità di servizio o in un drop-in di systemd e riavvialo durante un'apposita finestra di manutenzione.

Controlla il risultato

Mantieni attivo il carico di lavoro durante l'ispezione. Verifica che systemd-cglsil processo e i suoi figli siano posizionati nell'ambito previsto, che systemctl showvengano segnalate le proprietà richieste e che i file corrispondenti cpu.maxesistano memory.maxcon valori finiti. Quando il processo termina, l'ambito transitorio viene rimosso, quindi i relativi file cgroup potrebbero scomparire.

Una quota limita il tempo della CPU ma non garantisce una percentuale fissa in un monitor desktop, e un limite rigido di memoria può causare errori se l'applicazione necessita di più memoria rispetto al limite. Se il carico di lavoro diventa instabile, interromperlo e aumentare il limite a un valore sicuro misurato oppure utilizzare una MemoryHigh=soglia di pressione più flessibile insieme a un valore più alto MemoryMax=. Per il comportamento esatto, consultare la documentazione di systemd e del kernel installati; i riferimenti autorevoli sono il manuale di Ubuntu systemd-run , il manuale di Ubuntu systemd resource-control e la documentazione di Linux kernel cgroup v2 .

Lascia un commento

Come convertire tensione, corrente, kW, kVA e fattore di potenza trifase

Come convertire tensione, corrente, kW, kVA e fattore di potenza trifase

Impara le formule trifase bilanciate e converti passo dopo passo tensione di linea, corrente, kW, kVA e fattore di potenza, con un esempio pratico e limiti da verificare.

Limita l'utilizzo di CPU e memoria di un comando con Ubuntu cgroups

Limita l'utilizzo di CPU e memoria di un comando con Ubuntu cgroups

Esegui un carico di lavoro all'interno di un ambito systemd con CPUQuota e MemoryMax, quindi verifica i limiti tramite cgroup v2.

Crittografare il DNS upstream di Pi-hole su Ubuntu Server 24.04

Crittografare il DNS upstream di Pi-hole su Ubuntu Server 24.04

Configurare dnscrypt-proxy come bridge DoH locale di Pi-hole su Ubuntu 24.04, con un listener solo per localhost, selezione del resolver e controlli prima del cambio di DNS.

Come far funzionare i gesti del touchpad di Ubuntu 24.04 su Wayland

Come far funzionare i gesti del touchpad di Ubuntu 24.04 su Wayland

Prima di risolvere problemi relativi ad app o hardware, verifica le impostazioni del touchpad di Ubuntu, conferma la presenza di Wayland e testa le gesture integrate di GNOME.

Crea un mirror RAID 1 di Debian 12 con mdadm

Crea un mirror RAID 1 di Debian 12 con mdadm

Crea e verifica un array di dati RAID 1 a due dischi per Debian 12, formattalo in modo sicuro e configuralo per l'assemblaggio e il montaggio dopo il riavvio.

Crittografa la partizione di swap di Debian 12 con una nuova chiave ad ogni avvio.

Crittografa la partizione di swap di Debian 12 con una nuova chiave ad ogni avvio.

Configurare la crittografia a chiave casuale per una partizione di swap Debian 12 esistente, verificare la mappatura dm-crypt attiva e comprendere il compromesso relativo all'ibernazione.

Come limitare l'accesso degli utenti SSH a directory specifiche su Ubuntu 24.04 (Guida SFTP Chroot)

Come limitare l'accesso degli utenti SSH a directory specifiche su Ubuntu 24.04 (Guida SFTP Chroot)

Limita gli account SSH di Ubuntu 24.04 a cartelle SFTP designate tramite chroot, autorizzazioni appropriate, regole di corrispondenza e test di sicurezza, senza concedere l'accesso alla shell.

Rilascia in modo sicuro il blocco APT di Ubuntu e completa l'aggiornamento.

Rilascia in modo sicuro il blocco APT di Ubuntu e completa l'aggiornamento.

Individua il processo proprietario del blocco del frontend dpkg di Ubuntu, lascia che l'elaborazione dei pacchetti termini e ripara le installazioni interrotte senza eliminare i file di blocco.

Come configurare gli snapshot Btrfs automatici su Ubuntu Desktop

Come configurare gli snapshot Btrfs automatici su Ubuntu Desktop

Configura gli snapshot di sistema Btrfs programmati su Ubuntu Desktop con Timeshift, verifica la struttura dei sottovolumi di Ubuntu, scegli il periodo di conservazione e comprendi cosa gli snapshot non possono proteggere.

Come migrare Debian 12 a Testing senza rompere le dipendenze

Come migrare Debian 12 a Testing senza rompere le dipendenze

Pianifica una migrazione più sicura da Debian 12 a Testing: esegui l'aggiornamento tramite la versione Stable, effettua un backup, pulisci i sorgenti APT, simula le modifiche alle dipendenze e verifica cosa è cambiato.