Blog

Raggiungere il vero isolamento multi-tenant in Docker

Il modello di kernel condiviso di Docker introduce rischi per ambienti multi-tenant. Questa guida fornisce passi concreti per rafforzare l'isolamento utilizzando namespace utente, seccomp, AppArmor, strumenti di sandboxing e migliori pratiche di orchestrazione.

Riepilogo

I container Docker condividono il kernel dell'host, il che può essere un problema di sicurezza per ambienti multi-tenant in cui i tenant potrebbero non fidarsi l'uno dell'altro. Questo articolo spiega le lacune di isolamento nelle configurazioni predefinite di Docker e fornisce passi concreti per rafforzare l'isolamento utilizzando namespace Linux, cgroups, namespace utente, seccomp, AppArmor e virtualizzazione hardware. Imparerai come configurare demoni Docker per tenant, utilizzare strumenti di sandboxing come gVisor o Firecracker per un isolamento più forte e orchestrare con Kubernetes per la multi-tenancy. Parleremo anche della scelta del provider di infrastruttura giusto che offra virtualizzazione basata su KVM per un ulteriore livello di separazione. Alla fine, avrai un progetto per eseguire carichi di lavoro multi-tenant sicuri con Docker.

Quando si ospitano più tenant su un singolo host Docker, l'isolamento predefinito dei container—basato su namespace Linux e cgroups—spesso non è sufficiente. Una fuga da un container in un tenant potrebbe compromettere l'intero host e tutti gli altri container. Questo problema è particolarmente acuto nell'hosting condiviso, nelle piattaforme SaaS o in qualsiasi scenario in cui codice non fidato viene eseguito insieme al proprio. La buona notizia: è possibile impilare più tecniche di isolamento per costruire un ambiente multi-tenant rafforzato. Questa guida illustra sei passi pratici, dai frutti a portata di mano come i namespace utente alle misure avanzate come runtime in sandbox e scelte infrastrutturali.

Comprendere l'isolamento predefinito di Docker

Docker utilizza i namespace Linux per isolare processi, rete, filesystem e altre risorse. I cgroup limitano CPU, memoria e I/O. Ma questi condividono un singolo kernel—una vulnerabilità nel kernel può influenzare tutti i container. Per una vera multi-tenancy, specialmente con tenant non fidati, è necessaria una difesa a strati. Come discusso in Progettare un'architettura Docker multi-tenant: scegliere il giusto livello di isolamento, i livelli di isolamento vanno da debole (solo namespace) a forte (virtualizzazione hardware). Costruiamo dal più debole.

Passo 1: Abilitare i namespace utente

Per impostazione predefinita, root all'interno di un container corrisponde a root sull'host. Una fuga dal container dà accesso completo all'host. I namespace utente rimappano root del container a un utente non root all'esterno. Abilitalo globalmente con dockerd --userns-remap=default o per container con --userns=host. Questo semplice passo elimina molti attacchi di escalation dei privilegi. Testa le tue applicazioni: alcune che richiedono privilegi a livello di host (ad esempio, montaggio di filesystem) potrebbero non funzionare. Per siti Drupal o WordPress, di solito è sicuro.

Passo 2: Applicare profili Seccomp e AppArmor

Seccomp limita le chiamate di sistema che un container può fare. Docker include un profilo seccomp predefinito che blocca syscall pericolose come mount e reboot. Per il multi-tenant, restringilo ulteriormente—blocca syscall poco comuni usate dagli strumenti di fuga. Allo stesso modo, AppArmor può confinare i processi del container. Crea un profilo AppArmor personalizzato che neghi l'accesso in scrittura alle interfacce del kernel e restringa i percorsi dei file. Entrambi sono impostati tramite flag --security-opt. Combinali per una difesa a strati.

Passo 3: Utilizzare demoni Docker per tenant

