Oct 042011
 

Cgroups è presente dal kernel Linux ufficiale 2.6.24 (fine 2007), ma ancora non è molto conosciuto o usato (almeno per quello che so).
In questo articolo vi darò una panoramica di questo potente strumento Linux per controllare la quantità di CPU, memoria, I/O disco o I/O di rete che ogni processo o utente può utilizzare nel vostro server.

Quindi, in breve cgroups è una funzionalità che consente di limitare, registrare ed isolare l’utilizzo delle risorse (CPU, memoria, disco I/O, ecc) di gruppi di processi.
Vediamo come.

Teoria

Un control group è un insieme di processi che sono legati dagli stessi criteri. Questi gruppi possono essere gerarchici, in cui ogni gruppo eredita dei limiti dal proprio gruppo di appartenenza. Il kernel fornisce l’accesso a più controllori (sottosistemi) attraverso l’interfaccia di cgroups.

L’infrastruttura di cgroups fornisce solo le funzionalità di raggruppamento dei processi, mentre i vari sottosistemi di cgroups attuano le politiche di controllo specifico per ogni risorsa. Questo framework è molto potente e permette di impostare le regole di risorse non solo sulla base di utenti e gruppi.

Per esempio si potrebbe:

Prevenire che un server Web utilizzi tutta la memoria su un sistema che ha anche in esecuzione un database.
Allocare le risorse di sistema tra gruppi di utenti con priorità diverse (ad esempio, gli ospiti il 10% della CPU, gli utenti il 40% della CPU, i powerusers il 50% della CPU)

Ma cgroup può essere usato anche per isolare e dare comandi speciali a gruppi di processi, per cui possiamo dire che ci sono 2 tipi di sottosistemi

  1. I sottosistemi per l’isolamento e controlli speciali
  2. I sottosistemi per il controllo delle risorse

Mi concentrerò sul controllo delle risorse quindi questa è una piccola panoramica dei sottosistemi per l’isolamento e controlli speciali:

  • CPUset: assegna singole CPU e nodi di memoria a cgroups.
  • Namespace : fornisce una visione privata del sistema per i processi in in cgroup, ed è usato principalmente per realizzare a livello di sistema operativo la virtualizzazione.
  • Freezer: ferma tutti i processi in esecuzione in un cgroup, rimuovendoli dal task scheduler del kernel .
  • Device: consente o nega l’accesso ai dispositivi ai processi in un cgroup.
  • Checkpoint/Restart: Salva lo stato di tutti i processi in un cgroup in un file di dump. E’ possibile riavviarli in un secondo momento (o solo salvare lo stato e continuare).

L’amministrazione dei cgroup viene effettuata per mezzo di uno special virtual filesystem (una sorta di procfs o sysfs), denominato banalmente cgroupfs.

Cgropus in pratica

A meno che abbiate una versione del server di qualche anno fa (Red Hat e CentOS 5.x per esempio), si dovrebbe avere un kernel in grado di utilizzare cgroup, in generale, controllate se il vostro kernel è >= 2.6.24 di con il comando uname -a questo è il requisito per utilizzare cgroups.

A questo punto vi servono gli strumenti in user-space, io sto facendo i test sulla mia Ubuntu, su questo sistema i file da installare sono cgroup-bin e libcgroup1:

sudo aptitude install cgroup-bin libcgroup1

Una volta installato avrete un nuovo filesystem montato:

# ls /sys/fs/cgroup
cpu  cpuacct  devices  memory

Su altre distribuzioni Linux, potreste avere bisogno di montarlo manualmente con un comando come:

#sudo mount -t cgroup none /mnt

È possibile anche montare solo determinati sottosistemi di cgroup aggiungendo l’opzione -o nome_cgroup al comando mount.


Torniamo su Ubuntu (e Debian) si ha un file che può essere utilizzato per scegliere quale sottosistema di cgroups utilizzare, è /etc/cgconfig.conf , all’interno troverete la configurazione standard:

mount {
        cpu = /sys/fs//cgroup/cpu;
        cpuacct = /sys/fs/cgroup/cpuacct;
        devices = /sys/fs/cgroup/devices;
        memory = /sys/fs/cgroup/memory;
}

Questo in sostanza dice che sottosistema utilizzare e dove montarli.
Abbiamo già visto il sottosistema device gli altri nell’esempio sono:

cpu : questo sottosistema utilizza lo scheduler per fornire ai processi in cgroup accesso alla CPU.
cpuacct: questo sottosistema genera automaticamente report sulle risorse della CPU utilizzata dai processi in un cgroup.
memory: questo sottosistema pone dei limiti sull’uso della memoria da parte dei processi in un cgroup, e genera automaticamente report sulle risorse di memoria utilizzate da questi.

Per elencare i tipi di cgroup conosciuti utilizzare il seguente comando:

#cat /proc/cgroups 
 
#subsys_name	hierarchy	num_cgroups	enabled
cpuset	0	1	1
ns	0	1	1
cpu	1	1	1
cpuacct	2	1	1
memory	4	1	1
devices	3	1	1
freezer	0	1	1
net_cls	0	1	1
blkio	0	1	1

Esempio : Creiamo 2 cgroups

Finora abbiamo visto un sacco di informazioni, è il momento di vedere un esempio pratico.
Creeremo 2 gruppi di controllo denominati Browsers e Multimedia e provvederemo a impostare cgropus in modo che i browser possano utilizzare al massimo metà della CPU utilizzata da Multimedia questo perchè vogliamo garantire che risponano sempre entro certi limiti di tempo, per non perdere nemmeno un frame o sentire i fastidiosi “salti” anche quando il resto del sistema è sovraccarico.

