Blog

Una guida passo dopo passo per l'isolamento multi-tenant in Docker

Isola i carichi di lavoro multi-tenant in Docker controllando l'overhead di hosting. Scopri come configurare namespace, cgroup, policy di rete e hardening del runtime.

Riepilogo

La gestione di un'infrastruttura condivisa per campagne di più clienti o per proprietà web interne genera spesso attriti con la dirigenza a causa dei costi di hosting e della sicurezza dei dati. I container Docker offrono un'alternativa leggera alle macchine virtuali dedicate, ma le configurazioni predefinite presentano gravi lacune nell'isolamento. Un autentico multi-tenancy richiede perimetri ben definiti a livello di kernel, processi, rete e storage. Questa guida fornisce un framework pratico in cinque passaggi per proteggere le implementazioni Docker multi-tenant sfruttando le primitive di isolamento native di Linux. Imparerai come applicare quote sulle risorse, limitare i privilegi dei processi, segmentare le reti dei container e selezionare il giusto livello di isolamento. Seguendo questa blueprint, potrai salvaguardare gli ambienti dei tenant e difendere i budget infrastrutturali davanti agli stakeholder non tecnici.

Il tuo manager non tecnico entra nel tuo ufficio con la stampa dell'ultima fattura dell'hosting cloud. I costi sono aumentati, eppure diverse landing page ad alta priorità hanno subito picchi di latenza durante il lancio simultaneo di un prodotto. Ti viene chiesto di spiegare perché gli asset di marketing condividono gli stessi server, se i dati dei clienti sono esposti e perché il team non può semplicemente avviare una costosa macchina virtuale dedicata per ogni singola campagna.

Assegnare a ogni proprietà digitale una propria macchina virtuale (VM) elimina il problema dei "noisy neighbor", ma prosciuga rapidamente il budget operativo. I deployment Docker standard risolvono il problema dei costi eseguendo più siti su un unico kernel del sistema operativo, ma le configurazioni predefinite lasciano pericolose falle nell'isolamento. Se l'applicazione di un tenant riscontra uno script fuori controllo o subisce una violazione della sicurezza, qualsiasi altra applicazione ospitata sullo stesso host si ritrova a rischio.

Usa questa blueprint tecnica passo dopo passo per configurare un rigoroso isolamento multi-tenant in Docker. Implementa questi cinque passaggi operativi per proteggere la stabilità del sistema, isolare i dati dei tenant e tradurre le scelte di infrastruttura tecnica in un chiaro valore di business per la leadership aziendale.


1. Imponi quote rigide sulle risorse utilizzando i Control Group

Imposta immediatamente limiti espliciti su CPU, memoria e I/O del disco per ogni container. Quando più tenant condividono un host sottostante, i container senza vincoli competono per le risorse di sistema. Una singola query di database incontrollata o una campagna ad alto traffico possono esaurire l'intero pool di memoria dell'host, innescando l'Out-Of-Memory (OOM) killer di Linux che terminerà arbitrariamente processi di sistema.

I control group (cgroup) di Linux determinano la quantità di capacità di calcolo che ogni container può consumare. Applica questi limiti direttamente nelle definizioni di deployment:

services:
  tenant_app:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
  • Limiti di memoria (limits.memory): stabiliscono un tetto massimo invalicabile. Se il container supera i 512 megabyte, il kernel termina i processi al suo interno senza degradare i tenant adiacenti.
  • Riserve di memoria (reservations.memory): garantiscono un'allocazione di memoria di base, in modo che le applicazioni a basso traffico rimangano reattive.
  • Limiti di CPU (limits.cpus): limitano il container a una frazione massima dei core CPU disponibili, evitando che un singolo tenant monopolizzi la CPU.

Quando giustifichi questa architettura a dirigenti non tecnici, spiega i cgroup come contatori digitali automatizzati. Proprio come gli inquilini di un edificio commerciale pagano per il proprio consumo elettrico individuale invece di sovraccaricare l'interruttore principale, i cgroups assicurano che una landing page ad alto traffico non mandi mai in tilt il portale di lead generation di un altro cliente. Per un'analisi più approfondita dei compromessi architetturali, consulta la nostra guida su come progettare un'architettura multi-tenant.


2. Segmenta i processi dei tenant con namespace e utenti non-root

Non eseguire mai i processi dei container come utente predefinito root. Negli ambienti standard dei container Linux, l'utente root all'interno di un container corrisponde all'utente root sul kernel dell'host sottostante, a meno che non venga esplicitamente rimappato. Se un malintenzionato compromette un'applicazione web eseguita come root, ottiene privilegi elevati sull'host condiviso.

