Introduzione
Studiando i container spesso vengono citati chroot
, cgroups
e namespaces
. Vediamo di capire meglio cosa sono e perché è così importante capirne il funzionamento.
Chroot
In sistemi operativi Unix-like la top directory del file system è detta root directory ed è “/”. Tutto il file system è montato a partire dalla root directory come rami e sotto-rami di questa root.
Ogni processo però può avere una sua personale directory root: di default è la system root ma possiamo cambiarlo utilizzando il comando chroot()
: questo comando cambia la root directory del processo corrente e dei suo processi figli.
Potrebbe sembrare che usare il comando chroot()
permetta di aumentare la sicurezza del processo impedendogli, di fatto, di agire su file fuori dal proprio ambiente, ma questo non è vero.
chroot()
infatti effettua semplicemente un prepend della nuova root impostata a tutti i path che iniziano con “/
“. Utilizzando un path relativo posso quindi comunque agire su ogni file presente sul file system allo stesso modo.
chroot()
quindi è un comodo comando ma che non può essere usato per creare una sandbox dove andare a testare un software.
Cggroups
I Control Groups (cgroups) è una funzionalità di Linux che permette di limitare le risorse (CPU, memoria, network, IO) utilizzare da gruppi di processi.
Questi sono comodi quando si ha la necessità di un controllo più di fino rispetto a quello offerto di default dal sistema operativo su un insieme di processi.
Per esempio potrei avere la necessità che un applicazione non utilizzi più del 50% di CPU, o del 30% di RAM e così via; inoltre posso volere che questi limiti siano rispettati solo in caso di scarsità di risorse: in questo modo se il server è libero non c’è problema, se invece ha molto lavoro da fare posso definire quante risorse assegnare ad ogni gruppo.
Namespaces
Linux prevede un sistema gerarchico nei processi: init
è il padre di tutti i processi, è eseguito dal kernel durante il boot e il suo scopo principale è quello di creare i processi individuati da uno script in /etc/inittab
.
Tipicamente i processi padri possono killare i processi figli e così via.
I namespaces permettono di avere varie strutture gerarchiche di processi ognuno con il proprio albero di figli ma in cui un processo in un albero non può accedere e nemmeno sapere di un processo presente in un altro albero.
Senza utilizzare i namespace ho quindi una unica struttura ad albero dove la root è il processo init (PID = 1).
Utilizzando i namespace ho n strutture ad albero gerarchiche parallele e indipendenti: per esempio potrei avere due PID: uno per il namespace globale e uno per il mio namespace custom.
Ogni processo associato con un namespace può vedere o utilizzare solo le risorse associate a quel namespace e name
Conclusione
Come abbiamo visti i comandi chroot
, cgroups
e namespaces
permettono agli sviluppatori di fornire un certo grado di isolamento dei processi dagli altri, dal punto di vista del file system (chroot
), delle risorse (cgroup
) e degli altri processi (namespace
).
Utilizzando questi comandi posso quindi creare una specie di container dei processi: queste tecnologie sono infatti la base del funzionamento di Docker.