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.
Comment fonctionnent les Admission Controllers ?
Section intitulée « Comment fonctionnent les Admission Controllers ? »Quand vous créez une ressource avec kubectl apply, la requête traverse plusieurs étapes :
kubectl apply → API Server │ ▼ Authentication (Qui êtes-vous ?) │ ▼ Authorization (Avez-vous le droit ?) │ ▼ ┌──────────┴──────────┐ ▼ ▼ Mutating Validating Admission Admission (modifie) (accepte/refuse) │ │ └──────────┬──────────┘ ▼ etcd (persistance)Les 2 types d’admission controllers
Section intitulée « Les 2 types d’admission controllers »| Type | Rôle | Exemple |
|---|---|---|
| Mutating | Modifie la ressource avant persistance | Injecter un sidecar, ajouter des labels |
| Validating | Accepte ou refuse la ressource | Bloquer les pods privileged, exiger des labels |
Les Admission Controllers intégrés
Section intitulée « Les Admission Controllers intégrés »Kubernetes inclut de nombreux admission controllers activés par défaut. Voici les plus importants pour la sécurité :
Contrôleurs de sécurité
Section intitulée « Contrôleurs de sécurité »| Contrôleur | Type | Rôle | Activé par défaut |
|---|---|---|---|
| PodSecurity | Validating | Applique les Pod Security Standards | ✅ |
| NodeRestriction | Validating | Limite ce que les kubelets peuvent modifier | ✅ |
| ServiceAccount | Mutating | Injecte le token ServiceAccount | ✅ |
| AlwaysPullImages | Mutating | Force imagePullPolicy: Always | ❌ |
Contrôleurs de ressources
Section intitulée « Contrôleurs de ressources »| Contrôleur | Type | Rôle | Activé par défaut |
|---|---|---|---|
| LimitRanger | Mutating + Validating | Applique les limites par défaut | ✅ |
| ResourceQuota | Validating | Vérifie les quotas namespace | ✅ |
| DefaultStorageClass | Mutating | Ajoute la StorageClass par défaut | ✅ |
Voir les contrôleurs actifs
Section intitulée « Voir les contrôleurs actifs »# Contrôleurs activés sur l'API Serverkubectl 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-pluginsPod Security Admission (PSA)
Section intitulée « Pod Security Admission (PSA) »Le Pod Security Admission est l’admission controller qui applique les Pod Security Standards. Il est activé par défaut depuis Kubernetes 1.25.
Configuration
Section intitulée « Configuration »PSA se configure via des labels sur les namespaces :
apiVersion: v1kind: Namespacemetadata: 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: restrictedExemptions
Section intitulée « Exemptions »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/v1kind: AdmissionConfigurationplugins:- 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-leaseWebhooks personnalisés
Section intitulée « Webhooks personnalisés »Au-delà des contrôleurs intégrés, vous pouvez créer vos propres admission controllers via des webhooks.
ValidatingWebhookConfiguration
Section intitulée « ValidatingWebhookConfiguration »Refuse les ressources non conformes :
apiVersion: admissionregistration.k8s.io/v1kind: ValidatingWebhookConfigurationmetadata: name: require-labelswebhooks:- 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 indisponibleMutatingWebhookConfiguration
Section intitulée « MutatingWebhookConfiguration »Modifie automatiquement les ressources :
apiVersion: admissionregistration.k8s.io/v1kind: MutatingWebhookConfigurationmetadata: name: inject-sidecarwebhooks:- 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 indisponibleValidatingAdmissionPolicy (VAP)
Section intitulée « ValidatingAdmissionPolicy (VAP) »Depuis Kubernetes 1.30, ValidatingAdmissionPolicy permet de créer des politiques de validation sans webhook externe, directement avec des expressions CEL.
Avantages vs Webhooks
Section intitulée « Avantages vs Webhooks »| Critère | Webhooks | ValidatingAdmissionPolicy |
|---|---|---|
| Dépendance externe | Oui (service à maintenir) | Non (natif) |
| Latence | Variable (appel réseau) | Minimale |
| Langage | Go, Python, etc. | CEL |
| Complexité | Élevée | Faible à moyenne |
| Depuis K8s | 1.9+ | 1.30+ (stable) |
Exemple : interdire les pods privileged
Section intitulée « Exemple : interdire les pods privileged »apiVersion: admissionregistration.k8s.io/v1kind: ValidatingAdmissionPolicymetadata: name: deny-privilegedspec: 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/v1kind: ValidatingAdmissionPolicyBindingmetadata: name: deny-privileged-bindingspec: policyName: deny-privileged validationActions: - Deny matchResources: namespaceSelector: matchExpressions: - key: environment operator: In values: ["production"]Comparatif des solutions Policy-as-Code
Section intitulée « Comparatif des solutions Policy-as-Code »| Solution | Type | Langage | Courbe d’apprentissage | CKS |
|---|---|---|---|---|
| Pod Security Admission | Intégré | Labels | Facile | ✅ |
| ValidatingAdmissionPolicy | Intégré | CEL | Moyenne | ✅ |
| Kyverno | Add-on | YAML | Facile | ⚠️ |
| OPA Gatekeeper | Add-on | Rego | Difficile | ⚠️ |
Diagnostic et dépannage
Section intitulée « Diagnostic et dépannage »Voir les webhooks configurés
Section intitulée « Voir les webhooks configurés »# Webhooks de validationkubectl get validatingwebhookconfigurations
# Webhooks de mutationkubectl get mutatingwebhookconfigurations
# Détail d'un webhookkubectl describe validatingwebhookconfiguration <name>Erreurs courantes
Section intitulée « Erreurs courantes »“connection refused” ou timeout
Le webhook n’est pas accessible. Vérifiez :
- Le service existe et a des endpoints
- Le certificat CA est correct
- Le NetworkPolicy autorise le trafic depuis l’API Server
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 :
kubectl logs -n <namespace> -l app=<webhook-app>À retenir
Section intitulée « À retenir »- 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+) : validation native en CEL, sans webhook
- Webhooks : pour des cas complexes nécessitant de la logique métier
- CKS : focus sur PSA et VAP (natives), pas sur Kyverno/Gatekeeper