Applica l'isolamento dei processi tramite i namespace utente e l'esecuzione esplicita come non-root:

  1. Definisci utenti di runtime non privilegiati: crea utenti di servizio dedicati e con privilegi minimi all'interno dei tuoi Dockerfile.
    FROM php:8.2-fpm-alpine
    RUN addgroup -g 10001 tenantgroup && \
        adduser -u 10001 -D -G tenantgroup tenantuser
    USER tenantuser
    
  2. Abilita gli User Namespace (userns-remap): configura il demone Docker (/etc/docker/daemon.json) per rimappare gli ID utente dei container su un intervallo non privilegiato sull'host.
    {
      "userns-remap": "default"
    }
    

I namespace di Linux partizionano la visibilità del sistema. Il namespace Process ID (PID) garantisce che il Tenant A non possa visualizzare, inviare segnali o arrestare i processi appartenenti al Tenant B. Il namespace Mount (MNT) fornisce a ciascun tenant una vista isolata del filesystem, mentre i namespace IPC bloccano la comunicazione interprocesso non autorizzata.

La rimappatura dei namespace utente neutralizza i vettori di evasione dai container: un processo che crede di essere root (UID 0) all'interno del proprio container viene mappato su un ID non privilegiato (come UID 165536) sulla macchina host. Se un exploit aggira le barriere del container, l'attaccante si ritrova in una shell non privilegiata, impossibilitato a modificare le configurazioni dell'host o ad accedere alle directory degli altri tenant.


3. Rimuovi i privilegi del kernel e applica filesystem di sola lettura

Riduci al minimo le Linux capability disponibili e rendi il filesystem root del container immutabile all'avvio. I runtime dei container standard concedono circa una dozzina di capability del kernel Linux, molte delle quali non sono affatto necessarie per le applicazioni web. Le capability in eccesso offrono agli aggressori strumenti utili per manipolare il routing di rete, modificare l'orologio dell'host o aggirare i controlli di accesso ai file.

Proteggi i container di runtime rimuovendo tutte le capability predefinite e ripristinando solo i flag operativi essenziali:

services:
  tenant_web:
    image: custom-nginx:latest
    read_only: true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
      - seccomp=default.json
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=64m
      - /var/run:rw,noexec,nosuid,size=16m
  • cap_drop: - ALL: elimina qualsiasi capability del kernel dal processo del container.
  • cap_add: - NET_BIND_SERVICE: consente esplicitamente il binding alle porte privilegiate (come la 80 e la 443), bloccando al contempo la manipolazione diretta dei raw socket di rete.
  • read_only: true: monta l'intero filesystem root del container in sola lettura. Gli attaccanti non potranno scaricare binari dannosi, modificare script PHP o alterare i file di configurazione del web server.
  • tmpfs: alloca directory volatili in memoria per i file temporanei necessari (come /tmp), bloccando l'esecuzione di binari (noexec) e l'escalation di privilegi (nosuid).

Applica filtri Secure Computing Mode (seccomp) e moduli di sicurezza come AppArmor o SELinux per intercettare e limitare le chiamate di sistema (syscall) effettuate verso il kernel condiviso dell'host. Se il tuo team gestisce build personalizzate di applicazioni web, segui i nostri passaggi strutturati per l'hardening dei container Docker lungo tutte le pipeline di deployment.


4. Partiziona le reti tra gli ambienti dei tenant

Disabilita il networking bridge predefinito e stabilisci reti bridge custom, software-defined e isolate per lo stack di ciascun tenant. Per impostazione predefinita, i container posizionati sulla rete bridge standard di Docker possono scoprirsi e comunicare tra loro tramite indirizzi IP interni. Una vulnerabilità nel microservizio di marketing di un tenant consentirebbe lo spostamento laterale verso qualsiasi altro database o applicazione interna presente su quell'host.

Isola completamente il traffico dei tenant dichiarando bridge di rete indipendenti per ciascuno di essi:

networks:
  tenant_alpha_net:
    driver: bridge
    internal: true
  tenant_beta_net:
    driver: bridge
    internal: true
  public_gateway_net:
    driver: bridge

services:
  alpha_app:
    image: tenant_a_app:latest
    networks:
      - tenant_alpha_net
      - public_gateway_net

  alpha_db:
    image: mariadb:10.11
    networks:
      - tenant_alpha_net

  beta_app:
    image: tenant_b_app:latest
    networks:
      - tenant_beta_net
      - public_gateway_net

  beta_db:
    image: mariadb:10.11
    networks:
      - tenant_beta_net
  • Isolamento del tenant: alpha_app e alpha_db comunicano esclusivamente su tenant_alpha_net. beta_app non può raggiungere alpha_db, anche qualora un malintenzionato scansionasse la subnet interna.
  • Flag internal (internal: true): impedisce alle reti dei database di instradare il traffico direttamente verso l'esterno su Internet, limitando l'accesso in ingresso e in uscita esclusivamente ai container applicativi.
  • Gateway Reverse Proxy: solo il proxy di ingresso si collega a public_gateway_net per instradare le richieste HTTP/HTTPS in arrivo verso il container designato in base all'hostname.

