6.4 · Parcours 6 — Sécuriser (CKS)
Isolation : multi-tenancy et conteneurs bac à sable (gVisor)
Leçon théorique · questionnaire de validation · gratuit, dans le navigateur
Faire tourner plusieurs équipes, plusieurs clients ou plusieurs centaines d'élèves sur le même cluster, c'est le multi-tenancy. Il fait faire de grosses économies, et il pose une vraie question de sécurité : que se passe-t-il si l'un des « locataires » est malveillant, ou simplement compromis ? Cette leçon passe en revue les niveaux d'isolation disponibles, du simple namespace au conteneur bac à sable, et ce que chacun protège réellement.
Ce que vous saurez à la fin : distinguer multi-tenancy « souple » et « dure », empiler les protections de Kubernetes (namespaces, RBAC, quotas, règles réseau, Pod Security), expliquer pourquoi le noyau partagé est le maillon faible, et ce qu'apportent gVisor, Kata Containers et les clusters virtuels.
1. Deux niveaux de confiance
| Multi-tenancy souple | Multi-tenancy dure | |
|---|---|---|
| Locataires | des équipes d'une même entreprise | des clients, des inconnus, du code non vérifié |
| Hypothèse | erreurs possibles, malveillance rare | tout locataire peut être hostile |
| Objectif | éviter qu'une équipe gêne l'autre | empêcher toute évasion et tout accès aux voisins |
| Exemples | un cluster partagé par les équipes produit | un SaaS, un hébergeur, une plateforme d'apprentissage |
Plus la confiance baisse, plus il faut empiler de couches.
2. Les protections de Kubernetes, couche par couche
| Couche | Protège contre | Leçons |
|---|---|---|
| Namespace | les conflits de noms ; c'est la base des autres réglages | 1.5 |
| RBAC au moindre privilège | un locataire qui lit ou modifie les objets d'un autre | 2.11, 4.1, 6.3 |
| ResourceQuota et LimitRange | un locataire qui affame les autres (CPU, mémoire, nombre de pods) | 2.10 |
| NetworkPolicies | un pod qui joint les services d'un autre locataire | 3.5, 6.5 |
| Pod Security Standards | un pod privilégié, monté sur le disque du nœud ou dans son réseau | 6.1 |
| Secrets chiffrés et bien rangés | la fuite d'identifiants | 6.2 |
Ces couches protègent l'API et le réseau. Il reste un point commun à tous les conteneurs d'un nœud : le noyau Linux.
3. Le maillon faible : le noyau partagé
Un conteneur classique (runc) est un processus de l'hôte : ses appels système vont directement au noyau du nœud (leçon 0.3). Une faille du noyau (il y en a chaque année) peut permettre une évasion de conteneur : le processus sort de son isolation et prend la main sur le nœud, puis sur tous les conteneurs qui y tournent, ceux des autres locataires compris.
Les protections classiques réduisent la surface sans la supprimer :
- seccomp : filtrer les appels système autorisés (
RuntimeDefault) ; - AppArmor / SELinux : restreindre les fichiers et les actions ;
- ne pas être root, et retirer les capabilities (leçon 2.12).
Pour une confiance nulle, on ajoute une frontière de plus.
4. Les conteneurs bac à sable
gVisor
gVisor (runsc) intercale un noyau applicatif, écrit en Go, entre le conteneur et le noyau de l'hôte. Les appels système du conteneur sont traités par ce noyau intermédiaire, qui n'utilise lui-même qu'un petit sous-ensemble des appels du noyau réel, le tout sous un filtre seccomp très strict.
conteneur classique : appli ──appels système──► noyau de l'hôte
conteneur gVisor : appli ──► noyau gVisor (Sentry) ──(peu d'appels, filtrés)──► noyau de l'hôte
- Avantage : une faille du noyau Linux n'est plus directement exploitable depuis le conteneur. L'attaquant doit d'abord percer gVisor.
- Coût : un surcoût sur les appels système et les entrées-sorties, quelques fonctions du noyau non prises en charge, et une consommation mémoire un peu plus élevée par pod. Les applications qui font beaucoup d'appels système (bases de données sous forte charge) le ressentent le plus.
Kata Containers
Kata lance chaque pod dans une micro-machine virtuelle légère, avec son propre noyau. L'isolation est matérielle, comme une VM, avec une interface de conteneur. Le coût : un démarrage plus lent et la virtualisation imbriquée à prévoir.
Le choix se fait par pod
Dans les deux cas, on choisit l'environnement d'exécution par pod, avec une RuntimeClass (leçon 4.8) :
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
---
apiVersion: v1
kind: Pod
spec:
runtimeClassName: gvisor
5. Isoler le plan de contrôle : clusters virtuels et clusters dédiés
Le RBAC empêche un locataire de modifier les objets globaux (CRD, ClusterRoles, webhooks), mais il ne peut alors pas en créer non plus. Pour donner à chaque locataire un vrai cluster sans multiplier les machines :
- Cluster virtuel (vCluster, Kamaji…) : chaque locataire reçoit son propre serveur d'API, avec ses CRD, ses namespaces et ses droits d'administrateur, tandis que ses pods tournent sur le cluster hôte partagé. Il est administrateur de son cluster, sans aucun droit sur l'hôte.
- Cluster dédié par locataire : l'isolation maximale, mais aussi le coût et l'effort d'exploitation maximaux.
6. Ce que fait KubeNow
Les élèves exécutent du code que personne n'a relu : c'est du multi-tenancy dur par définition. La plateforme combine donc :
- un cluster virtuel par élève (« Mon cluster ») ou un namespace dédié (labs), avec RBAC, quotas et règles réseau propres à chaque session ;
- des Pod Security Standards imposés ;
- gVisor pour tous les pods des élèves : même en cas de faille du noyau, un conteneur d'élève ne parle pas directement au noyau des serveurs.
C'est aussi pour ça que certains de vos conteneurs se comportent un peu différemment d'un serveur classique : uname -r, la mémoire minimale d'un pod…
Cette leçon se valide par le QCM de passage.