Come creare un utente con un utilizzo limitato della RAM?


45

Quindi ho 4 GB di RAM + 4 GB di scambio. Voglio creare un utente con ram e swap limitati: 3 GB di RAM e 1 GB di swap. Tale cosa è possibile? È possibile avviare applicazioni con RAM limitata e scambiarle a loro disposizione senza creare un utente separato (e non installare app speciali - avendo solo una configurazione server Debian / CentOS predefinita e non usando sudo)?

Aggiornare:

Così ho aperto Terminall e l'ho digitato ulimit command: ulimit -v 1000000che sarà come una 976,6Mblimitazione. Successivamente ho chiamato ulimit -ae ho visto che la limitazione è "attiva". Poi ho iniziato alcuni script bash che compila e avvia la mia app nohup, una lunga nohup ./cloud-updater-linux.sh >& /dev/null & ... ma dopo qualche tempo ho visto:

inserisci qui la descrizione dell'immagine

(il che sarebbe ok se non fossero applicate limitazioni - ha scaricato un po 'di lib di grandi dimensioni e ha iniziato a compilarlo.)

Ma ho pensato di applicare limitazioni alla shell e a tutti i processi avviati con / da essa con ulimit -v 1000000? Cosa ho sbagliato? Come creare un terminale e tutti i processi secondari che viene avviato possono essere limitati all'uso della RAM?


1
Non è possibile applicare restrizioni di memoria su un utente nel suo complesso, solo su ciascun processo. E non puoi distinguere tra RAM e utilizzo dello swap. Se si desidera un controllo più preciso, eseguire i processi dell'utente in una macchina virtuale.
Gilles 'SO-smetti di essere malvagio' il

@Gilles è abbastanza sicuro che le macchine virtuali utilizzino solo cgroups e namespace o derivati ​​di
RapidWebs

@RapidWebs no non lo fanno. Emulano semplicemente la quantità predefinita di RAM e il sistema operativo guest decide quindi come allocarlo ai processi.
Ruslan,

I contenitori (non le macchine virtuali) utilizzano i cgroup per limitare l'utilizzo della memoria. Limitare la memoria virtuale non è una buona idea; Un processo può usare molta memoria virtuale, ma può usare solo un po 'di RAM. Ad esempio il mio sistema ha 34359738367 kB di memoria virtuale allocata, ma molto meno ram.
ctrl-alt-delor,

Risposte:


65

ulimitè fatto per questo. È possibile impostare le impostazioni predefinite per ulimitun utente o una base per gruppo in

/etc/security/limits.conf

ulimit -v KBYTESimposta la dimensione massima della memoria virtuale. Non credo che tu possa dare una quantità massima di swap. È solo un limite alla quantità di memoria virtuale che l'utente può utilizzare.

Quindi limits.confavresti la linea (al massimo 4Gdella memoria)

luser  hard  as   4000000

AGGIORNAMENTO - CGroups

I limiti imposti da ulimited limits.confè per processo. Sicuramente non ero chiaro su questo punto.

Se si desidera limitare la quantità totale di memoria utilizzata da un utente (che è ciò che è stato richiesto). Vuoi usare i cgroups .

In /etc/cgconfig.conf:

group memlimit {
    memory {
        memory.limit_in_bytes = 4294967296;
    }
}

Questo crea un cgroupche ha un limite massimo di memoria di 4GiB.

In /etc/cgrules.conf:

luser   memory   memlimit/

Questo farà sì che tutti i processi eseguiti luservengano eseguiti all'interno dei memlimitcgroup creati in cgconfig.conf.


è possibile impostare una cosa del genere useradd?
myWallJSON

4
@myWallJSON Non direttamente, ma è possibile aggiungerlo immediatamente a limits.conf oppure è possibile impostare un gruppo con determinati limiti in limits.conf e aggiungere l'utente a quel gruppo.
utopiabound

1
È fantastico! Non sapevo che potresti farlo! Ottima risposta +1
Yanick Girouard

1
@utopiabound: ho aggiornato la mia Q con alcuni dati che ho provato a usare ulimit.
myWallJSON

1
@ f.ardelian Aggiorna il kernel. Ecco un articolo su come fare proprio questo!
Daniel C. Sobral,

4

Non è possibile limitare l'utilizzo della memoria a livello di utente, ulimit può farlo ma per un singolo processo.

Anche con l'utilizzo dei limiti per utente /etc/security/limits.conf, un utente può utilizzare tutta la memoria eseguendo più processi.

Se vuoi davvero limitare le risorse, devi utilizzare uno strumento di gestione delle risorse, come rcapd utilizzato da progetti e zone in Solaris.

C'è qualcosa che sembra fornire funzionalità simili su Linux su cui potresti indagare: i cgroups .


Bene, suppongo che l'impostazione di un limite sulla shell di accesso degli utenti o qualcosa del genere possa essere interpretata come "impostazione di un limite per l'utente", poiché tutti i processi erediteranno da quella shell?
AMN

1
@amn Non lo farà. Un utente potrebbe semplicemente aprire una nuova shell di accesso per ovviare a tale limite.
jlliagre,

Bene, questo invalida la mia ipotesi, va bene.
AMN

4

cgroupssono il modo giusto per farlo, come hanno sottolineato altre risposte. Sfortunatamente non esiste una soluzione perfetta al problema, come vedremo di seguito. Esistono diversi modi per impostare i limiti di utilizzo della memoria del cgroup. Il modo in cui si fa in modo che una sessione di accesso di un utente diventi automaticamente parte di un cgroup varia da sistema a sistema. Red Hat ha alcuni strumenti, così come systemd .

memory.memsw.limit_in_bytese memory.limit_in_bytesimpostare limiti includendo e non includendo swap, rispettivamente. Il rovescio della medaglia memory.limit_in_bytesè che conta i file memorizzati nella cache dal kernel per conto dei processi nel cgroup rispetto alla quota del gruppo. Meno cache significa più accesso al disco, quindi potresti rinunciare ad alcune prestazioni se il sistema disponesse altrimenti di memoria.

D'altra parte, memory.soft_limit_in_bytesconsente al cgroup di superare le quote, ma se il killer OOM del kernel viene invocato, quei cgroup che superano le loro quote vengono uccisi per primi, logicamente. Il rovescio della medaglia di ciò, tuttavia, è che ci sono situazioni in cui è immediatamente necessario un po 'di memoria e non c'è tempo per il killer OOM di cercare i processi da uccidere, nel qual caso qualcosa potrebbe fallire prima che i processi dell'utente in eccesso siano ucciso.

ulimit, tuttavia, è assolutamente lo strumento sbagliato per questo. ulimit pone dei limiti sull'utilizzo della memoria virtuale, che quasi sicuramente non è quello che desideri. Molte applicazioni del mondo reale usano molta più memoria virtuale rispetto alla memoria fisica. La maggior parte dei runtime raccolti dall'immondizia (Java, Go) funzionano in questo modo per evitare la frammentazione. Un banale programma "ciao mondo" in C, se compilato con disinfettante per indirizzi, può usare 20 TB di memoria virtuale. Allocatori su cui non si basano sbrk, come jemalloc (che è l'allocatore predefinito per Rust) o tcmalloc, avrà anche un utilizzo della memoria virtuale sostanzialmente superiore al loro utilizzo fisico. Per motivi di efficienza, molti strumenti eseguiranno il mmap dei file, aumentando l'utilizzo virtuale ma non necessariamente quello fisico. Tutti i miei processi Chrome utilizzano 2 TB di memoria virtuale ciascuno. Sono su un laptop con 8 GB di memoria fisica. Qualsiasi modo in cui si tentasse di impostare quote di memoria virtuale qui sarebbe di rompere Chrome, forzare Chrome a disabilitare alcune funzionalità di sicurezza che si basano sull'allocazione (ma non sull'uso) di grandi quantità di memoria virtuale o essere completamente inefficaci per impedire a un utente di abusare del sistema .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.