Per ambienti più avanzati, valuta le modalità Enhanced Container Isolation (ECI) di Docker o runtime come Sysbox, che impongono automaticamente perimetri più rigidi sui namespace utente e filesystem /proc e /sys virtualizzati senza richiedere complesse configurazioni manuali di rete.


5. Definisci una matrice decisionale oggettiva per il multi-tenancy

Supera la convinzione secondo cui tutti gli asset digitali richiedano macchine virtuali dedicate. I responsabili marketing spesso presumono che l'isolamento tramite VM a livello hardware sia l'unico modello di sicurezza valido. In realtà, il provisioning di VM dedicate per landing page leggere o siti di campagne temporanee genera costi enormi e un pesante overhead di manutenzione operativa senza migliorare la sicurezza dell'applicazione web.

Utilizza la seguente matrice comparativa per valutare i requisiti dei carichi di lavoro e presentare una strategia di deployment razionale ai decisori aziendali:

Livello di isolamentoTecnologia sottostantePerimetro di sicurezzaOverhead delle risorseCaso d'uso ideale
Container su stack condivisoNamespace e cgroup su singolo SOIsolamento logico a livello di SOMolto bassoLanding page ad alto volume, staging interno, siti di campagne temporanee
Container rinforzati (ECI / Sysbox)Namespace utente, AppArmor, root di sola letturaA livello di SO avanzato e virtualizzazioneBassoHosting multi-cliente per agenzie, portali autenticati, form di marketing sensibili
Macchine virtuali dedicate (VM)Virtualizzazione hardware tramite hypervisorRigorosa separazione hardware/kernelAltoElaborazione pagamenti, dati regolamentati HIPAA/PCI, esecuzione di codice personalizzato non attendibile
Ibrido (container in VM dedicate)Container rinforzati all'interno di VM dedicate al tenantPerimetri multilivello hardware e SODa moderato ad altoClienti enterprise di fascia alta che richiedono conformità contrattuale dedicata

Valuta ogni progetto in base a criteri rigorosi prima di allocare il budget per l'infrastruttura:

  1. Sensibilità dei dati: il progetto archivia dati soggetti a regolamentazioni (ad es. dati di carte di credito o informazioni sanitarie)? Se sì, implementalo su una VM dedicata.
  2. Provenienza del codice: stai implementando codice standardizzato e verificato dal team o stai consentendo l'uso di plugin di terze parti non controllati? Il codice standard appartiene a container rinforzati; il codice di terze parti non testato richiede l'isolamento tramite hypervisor.
  3. Budget e ciclo di vita: per landing page stagionali e siti web aziendali principali, il multi-tenancy basato su container rinforzati garantisce il massimo rendimento per ogni euro speso.

Quando presenti i piani infrastrutturali al management, consulta la nostra guida su come valutare quando i clienti necessitano di VM dedicate per supportare le tue raccomandazioni con solide argomentazioni suddivise per livelli.


Conclusione: trasformare i controlli di sicurezza in ROI di business

Proteggere un ambiente Docker multi-tenant non richiede il budget di un'architettura cloud enterprise. Richiede un'applicazione rigorosa e disciplinata dei controlli del sistema operativo.

Quando revisioni l'infrastruttura con la leadership non tecnica, inquadra queste configurazioni tecniche attorno a tre metriche aziendali chiave:

  • Efficienza dei costi: i container multi-tenant consentono al team di ospitare decine di siti di marketing con una frazione dell'impronta di calcolo richiesta dalle singole VM.
  • Garanzia di uptime: i control group assicurano che i picchi di traffico su una campagna stagionale non degradino le prestazioni dei siti web istituzionali.
  • Contenimento del raggio d'impatto (Blast Radius): filesystem di sola lettura, rimozione delle capability e bridge di rete isolati assicurano che una violazione su un singolo sito non possa accedere ai database dei clienti adiacenti o ai controlli dell'host.

Implementa queste misure di sicurezza in modo sistematico nei tuoi template di container. Otterrai un'infrastruttura ad alte prestazioni e conveniente che soddisfa sia gli standard di sicurezza ingegneristici sia i vincoli di budget della dirigenza.

Sources (5)