Aller au contenu
Conteneurs & Orchestration high

Admission Controllers Kubernetes : valider et modifier vos ressources

15 min de lecture

Logo Kubernetes

Les Admission Controllers sont des plugins qui interceptent les requêtes vers l'API Kubernetes après authentification et autorisation, mais avant la persistance dans etcd. Ils peuvent valider (accepter ou refuser) ou muter (modifier) les ressources. Ce mécanisme est la base du policy-as-code sur Kubernetes.

Quand vous créez une ressource avec kubectl apply, la requête traverse plusieurs étapes :

Flux d'une requête à travers les Admission Controllers

Les admission controllers se divisent en deux catégories qui interviennent à des moments différents du cycle de vie de la requête. Comprendre cette distinction est essentiel pour savoir quel type utiliser selon votre besoin.

TypeRôleExemple
MutatingModifie la ressource avant persistanceInjecter un sidecar, ajouter des labels
ValidatingAccepte ou refuse la ressourceBloquer les pods privileged, exiger des labels

Exemple concret : Imaginez le déploiement d'un pod. Un Mutating Admission Controller peut automatiquement ajouter un label team: backend à tous les pods créés dans un namespace donné. Ensuite, un Validating Admission Controller vérifie que ce label existe bien — si vous aviez oublié de le configurer, la mutation l'a ajouté pour vous.

Kubernetes inclut de nombreux admission controllers activés par défaut. Vous n'avez pas besoin de les installer : ils font partie de l'API Server. Leur activation se contrôle via le flag --enable-admission-plugins au démarrage de l'API Server.

Pour la certification CKS et la sécurité en production, certains contrôleurs sont particulièrement importants. Voyons lesquels et pourquoi.

Ces contrôleurs protègent votre cluster contre les configurations dangereuses et les escalades de privilèges.

ContrôleurTypeRôleActivé par défaut
PodSecurityValidatingApplique les Pod Security Standards
NodeRestrictionValidatingLimite ce que les kubelets peuvent modifier
ServiceAccountMutatingInjecte le token ServiceAccount
AlwaysPullImagesMutatingForce imagePullPolicy: Always

Pourquoi PodSecurity est-il si important ? C'est le gardien qui empêche les pods de s'exécuter avec des privilèges excessifs. Sans lui, n'importe quel développeur pourrait déployer un pod en mode privileged, avec un accès complet au nœud hôte.

Pourquoi NodeRestriction ? Ce contrôleur empêche un nœud compromis de modifier des ressources qui ne lui appartiennent pas. Par exemple, un kubelet malveillant ne peut pas modifier les pods d'un autre nœud.

Ces contrôleurs gèrent les quotas et les limites pour éviter qu'un namespace ne consomme toutes les ressources du cluster.

ContrôleurTypeRôleActivé par défaut
LimitRangerMutating + ValidatingApplique les limites par défaut
ResourceQuotaValidatingVérifie les quotas namespace
DefaultStorageClassMutatingAjoute la StorageClass par défaut

LimitRanger en action : Si vous créez un pod sans spécifier de resources.limits, LimitRanger peut automatiquement ajouter des limites par défaut définies dans un objet LimitRange. C'est une mutation qui évite les pods sans limites qui pourraient consommer toutes les ressources d'un nœud.

ResourceQuota : Ce contrôleur valide que la création d'une ressource ne dépasse pas les quotas du namespace. Si votre namespace a une limite de 10 pods et que vous essayez d'en créer un 11ème, ResourceQuota le refuse.

Fenêtre de terminal
# Contrôleurs activés sur l'API Server
kubectl get pods -n kube-system kube-apiserver-* -o yaml | \
grep -A1 "enable-admission-plugins"
# Ou via le manifest (kubeadm)
cat /etc/kubernetes/manifests/kube-apiserver.yaml | \
grep enable-admission-plugins

Le Pod Security Admission est l'admission controller qui applique les Pod Security Standards. Il est activé par défaut depuis Kubernetes 1.25.

PSA se configure via des labels sur les namespaces :

apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Niveau à appliquer
pod-security.kubernetes.io/enforce: restricted
# Version du standard (latest ou v1.xx)
pod-security.kubernetes.io/enforce-version: latest
# Mode audit (logs uniquement)
pod-security.kubernetes.io/audit: restricted
# Mode warn (affiche un warning)
pod-security.kubernetes.io/warn: restricted

Certains workloads système nécessitent des privilèges (CNI, monitoring). Exemptez-les dans la configuration :

# /etc/kubernetes/psa.yaml (fichier de config API Server)
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: "baseline"
enforce-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces:
- kube-system
- kube-node-lease

Au-delà des contrôleurs intégrés, vous pouvez créer vos propres admission controllers via des webhooks.

Refuse les ressources non conformes :

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: require-labels
webhooks:
- name: require-labels.example.com
clientConfig:
service:
name: label-validator
namespace: admission
path: /validate
caBundle: ${CA_BUNDLE}
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Fail # Refuse si le webhook est indisponible

Modifie automatiquement les ressources :

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: inject-sidecar
webhooks:
- name: inject-sidecar.example.com
clientConfig:
service:
name: sidecar-injector
namespace: admission
path: /mutate
caBundle: ${CA_BUNDLE}
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None
failurePolicy: Ignore # Accepte si le webhook est indisponible

ValidatingAdmissionPolicy (VAP) et MutatingAdmissionPolicy (MAP)

Section intitulée « ValidatingAdmissionPolicy (VAP) et MutatingAdmissionPolicy (MAP) »