Eseguire un singolo demone Docker per tutti i tenant è rischioso—qualsiasi fuga da un container potrebbe accedere al socket del demone. Isola i demoni per tenant utilizzando Docker-in-Docker (DinD) o endpoint remoti del demone. Ad esempio, avvia un demone Docker all'interno di un container con --privileged (ma questo indebolisce l'isolamento). Un approccio migliore: eseguire demoni separati su VM separate o utilizzare la funzionalità sperimentale --group di Docker con namespace utente. Per l'orchestrazione, l'isolamento basato su namespace di Kubernetes è più pratico, come descritto in Difendersi dalla fuga dai container: guida pratica all'isolamento Docker per hosting multi-tenant.

Passo 4: Considerare i runtime in sandbox

Quando il kernel Linux stesso non è fidato, utilizza un runtime in sandbox che aggiunge un leggero layer di VM. gVisor (runsc) intercetta le syscall e implementa il proprio kernel, mentre Firecracker utilizza micro-VM con virtualizzazione hardware. Entrambi si integrano con Docker tramite i runtime containerd. Ad esempio, aggiungi "runtimes": {"runsc": {}} alla configurazione del demone Docker ed esegui container con --runtime=runsc. Il sovraccarico delle prestazioni è del 5–15% ma l'isolamento è molto più forte. Ideale per configurazioni multi-tenant ad alta sicurezza.

Passo 5: Orchestrare con Kubernetes e policy di sicurezza

Kubernetes fornisce multi-tenancy nativa tramite namespace, Pod Security Standards e NetworkPolicies. Definisci namespace per tenant con quote di risorse e applica contesti di sicurezza dei pod restrittivi (rimuovi tutte le capacità, filesystem root in sola lettura). Controller di ammissione come OPA/Gatekeeper possono bloccare configurazioni errate. Se gestisci molti tenant, Kubernetes automatizza l'applicazione dell'isolamento. Per l'orchestrazione su scala di produzione, consulta Oltre Docker Compose: orchestrare applicazioni containerizzate pronte per la produzione.

Passo 6: Scegliere il provider di hosting giusto

L'hypervisor del tuo provider di infrastruttura è importante. Docker su hosting condiviso (OpenVZ) dà un isolamento debole—un tenant può vedere i processi di altri. Preferisci provider che utilizzano KVM o VMware, che offrono separazione a livello hardware. Provider come DigitalOcean, Kamatera o AWS offrono VPS basati su KVM con risorse dedicate. Per bare-metal, assicurati che la virtualizzazione a livello BIOS sia abilitata per container nidificati. Un provider che isola i tenant a livello di hypervisor completa il tuo isolamento dei container. Come dettagliato in Padroneggiare l'isolamento Docker per un hosting web sicuro ed efficiente, anche il sistema operativo host dovrebbe essere indurito con una superficie di attacco minima.

Avvertenze e compromessi

Ogni livello aggiuntivo aumenta la complessità e il costo delle prestazioni. I namespace utente potrebbero rompere i volumi montati sull'host. I profili Seccomp richiedono messa a punto per applicazione. I runtime in sandbox come gVisor non supportano tutte le syscall—la tua app potrebbe non funzionare. I demoni Docker per tenant aumentano il sovraccarico di memoria. Scegli il livello di isolamento che corrisponde al tuo modello di minaccia: per tenant fidati, i namespace predefiniti possono bastare; per SaaS pubblici, investi in runtime sandbox e policy Kubernetes. Testa accuratamente prima della produzione.

Conclusione

Il vero isolamento multi-tenant in Docker è raggiungibile sovrapponendo più funzionalità del kernel, runtime sandbox e controlli di orchestrazione. Inizia con namespace utente e seccomp, poi passa a demoni per tenant o runtime sandbox. Per larga scala, Kubernetes fornisce isolamento basato su policy. Abbina sempre un host separato a livello di hypervisor da un provider affidabile. Nessuna singola tecnica è a prova di proiettile, ma combinarle crea una difesa robusta. I tuoi tenant ti ringrazieranno—e anche il tuo audit di sicurezza.

Sources (5)