Aller au contenu

Mutations automatiques et politiques

Kontainers applique automatiquement certaines modifications (mutations) et certains contrôles (politiques) sur vos workloads au moment de leur création. Si vous avez l’habitude d’un cluster Kubernetes « vanilla », cette page est celle à lire en premier : elle recense tout ce qui se passe sans que vous l’ayez demandé.

Vue d’ensemble

ComportementEffet
imagePullPolicy forcé à AlwaysL’image est re-vérifiée auprès du registre à chaque démarrage de pod
Requests injectées si absentescpu: 100m, memory: 200Mi, ephemeral-storage: 1Gi
limits.memory alignée sur requests.memoryToujours, même si vous déclarez une valeur différente
Limite de stockage éphémère2 Gi par conteneur si non déclarée
Aucune limite CPUJamais injectée, jamais imposée
Pod Security baselinePods privilégiés, hostPath, hostNetwork… rejetés
Tolerations control-planePods rejetés à l’admission

Avant / après : un exemple réel

Voici ce que devient un Deployment déclaré sans aucune section resources :

# Ce que vous soumettez
containers:
- name: web
image: nginx:alpine
# Ce qui tourne réellement (observé sur le cluster)
containers:
- name: web
image: nginx:alpine
imagePullPolicy: Always
resources:
requests:
cpu: 100m
memory: 200Mi
ephemeral-storage: 1Gi
limits:
memory: 200Mi
ephemeral-storage: 2Gi

Et si vous déclarez une limite mémoire différente de la request, elle est ramenée à la valeur de la request :

# Vous déclarez : requests.memory: 300Mi / limits.memory: 500Mi
# La plateforme applique : requests.memory: 300Mi / limits.memory: 300Mi

Conséquences opérationnelles

imagePullPolicy: Always

  • Un tag mutable (latest, main…) est re-téléchargé à chaque redémarrage : vos pods suivent le registre, ce qui peut être voulu… ou pas.
  • Si votre registre est indisponible ou votre token de pull expiré, vos pods ne peuvent plus redémarrer — même si l’image est déjà présente sur le nœud. Pensez-y avant une opération de maintenance sur votre registre, et surveillez l’expiration de vos pull secrets.
Pourquoi cette règle ?

Les nœuds du cluster gardent en cache les images de tous les tenants. Sans re-vérification au démarrage, un pod pourrait démarrer sur l’image privée d’un autre client simplement parce qu’elle est déjà présente sur le nœud — en contournant l’authentification du registre. Always garantit que chaque démarrage revalide le droit de tirer l’image : c’est le prix de la confidentialité des images privées sur une plateforme mutualisée.

limits.memory = requests.memory

  • Il n’y a pas d’overcommit mémoire : ce que vous réservez est ce que vous pouvez consommer. Dès que votre conteneur dépasse sa request, il est OOMKilled.
  • Le réflexe vanilla « j’augmente la limit » ne fonctionne pas ici : il faut augmenter la request (et c’est elle qui est facturée).
  • Dimensionnez la request mémoire sur votre pic réel de consommation, observable dans le monitoring.
Pourquoi cette règle ?

La mémoire est une ressource non compressible : contrairement au CPU (qu’on peut throttler), un dépassement mémoire ne peut se régler que par un kill. Autoriser limit > request reviendrait à faire de l’overcommit — où un nœud saturé OOM-kill des pods d’autres tenants qui, eux, respectaient leur réservation.

Avec request = limit, chaque tenant est garanti d’avoir exactement ce qu’il réserve (et paie), et ne peut jamais déborder sur les voisins — c’est la condition d’une isolation prévisible en multi-tenant. Et cela rend l’assiette de facturation honnête : la réservation facturée correspond à la consommation maximale réellement possible.

Requests injectées

  • Même un pod déclaré « sans ressources » réserve 0,1 vCPU et 200 Mi — et cette réservation est facturée. Déclarer vos resources explicitement, c’est piloter votre facture.
Pourquoi cette règle ?

Sans request, le scheduler place les pods à l’aveugle : un nœud peut accepter plus de charge qu’il n’en supporte, et ce sont les workloads voisins qui en paient les conséquences. Injecter des requests par défaut garantit que tout pod du cluster a une réservation cohérente — le placement reste fiable pour tout le monde, et chaque consommation a une assiette de facturation.

CPU sans limite

  • Vos conteneurs peuvent burster au-delà de leur request CPU sans throttling.
  • En cas de contention sur un nœud, le partage se fait au prorata des requests : une request CPU réaliste vous garantit votre part.
Pourquoi pas de limite CPU ?

Le CPU est une ressource compressible : en cas de contention, le noyau throttle et partage au prorata des requests — personne ne peut affamer ses voisins, même sans limite. Une limite CPU n’apporterait donc rien à l’isolation ; elle ne ferait qu’ajouter de la latence artificielle sur vos pics de charge. C’est le symétrique exact de la règle mémoire : on limite strictement ce qui est non compressible, on laisse respirer ce qui l’est.

Politiques de rejet

Certaines créations sont refusées à l’admission. Les messages d’erreur ci-dessous sont ceux que vous verrez réellement.

Pods privilégiés (Pod Security baseline)

privileged: true, hostPath, hostNetwork, hostPID, hostIPC sont rejetés. Si un chart Helm public échoue au déploiement, c’est une cause fréquente.

Pourquoi cette règle ?

Toutes ces capacités donnent accès au nœud — qui est partagé entre les tenants. Un pod privilégié ou un montage hostPath permettrait de lire les données des voisins, voire de compromettre le nœud entier. Le standard baseline bloque précisément les vecteurs d’évasion connus tout en laissant passer les applications ordinaires : c’est le socle de l’isolation entre clients.

Tolerations control-plane

admission webhook "validate.kyverno.svc-fail" denied the request:
restrict-controlplane-scheduling: 'validation error: Pods may not
use tolerations which schedule on control plane nodes.'

Retirez la toleration node-role.kubernetes.io/control-plane de votre manifest.

Pourquoi cette règle ?

Les nœuds control-plane hébergent l’API et etcd — le cerveau du cluster, partagé par tous les tenants. Un workload client qui s’y planifierait entrerait en concurrence de ressources avec eux : c’est la disponibilité de la plateforme entière qui serait en jeu.