Kubernetes propose désormais un duo natif de policies déclaratives en CEL, sans webhook à maintenir :

  • ValidatingAdmissionPolicy (GA depuis 1.30) — accepte ou refuse une ressource selon une expression CEL.
  • MutatingAdmissionPolicy (GA depuis 1.36) — modifie la ressource entrante (ajout de label, de securityContext par défaut, etc.) en CEL.

Avant 1.36, il fallait passer par un webhook externe (Kyverno, Gatekeeper, code maison) pour toute mutation. Désormais, la majorité des cas simples se traitent en quelques lignes de YAML.

Pourquoi utiliser VAP plutôt que des webhooks classiques ? La réponse tient en deux mots : simplicité et fiabilité.

Avec un webhook, vous devez déployer un service, gérer ses certificats TLS, assurer sa haute disponibilité, et maintenir le code. Si le webhook est down, vos déploiements peuvent être bloqués (avec failurePolicy: Fail) ou passer sans validation (avec Ignore).

VAP élimine ces problèmes : la validation s'exécute directement dans l'API Server, sans appel réseau externe.

CritèreWebhooksVAP + MAP
Dépendance externeOui (service à maintenir)Non (natif)
LatenceVariable (appel réseau)Minimale
LangageGo, Python, etc.CEL
ComplexitéÉlevéeFaible à moyenne
Validation depuis K8s1.9+1.30+ (stable)
Mutation depuis K8s1.9+1.36+ (stable)

La contrepartie ? CEL est moins flexible que du code Go ou Python. Pour des validations simples ("ce champ doit exister", "cette valeur est interdite") et des mutations simples (ajout d'un label, valeur par défaut), VAP et MAP sont parfaits. Pour de la génération de ressources (NetworkPolicy auto-créée), de la vérification de signature d'image (Cosign) ou de la logique métier complexe, les webhooks restent nécessaires.

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: deny-privileged
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: "!object.spec.containers.exists(c, c.securityContext.privileged == true)"
message: "Les conteneurs privileged sont interdits"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: deny-privileged-binding
spec:
policyName: deny-privileged
validationActions:
- Deny
matchResources:
namespaceSelector:
matchExpressions:
- key: environment
operator: In
values: ["production"]

Cette policy ajoute automatiquement le label team: platform sur tout pod créé dans le namespace ciblé.

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
name: add-team-label
spec:
failurePolicy: Fail
reinvocationPolicy: Never
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE"]
resources: ["pods"]
mutations:
- patchType: ApplyConfiguration
applyConfiguration:
expression: |
Object{
metadata: Object.metadata{
labels: {"team": "platform"}
}
}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
name: add-team-label-binding
spec:
policyName: add-team-label
matchResources:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: map-test

Le guide ValidatingAdmissionPolicy détaille les deux types patchType (ApplyConfiguration et JSONPatch) ainsi que la stratégie de déploiement progressif.

Plusieurs outils permettent d'implémenter du policy-as-code sur Kubernetes. Comment choisir ? Cela dépend de votre contexte : préparation CKS, expertise de l'équipe, besoins fonctionnels.

SolutionTypeLangageCourbe d'apprentissageCKS
Pod Security AdmissionIntégréLabelsFacile
ValidatingAdmissionPolicyIntégréCELMoyenne
MutatingAdmissionPolicy (1.36+)IntégréCELMoyenne
KyvernoAdd-onYAMLFacile⚠️
OPA GatekeeperAdd-onRegoDifficile⚠️

Comment lire ce tableau ?

  • PSA est le point de départ : activez-le sur tous vos namespaces avec au minimum le niveau baseline. C'est rapide et efficace.
  • VAP + MAP complètent PSA pour des règles personnalisées que PSA ne couvre pas (interdire certaines images, exiger des annotations, injecter un label, fixer un securityContext par défaut). Depuis 1.36 le duo couvre validation et mutation sans webhook.
  • Kyverno et Gatekeeper apportent ce que VAP+MAP ne couvrent pas : génération automatique de ressources (NetworkPolicy, Secret, ConfigMap), vérification de signatures d'images Cosign, rapports de conformité détaillés. Ils ajoutent en contrepartie de la complexité opérationnelle.
Fenêtre de terminal
# Webhooks de validation
kubectl get validatingwebhookconfigurations
# Webhooks de mutation
kubectl get mutatingwebhookconfigurations
# Détail d'un webhook
kubectl describe validatingwebhookconfiguration <name>

"connection refused" ou timeout

Le webhook n'est pas accessible. Vérifiez :

  1. Le service existe et a des endpoints
  2. Le certificat CA est correct
  3. Le NetworkPolicy autorise le trafic depuis l'API Server
Fenêtre de terminal
kubectl get endpoints -n <namespace> <service-name>
kubectl describe service -n <namespace> <service-name>

"failed to call webhook"

Le webhook retourne une erreur. Vérifiez les logs :

Fenêtre de terminal
kubectl logs -n <namespace> -l app=<webhook-app>
  • Admission Controllers : plugins qui interceptent les requêtes API avant persistance
  • Mutating (modifie) → Validating (accepte/refuse) → etcd
  • Pod Security Admission : contrôleur intégré pour les Pod Security Standards
  • ValidatingAdmissionPolicy (K8s 1.30+) et MutatingAdmissionPolicy (K8s 1.36+) : duo natif validation + mutation en CEL, sans webhook
  • Webhooks : pour la génération de ressources, la vérification de signatures et la logique métier complexe
  • CKS : focus sur PSA, VAP et MAP (natives), pas sur Kyverno/Gatekeeper

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

10 questions
8 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn