Cosa sono gli spazi dei nomi Linux e a cosa servono?

0
199

Gli spazi dei nomi Linux sono la tecnologia alla base delle tecnologie container come Docker. Sono una funzionalità del kernel Linux che consente al sistema di limitare le risorse visualizzate dai processi containerizzati e che garantisce che nessuno di essi possa interferire con un altro.

Cosa sono gli spazi dei nomi?

Quando si eseguono molti processi e applicazioni diversi su un singolo server, come nel caso di strumenti di distribuzione come Kubernetes, è importante isolare ogni processo, principalmente per motivi di sicurezza.

Un contenitore non dovrebbe essere in grado di ottenere il controllo sulle risorse di un altro, perché se quel contenitore viene poi compromesso, potrebbe compromettere l'intero sistema. Questo metodo di attacco è simile a come funziona il bug della CPU Meltdown; diversi thread di un processore dovrebbero essere isolati l'uno dall'altro. Allo stesso modo, i processi in esecuzione su diversi sistemi virtuali (contenitori) dovrebbero essere isolati da altri contenitori.

Gli spazi dei nomi ottengono questo isolamento a livello di kernel. Simile a come funziona l'applicazione chroot, che imprigiona un processo in una directory radice diversa, gli spazi dei nomi separano altri aspetti del sistema. Sono disponibili sette namespace:

  • Mount, o mnt. Molto simile a chroot, lo spazio dei nomi Mount partiziona virtualmente il file system. I processi in esecuzione in spazi dei nomi di montaggio separati non possono accedere ai file al di fuori del loro punto di montaggio. Poiché questo viene fatto a livello di kernel, è molto più sicuro che cambiare la directory principale con chroot.
  • Processo, o pid. In Linux, i primi processi vengono generati come figli di PID 1, che costituisce la radice dell'albero dei processi. Lo spazio dei nomi del processo taglia un ramo dell'albero PID e non consente l'accesso più in alto nel ramo. I processi negli spazi dei nomi figlio avranno effettivamente più PID—il primo che rappresenta il PID globale utilizzato dal sistema principale e il secondo PID che rappresenta il PID all'interno dell'albero dei processi figlio, che ricomincerà da 1.
  • Comunicazione tra processi o ipc. Questo spazio dei nomi controlla se i processi possono comunicare direttamente tra loro.
  • Rete, o netto. Questo spazio dei nomi gestisce i dispositivi di rete che un processo può vedere. Tuttavia, questo non configura automaticamente nulla per te, devi comunque creare dispositivi di rete virtuali e gestire la connessione tra le interfacce di rete globale e le interfacce di rete figlio. Il software di containerizzazione come Docker lo ha già capito e può gestire la rete per te.
  • Utente. Questo spazio dei nomi consente al processo di avere “radice virtuale” all'interno del proprio spazio dei nomi, senza avere l'effettivo accesso root al sistema genitore. Inoltre, partiziona le informazioni UID e GID, in modo che gli spazi dei nomi figlio possano avere le proprie configurazioni utente.
  • UTS. Questo spazio dei nomi controlla le informazioni sul nome host e sul dominio e consente ai processi di pensare di essere in esecuzione su server con nomi diversi.
  • Cgroupè un'altra caratteristica del kernel molto simile ai namespace. I Cgroup consentono al sistema di definire i limiti delle risorse (CPU, memoria, spazio su disco, traffico di rete, ecc.) per un gruppo di processi. Questa è una funzionalità utile per le app containerizzate, ma non esegue alcun tipo di “isolamento delle informazioni” come farebbero gli spazi dei nomi. Lo spazio dei nomi cgroup è una cosa separata e controlla solo quali cgroup un processo può vedere e non lo assegna a un cgroup specifico.

Per impostazione predefinita, qualsiasi processo che esegui utilizza gli spazi dei nomi globali , e anche la maggior parte dei processi sul tuo sistema, se non diversamente specificato.

Lavorare con gli spazi dei nomi

Puoi utilizzare il comando lsns (ls-namespaces) per visualizzare gli attuali namespace attivi nel tuo sistema. Questo comando deve essere eseguito come root, altrimenti l'elenco potrebbe essere incompleto.

< /p> Annuncio

Sopra c'è l'output di lsns da una nuova installazione di Ubuntu. Ogni spazio dei nomi è elencato insieme all'ID del processo, all'utente e al comando che lo ha creato. I sette spazi dei nomi generati da /sbin/init con PID 1 sono i sette spazi dei nomi globali. Gli unici altri spazi dei nomi sono gli spazi dei nomi mnt per i demoni di sistema, insieme al servizio Livepatch di Canonical.

Se lavorassi con i contenitori, questo elenco sarebbe molto più lungo. Puoi generare questo elenco in formato JSON con il flag -J , che puoi utilizzare molto più facilmente con un linguaggio di script.

Puoi modificare lo spazio dei nomi corrente con l'utilità nsenter. Questo comando ti permette di “inserire” lo spazio dei nomi di un altro processo, solitamente per scopi di debug. Può effettivamente eseguire qualsiasi comando in quello spazio dei nomi, ma per impostazione predefinita tenta solo di caricare una shell (/bin/bash di solito).

Si specifica un ID di processo, quindi ogni spazio dei nomi che si desidera inserire:

sudo nsenter -t PID –mount –net –pid //etc.

Ad esempio, il tentativo di inserire lo spazio dei nomi mount per kdevtmpfs ti caricherà in quello spazio dei nomi, ma successivamente fallirà perché non riesce a trovare /bin/bash, il che significa che in realtà ha funzionato, perché la directory radice apparente è stata modificata .

Pubblicità

Se lo spazio dei nomi mnt di tuo figlio include /bin/bash, puoi inserirlo e caricare una shell. Questa operazione può essere eseguita manualmente, ma deve essere eseguita tramite montaggi di bind, che possono manipolare l'albero delle directory e collegare i file negli spazi dei nomi mnt. Questo può portare ad alcuni casi d'uso interessanti, come far leggere a due processi contenuti diversi dallo stesso file.

Per creare nuovi spazi dei nomi, devi eseguire il fork da uno esistente (di solito globale) e specificare quali spazi dei nomi vuoi modificare. Questa operazione viene eseguita con il comando unshare, che esegue un comando con un nuovo spazio dei nomi “unshared” dal master.

Per annullare la condivisione dello spazio dei nomi del nome host, usa:

sudo unshare -u command

Se il comando viene lasciato vuoto, unshare esegue bash per impostazione predefinita. Questo crea un nuovo spazio dei nomi che verrà visualizzato nell'output di lsns:

< /p>

La schermata del multiplexer del terminale viene utilizzata qui per mantenere bash in esecuzione in background, altrimenti lo spazio dei nomi scomparirebbe alla chiusura del processo.

A meno che tu non stia eseguendo una programmazione di livello molto basso, probabilmente non dovrai toccare gli spazi dei nomi da solo. I programmi di containerizzazione come Docker gestiranno i dettagli per te e, nella maggior parte dei casi in cui è necessario l'isolamento dei processi, dovresti semplicemente utilizzare uno strumento esistente. Tuttavia, è importante capire come funzionano gli spazi dei nomi nel contesto della containerizzazione, specialmente se stai eseguendo una configurazione di basso livello dei tuoi container Docker o devi eseguire qualsiasi debug manuale.