---
title: "Mutations automatiques et politiques"
description: "Tout ce que la plateforme Kontainers modifie ou impose automatiquement sur vos pods : imagePullPolicy, requests, limites mémoire, sécurité."
source_url:
  html: https://docs.blackswift.cloud/reference/mutations-et-politiques/
  md: https://docs.blackswift.cloud/reference/mutations-et-politiques.md
---

# Mutations automatiques et politiques

> Tout ce que la plateforme Kontainers modifie ou impose automatiquement sur vos pods : imagePullPolicy, requests, limites mémoire, sécurité.

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

| Comportement | Effet |
| --- | --- |
| `imagePullPolicy` forcé à `Always` | L'image est re-vérifiée auprès du registre à chaque démarrage de pod |
| Requests injectées si absentes | `cpu: 100m`, `memory: 200Mi`, `ephemeral-storage: 1Gi` |
| `limits.memory` alignée sur `requests.memory` | Toujours, même si vous déclarez une valeur différente |
| Limite de stockage éphémère | 2 Gi par conteneur si non déclarée |
| Aucune limite CPU | Jamais injectée, jamais imposée |
| Pod Security `baseline` | Pods privilégiés, hostPath, hostNetwork… rejetés |
| Tolerations control-plane | Pods rejetés à l'admission |

## Avant / après : un exemple réel

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

```yaml
# Ce que vous soumettez
containers:
  - name: web
    image: nginx:alpine
```

```yaml
# 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 :

```yaml
# 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](https://docs.blackswift.cloud/depanner/pod-en-erreur.md).

<details>
<summary>Pourquoi cette règle ?</summary>

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.

</details>

### `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](https://docs.blackswift.cloud/reference/facturation.md)).
- Dimensionnez la request mémoire sur votre pic réel de consommation, observable
  dans le [monitoring](https://docs.blackswift.cloud/operer/acceder-au-monitoring.md).

<details>
<summary>Pourquoi cette règle ?</summary>

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.

</details>

### 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](https://docs.blackswift.cloud/reference/facturation.md). Déclarer vos `resources`
  explicitement, c'est piloter votre facture.

<details>
<summary>Pourquoi cette règle ?</summary>

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.

</details>

### 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.

<details>
<summary>Pourquoi pas de limite CPU ?</summary>

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.

</details>

## 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.

<details>
<summary>Pourquoi cette règle ?</summary>

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.

</details>

### Tolerations control-plane

```text
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.

<details>
<summary>Pourquoi cette règle ?</summary>

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.

</details>

<Aside type="tip">
Un pod rejeté à l'admission n'apparaît jamais dans `kubectl get pods` : c'est le
ReplicaSet qui porte l'erreur. Voir
[Aucun pod ne se crée](https://docs.blackswift.cloud/depanner/checklist-de-diagnostic.md).
</Aside>