Per farlo abbiamo 2 modi, lavorare sul filesystem o utilizzare alcuni comandi speciali sul terminale

Primo metodo è di utilizzare il meta-filesystem di cgroups.

La prima cosa da fare è creare i 2 cgroups, che non sono altro che una directory del nostro filesystem.
Vogliamo lavorare con il sottosistema CPU, quindi creeremo le 2 directory in quel percorso:

># cd /sys/fs/cgroup/cpu
># mkdir Browsers
># mkdir Multimedia

A questo punto dobbiamo dire al sistema che il cgroup Multimedia deve avere il doppio del peso rispetto a Browsers, lo facciamo creando all’interno di ogno gruppo un file dal nome cpu.shares, che contiene solo un valore, e dando a Multimedia un valore doppio rispetto a quello di Browsers:

$ echo 2048 >  /sys/fs/cgroup/cpu/Multimedia/cpu.shares
$ echo 1024 >  /sys/fs/cgroup/cpu/Browsers/cpu.shares

Abbiamo finito, beh quasi.
Ora dobbiamo dire quali processi appartengono al cgroup Multimedia e quali al cgroup Browsers.
Per spostare un processo in un cgroup il suo Pid deve essere elencati nel file /path_to_cgroup/tasksi, quindi potremmo semplicemente fare qualcosa del genere:

$ firefox &
$ echo $! >  /sys/fs/cgroup/cpu/Browsers/tasks
 
$ mplayer music.mp3 &
$ echo $! >  /sys/fs/cgroup/cpu/Multimedia/tasks

Secondo metodo è usare un set di comandi

Creazioni dei 2 cgroups viene fatta con il comando cgcreate
La sintassi è:

cgcreate -t uid:gid -a uid:gid -g subsystems:path

Quindi, per creare gli stessi 2 cgroups dobbiamo dare i comandi:

cgcreate -g cpu:/Browsers
cgcreate -g cpu:/Multimedia

Ora dobbiamo dare a Multimedia il peso doppio rispetto a Browsers, per farlo usiamo il comando cgget
la sintassi percgset è: cgset -r parameter=value path_to_cgroup, quindi nel nostro esempio daremo:

cgset -r cpu.shares=1024 Browsers
cgset -r cpu.shares=2048 Multimedia

Per spostare un processo in un cgroup è possibile utilizzare il comando cgclassify
La sintassi per cgclassify è: cgclassify -g subsystems:path_to_cgroup pidlist

Quindi se il nsotro browser ha pid 1234 e la nostra applicazione multimediale ha pid 9876 dovremmo usare questi comandi:

cgclassify -g cpu:Browsers 1234
cgclassify -g cpu:Multimedia 9876

E questo è tutto, siamo riusciti a creare 2 cgroups dove, per la cpu, un cgroup impiega il doppio delle cpu dell’altro.
Potremmo usare alcune regole simili anche per la memoria (in modo che il web server non mangi tutta la memoria del nostro database), di rete o disco I/O.

Naturalmente è anche possibile mescolare le varie regole dei cgroups in modo che un processo abbia limitazioni sia sulla Cpu che sulla Memoria.

Il demone cgred

Cgred è un demone che muove processi nei cgroups a seconda dei parametri impostati nel file /etc/cgrules.conf. Le voci nel file /etc/cgrules.conf possono prendere una delle due forme:

  • user hierarchies control_group
  • user:command hierarchies control_group
Per esempio:
maria			devices		/usergroup/staff
Questa voce specifica che tutti i processi che appartengono all’utente chiamato  maria accede al sottosistema di dispositivi in ​​base ai parametri indicati nel cgroup/usergroup/staff . Per associare comandi particolari a specifici cgroups, aggiungere il parametro command, come segue:
maria:ftp		devices		/usergroup/staff/ftp
Questa volta la entry dice che quando l’utente maria usa il comando ftp, il processo è automaticamente messo nel cgroup /usergroup/staff/ftp nella gerarchia che contiene il subsystem devices.

Conclusioni

Questo era solo un piccolo esempio dei molti usi che si possono avere per cgroups.
E’ il modo più semplice e potente per limitare le risorse sui sistemi linux.

Riferimenti

Effective Linux Resource Management, cgroups su Suse
Resource Management on Red Hta Enterprise 6
Cgroups in Debian Squeeze
Linux kernel hacking: contenitori di processi/1

Popular Posts:

Flattr this!

  5 Responses to “Introduzione a Cgroups, Linux Control Group”

  1. […] lendo este artigo neste link: http://linuxaria.com/article/introduction-to-cgroups-the-linux-conrol-group?lang=en Gostou? Talvez você goste destes também.Jupiter Applet .Dicas e truques de SSHSSH é um dos […]

  2. Hi,
    I have mounted cpuset subsystem and it created a default cgroup under it called sysdefault.All the tasks/processes belongs to this group. But I created my own cgroup in this cpuset sybsystem and I want to assign some specific tasks to my own cgroup. My question is how can I assign specific tasks to my custom cgroup? I tried using the command

    echo $pidof task > /mnt/cgroups/cpuset/mycgroup
    and also
    cgclassify -g cpuset:mycgroup $pid

    but it gives me error ” No space left on device”.

    I even modified the /etc/cgrules.conf file but it is not working.

  3. salve,
    grazie dell’articolo interessante… anche se un po’ complesso…

    come dovrei fare per limitare l’uso della ram di
    firefox (plugin-container) ?

    grazie

  4. hi,
    thanks interesting article … although a bit ‘complex …

    how should I do to limit the use of the ram in
    firefox (plugin-container) process?

    thanks

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*