Blog
Un plan étape par étape pour l'isolation multi-tenant avec Docker
Isolez les charges de travail multi-tenants dans Docker tout en maîtrisant les coûts d'hébergement. Découvrez comment configurer les namespaces, cgroups, politiques réseau et le durcissement du runtime.
Résumé
Gérer une infrastructure mutualisée pour les campagnes de plusieurs clients ou des sites web internes entraîne souvent des frictions avec la direction concernant les coûts d'hébergement et la sécurité des données. Les conteneurs Docker offrent une alternative légère aux machines virtuelles dédiées, mais leurs configurations par défaut présentent d'importantes failles d'isolation. Une véritable mutualisation (multi-tenancy) exige des délimitations strictes au niveau du noyau, des processus, du réseau et du stockage. Ce guide fournit un cadre pratique en cinq étapes pour sécuriser les déploiements Docker multi-tenants à l'aide des mécanismes d'isolation natifs de Linux. Vous apprendrez à appliquer des quotas de ressources, restreindre les privilèges des processus, segmenter les réseaux de conteneurs et choisir le bon niveau d'isolation. En suivant ce plan d'action, vous pourrez protéger les environnements de vos clients et défendre vos budgets d'infrastructure auprès des décideurs non techniques.
Votre responsable non technique entre dans votre bureau avec la facture d'hébergement cloud du mois dernier à la main. Les coûts ont grimpé en flèche, alors même que plusieurs landing pages stratégiques ont subi des pics de latence lors d'un lancement de produit simultané. On vous demande d'expliquer pourquoi les ressources marketing partagent les mêmes serveurs, si les données des clients sont exposées et pourquoi l'équipe ne peut pas simplement déployer une machine virtuelle dédiée et coûteuse pour chaque campagne.
Attribuer à chaque ressource numérique sa propre machine virtuelle (VM) élimine le problème des voisins bruyants (« noisy neighbors »), mais cela épuise rapidement votre budget opérationnel. Les déploiements Docker standards résolvent le problème des coûts en exécutant plusieurs sites sur un seul et même noyau de système d'exploitation, mais les configurations par défaut laissent de dangereuses brèches d'isolation. Si l'application d'un client subit l'exécution d'un script incontrôlé ou une intrusion malveillante, toutes les applications co-hébergées sur cet hôte sont en danger.
Suivez ce plan technique étape par étape pour configurer une isolation multi-tenant rigoureuse dans Docker. Mettez en œuvre ces cinq étapes opérationnelles pour protéger la stabilité du système, isoler les données de chaque client et valoriser vos choix d'infrastructure technique auprès de votre direction.
1. Imposer des quotas stricts de ressources grâce aux Control Groups
Définissez immédiatement des limites explicites de processeur (CPU), de mémoire et d'E/S disque sur chaque conteneur. Lorsque plusieurs locataires (tenants) partagent un hôte sous-jacent, les conteneurs sans restriction entrent en concurrence pour les ressources système. Une simple requête de base de données incontrôlée ou une campagne à fort trafic peut saturer la mémoire totale de l'hôte, déclenchant le mécanisme Out-Of-Memory (OOM) killer de Linux qui fermera des processus système de manière arbitraire.
Les groupes de contrôle Linux (cgroups) régissent la quantité de ressources de calcul qu'un conteneur peut consommer. Définissez ces limites directement dans vos fichiers de déploiement :
services:
tenant_app:
image: nginx:alpine
deploy:
resources:
limits:
cpus: '0.75'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
- Limites de mémoire (
limits.memory) : Définit un plafond strict. Si le conteneur dépasse 512 mégaoctets, le noyau met fin aux processus à l'intérieur de ce conteneur sans dégrader les conteneurs voisins. - Réservations de mémoire (
reservations.memory) : Garantit une allocation de mémoire minimale afin que les applications à faible trafic restent réactives. - Limites de CPU (
limits.cpus) : Limite le conteneur à une fraction maximale des cœurs CPU disponibles, évitant ainsi qu'un seul client n'accapare tout le processeur.
Pour justifier cette architecture auprès de décideurs non techniques, comparez les cgroups à des sous-compteurs électriques individuels. Tout comme les locataires d'un immeuble de bureaux paient leur propre consommation d'électricité au lieu de faire disjoncter le compteur principal, les cgroups garantissent qu'une landing page à fort trafic ne fera jamais tomber le portail de génération de leads d'un autre client. Pour une analyse plus approfondie des compromis architecturaux, consultez notre guide sur la conception d'une architecture Docker multi-tenant.
2. Segmenter les processus locataires avec les Namespaces et les utilisateurs non-root
N'exécutez jamais les processus de conteneur en tant qu'utilisateur root par défaut. Dans les environnements de conteneurs Linux standards, l'utilisateur root à l'intérieur d'un conteneur correspond au root du noyau de l'hôte sous-jacent, sauf en cas de remappage explicite. Si un attaquant compromet une application web exécutée sous root, il obtient des privilèges élevés sur l'ensemble de l'hôte partagé.
Appliquez l'isolation des processus à l'aide des namespaces utilisateur et d'une exécution explicite sans privilèges root :
- Définir des utilisateurs d'exécution non privilégiés : Créez des utilisateurs de service dédiés et à faibles privilèges dans vos Dockerfiles.
FROM php:8.2-fpm-alpine RUN addgroup -g 10001 tenantgroup && \n adduser -u 10001 -D -G tenantgroup tenantuser USER tenantuser - Activer les User Namespaces (userns-remap) : Configurez le démon Docker (
/etc/docker/daemon.json) pour remapper les ID utilisateurs des conteneurs vers une plage non privilégiée sur l'hôte.{ "userns-remap": "default" }
Les namespaces Linux compartimentent la visibilité du système. Le namespace PID (Process ID) garantit que le locataire A ne peut ni voir, ni envoyer de signaux, ni terminer les processus appartenant au locataire B. Le namespace Mount (MNT) donne à chaque locataire une vue isolée du système de fichiers, tandis que les namespaces IPC bloquent toute communication inter-processus non autorisée.
Le remappage des user namespaces neutralise les risques d'évasion de conteneur : un processus qui pense être root (UID 0) à l'intérieur de son conteneur est en réalité mappé sur un identifiant non privilégié (tel que l'UID 165536) sur la machine hôte. Si un exploit franchit les barrières du conteneur, l'attaquant se retrouve dans un shell sans privilèges, incapable de modifier les configurations de l'hôte ou d'accéder aux répertoires des autres locataires.
3. Réduire les privilèges du noyau et imposer des systèmes de fichiers en lecture seule
Supprimez les capacités Linux superflues et rendez le système de fichiers racine du conteneur immuable au démarrage. Par défaut, les moteurs d'exécution de conteneurs accordent environ une douzaine de capacités (Linux capabilities) au noyau, dont la plupart ne sont jamais nécessaires aux applications web. Ces privilèges superflus fournissent aux attaquants des outils pour manipuler le routage réseau, modifier l'horloge de l'hôte ou contourner les contrôles d'accès aux fichiers.
Verrouillez les conteneurs en production en supprimant toutes les capacités par défaut et en ne réactivant que les options opérationnelles indispensables :
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: Retire toutes les capacités du noyau au processus du conteneur.cap_add: - NET_BIND_SERVICE: Autorise explicitement l'écoute sur des ports privilégiés (comme 80 et 443) tout en bloquant la manipulation brute des sockets réseau.read_only: true: Monte l'intégralité du système de fichiers racine du conteneur en lecture seule. Les attaquants ne peuvent pas télécharger de binaires malveillants, modifier de scripts PHP ni altérer les fichiers de configuration du serveur web.tmpfs: Alloue des répertoires temporaires en mémoire pour les fichiers nécessaires (comme/tmp) tout en interdisant l'exécution de binaires (noexec) et l'élévation de privilèges (nosuid).
Appliquez des filtres seccomp (secure computing mode) et des modules de sécurité comme AppArmor ou SELinux pour intercepter et restreindre les appels système adressés au noyau partagé de l'hôte. Si votre équipe gère des builds d'applications web personnalisés, suivez nos étapes structurées pour le durcissement des conteneurs Docker dans vos pipelines de déploiement.
4. Cloisonner les réseaux entre les environnements locataires
Désactivez le réseau bridge par défaut et mettez en place des réseaux bridge personnalisés et isolés pour chaque environnement client. Par défaut, les conteneurs placés sur le réseau bridge standard de Docker peuvent se découvrir et communiquer entre eux via leurs adresses IP internes. Une vulnérabilité dans le microservice marketing d'un client permet ainsi un déplacement latéral vers toutes les autres bases de données et applications internes hébergées sur ce serveur.
Isolez complètement le trafic des locataires en déclarant des ponts réseau indépendants pour chacun d'eux :
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
- Isolation des locataires :
alpha_appetalpha_dbcommuniquent exclusivement viatenant_alpha_net.beta_appne peut pas joindrealpha_db, même si un attaquant analyse le sous-réseau interne. - Paramètre interne (
internal: true) : Empêche les réseaux de bases de données de router du trafic directement vers Internet, limitant les accès entrants et sortants uniquement aux conteneurs applicatifs. - Passerelle Reverse Proxy : Seul le proxy d'entrée est connecté à
public_gateway_netpour router les requêtes HTTP/HTTPS entrantes vers le conteneur du locataire approprié en fonction du nom d'hôte.
Pour les environnements plus exigeants, envisagez les modes d'isolation avancée (Enhanced Container Isolation ou ECI) de Docker ou des moteurs d'exécution comme Sysbox, qui appliquent automatiquement des limites de namespaces utilisateur plus strictes et virtualisent les systèmes de fichiers /proc et /sys sans nécessiter de scripts réseau complexes.
5. Établir une matrice de décision objective pour le multi-tenant
Combattez l'idée reçue selon laquelle chaque actif numérique nécessiterait une machine virtuelle dédiée. Les responsables marketing supposent souvent que l'isolation au niveau matériel via VM est le seul modèle de sécurité valable. En réalité, provisionner des VM dédiées pour de simples landing pages ou des sites de campagne temporaires engendre une explosion des coûts et une lourde charge de maintenance opérationnelle, sans pour autant améliorer la sécurité de l'application web.
Utilisez la matrice comparative suivante pour évaluer les besoins de vos charges de travail et présenter une stratégie de déploiement rationnelle aux décideurs :
| Niveau d'isolation | Technologie sous-jacente | Périmètre de sécurité | Surcharge de ressources | Cas d'usage idéal |
|---|---|---|---|---|
| Conteneurs sur stack mutualisée | Namespaces & Cgroups sur un OS unique | Isolation logique au niveau de l'OS | Très faible | Landing pages à fort trafic, préproduction interne, sites de campagne temporaires |
| Conteneurs durcis (ECI / Sysbox) | User namespaces, AppArmor, racine en lecture seule | Niveau OS avancé & virtualisation | Faible | Hébergement multi-clients en agence, portails authentifiés, formulaires marketing sensibles |
| Machines virtuelles dédiées (VM) | Virtualisation matérielle par hyperviseur | Séparation stricte matériel/noyau | Élevée | Traitement des paiements, données réglementées HIPAA/PCI, exécution de code tiers non vérifié |
| Hybride (Conteneurs dans des VM dédiées) | Conteneurs durcis au sein de VM spécifiques au client | Cloisonnement multicouche matériel & OS | Modérée à élevée | Grands comptes exigeant une conformité contractuelle dédiée |
Évaluez chaque projet selon des critères stricts avant d'allouer du budget d'infrastructure :
- Sensibilité des données : Le projet stocke-t-il des données soumises à réglementation (ex. données de carte bancaire ou informations de santé) ? Si oui, déployez-le sur une VM dédiée.
- Provenance du code : Déployez-vous du code standardisé et audité par votre équipe ou autorisez-vous des plugins tiers non vérifiés ? Le code standard a sa place dans des conteneurs durcis ; le code tiers non testé nécessite une isolation par hyperviseur.
- Budget et durée de vie : Pour les landing pages saisonnières et les sites web d'entreprise classiques, la mutualisation sur conteneurs durcis offre le meilleur rapport performance/prix.
Lorsque vous présentez vos plans d'infrastructure à la direction, appuyez-vous sur notre guide pour évaluer quand les clients ont besoin de VM dédiées afin de soutenir vos recommandations par des arguments structurés par niveaux.
Conclusion : Traduire les contrôles de sécurité en retour sur investissement (ROI)
Sécuriser un environnement Docker multi-tenant ne nécessite pas un budget d'infrastructure cloud démesuré. Cela exige simplement une application rigoureuse et méthodique des contrôles du système d'exploitation.
Lorsque vous faites le point sur l'infrastructure avec des dirigeants non techniques, structurez vos explications autour de trois indicateurs clés :
- Rentabilité : Les conteneurs mutualisés permettent à l'équipe d'héberger des dizaines de sites marketing sur une fraction de la puissance de calcul requise par des VM individuelles.
- Garantie de disponibilité : Les groupes de contrôle (cgroups) garantissent qu'un pic de trafic sur une campagne saisonnière ne dégradera pas les performances des sites institutionnels principaux.
- Limitation du périmètre d'impact : Les systèmes de fichiers en lecture seule, la suppression des privilèges et les ponts réseau isolés garantissent qu'une faille sur un site ne permettra jamais d'accéder aux bases de données des autres clients ni aux commandes de l'hôte.
Appliquez ces garde-fous de manière systématique dans vos modèles de conteneurs. Vous offrirez ainsi une infrastructure performante et économique qui répond à la fois aux exigences de sécurité des équipes d'ingénierie et aux contraintes budgétaires de la direction.

