
Gatekeeper est le projet Kubernetes construit autour d’OPA (Open Policy Agent), moteur de policy-as-code CNCF Graduated. Il utilise le langage Rego pour définir des policies complexes via un modèle ConstraintTemplate + Constraint. C’est un outil mature et largement adopté par les équipes déjà familières avec l’écosystème OPA.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Quand choisir Gatekeeper vs VAP vs Kyverno
- Comprendre le modèle ConstraintTemplate + Constraint
- Écrire des policies Rego orientées sécurité (privileged, hostPath, runAsNonRoot)
- Utiliser gator pour tester localement
- Diagnostiquer un rejet d’admission (Gatekeeper vs PSA vs RBAC)
Quand choisir Gatekeeper
Section intitulée « Quand choisir Gatekeeper »Gatekeeper n’est pas toujours le bon choix. Avant d’investir du temps dans l’apprentissage de Rego, posez-vous les bonnes questions. Ce tableau compare les trois approches principales selon des critères concrets.
| Critère | VAP | Kyverno | Gatekeeper |
|---|---|---|---|
| Langage | CEL (natif K8s) | YAML | Rego |
| Composant externe | Non | Oui (webhook) | Oui (webhook) |
| Courbe d’apprentissage | Faible | Faible | Élevée |
| Logique complexe | Limitée | Moyenne | Très riche |
| Audit ressources existantes | Non | PolicyReports | Intégré |
| Mutation | Beta (1.34) | ✅ | ✅ |
| Génération de ressources | Non | ✅ | Non |
| Écosystème OPA existant | Non | Non | Oui |
| Maturité CNCF | Natif K8s | Incubating | Graduated (OPA) |
Résumé en une phrase : Choisissez VAP si vous voulez rester natif, Kyverno pour sa simplicité YAML, ou Gatekeeper si vous avez déjà un écosystème OPA/Rego.
Quand utiliser Gatekeeper
Section intitulée « Quand utiliser Gatekeeper »Voici les scénarios où Gatekeeper a un avantage clair :
- Vous utilisez déjà OPA ailleurs (Terraform, CI/CD, APIs)
- Votre équipe maîtrise Rego
- Vous avez besoin de logique complexe (références croisées, calculs, ensembles)
- Vous voulez un audit intégré des ressources existantes
- Vous avez une librairie de policies Rego à réutiliser
Quand NE PAS utiliser Gatekeeper
Section intitulée « Quand NE PAS utiliser Gatekeeper »À l’inverse, ces situations suggèrent un autre outil :
- Vous débutez en policy-as-code → VAP ou Kyverno
- Vous voulez éviter un composant externe → VAP
- Vous avez besoin de générer des ressources → Kyverno
- L’équipe préfère rester en YAML pur → Kyverno
Architecture Gatekeeper
Section intitulée « Architecture Gatekeeper »Analogie : ConstraintTemplate = classe, Constraint = instance de cette classe.
Installation
Section intitulée « Installation »kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/v3.22.0/deploy/gatekeeper.yamlhelm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/chartshelm install gatekeeper gatekeeper/gatekeeper \ --namespace gatekeeper-system \ --create-namespace \ --set replicas=3 \ --set audit.replicas=1Vérifier l’installation :
kubectl get pods -n gatekeeper-systemNAME READY STATUS RESTARTS AGEgatekeeper-audit-5c4b5d897d-x7bmt 1/1 Running 0 42sgatekeeper-controller-manager-6958bc4b76-6bhq2 1/1 Running 0 42sgatekeeper-controller-manager-6958bc4b76-cjtk2 1/1 Running 0 42sgatekeeper-controller-manager-6958bc4b76-sjhdf 1/1 Running 0 42sAprès l’installation, vous verrez deux types de pods. Comprendre leur rôle est essentiel pour le dépannage.
| Composant | Rôle | Réplicas |
|---|---|---|
controller-manager | Webhook d’admission — intercepte et valide les requêtes | 3 (HA) |
audit | Scan périodique des ressources existantes | 1 |
Pourquoi 3 réplicas pour le controller-manager ? C’est un composant critique sur le chemin de l’API Server. Si un seul pod est down, les requières d’admission pourraient échouer. Avec 3 réplicas, vous avez de la haute disponibilité.
Le pod audit scanne les ressources existantes pour détecter les violations. Même si une ressource a été créée avant l’installation de Gatekeeper, l’audit la trouvera.
Exemple 1 : refuser privileged (rentable CKS)
Section intitulée « Exemple 1 : refuser privileged (rentable CKS) »Cet exemple est le plus rentable pour la CKS : refuser les conteneurs en mode privileged est un contrôle fondamental.
apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8sdenyprivilegedspec: crd: spec: names: kind: K8sDenyPrivileged targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sdenyprivileged
violation[{"msg": msg}] { container := input.review.object.spec.containers[_] container.securityContext.privileged == true msg := sprintf("Conteneur '%v' en mode privileged interdit", [container.name]) }
violation[{"msg": msg}] { container := input.review.object.spec.initContainers[_] container.securityContext.privileged == true msg := sprintf("InitContainer '%v' en mode privileged interdit", [container.name]) }apiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sDenyPrivilegedmetadata: name: deny-privileged-containersspec: enforcementAction: deny match: kinds: - apiGroups: [""] kinds: ["Pod"] excludedNamespaces: - kube-system - gatekeeper-systemExemple 2 : securityContext complet (runAsNonRoot + readOnlyRootFilesystem)
Section intitulée « Exemple 2 : securityContext complet (runAsNonRoot + readOnlyRootFilesystem) »Pour la CKS, imposer un securityContext sécurisé est encore plus pertinent :
apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8ssecuritycontextcompletespec: crd: spec: names: kind: K8sSecurityContextComplete targets: - target: admission.k8s.gatekeeper.sh rego: | package k8ssecuritycontextcomplete
# Vérifie runAsNonRoot violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.securityContext.runAsNonRoot == true msg := sprintf("Conteneur '%v' doit avoir runAsNonRoot: true", [container.name]) }
# Vérifie allowPrivilegeEscalation violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.securityContext.allowPrivilegeEscalation == false msg := sprintf("Conteneur '%v' doit avoir allowPrivilegeEscalation: false", [container.name]) }
# Vérifie readOnlyRootFilesystem violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not container.securityContext.readOnlyRootFilesystem == true msg := sprintf("Conteneur '%v' doit avoir readOnlyRootFilesystem: true", [container.name]) }Exemple 3 : refuser hostPath (isolation filesystem)
Section intitulée « Exemple 3 : refuser hostPath (isolation filesystem) »apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8sdenyhostpathspec: crd: spec: names: kind: K8sDenyHostPath targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sdenyhostpath
violation[{"msg": msg}] { volume := input.review.object.spec.volumes[_] volume.hostPath msg := sprintf("Volume hostPath '%v' interdit", [volume.name]) }Exemple 4 : registries autorisées (Supply Chain)
Section intitulée « Exemple 4 : registries autorisées (Supply Chain) »apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8sallowedregistriesspec: crd: spec: names: kind: K8sAllowedRegistries validation: openAPIV3Schema: type: object properties: registries: type: array items: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8sallowedregistries
violation[{"msg": msg}] { container := input.review.object.spec.containers[_] not registry_allowed(container.image) msg := sprintf("Image '%v' provient d'un registry non autorisé", [container.image]) }
registry_allowed(image) { registry := input.parameters.registries[_] startswith(image, registry) }Constraint associé :
apiVersion: constraints.gatekeeper.sh/v1beta1kind: K8sAllowedRegistriesmetadata: name: only-trusted-registriesspec: enforcementAction: deny match: kinds: - apiGroups: [""] kinds: ["Pod"] parameters: registries: - "gcr.io/my-project/" - "registry.internal.company.com/"Pod Security Standards avec Gatekeeper
Section intitulée « Pod Security Standards avec Gatekeeper »La librairie officielle Gatekeeper a une section dédiée aux Pod Security Standards. Pour la CKS, c’est l’angle le plus fort de Gatekeeper.
# Installer les templates Pod Security Standardskubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/privileged-containers/template.yamlkubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/host-network-ports/template.yamlkubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/allowed-users/template.yaml| Template PSS | Description | Équivalent PSA |
|---|---|---|
K8sPSPPrivilegedContainer | Interdit privileged | Baseline/Restricted |
K8sPSPHostNetworkingPorts | Contrôle hostNetwork/hostPort | Baseline/Restricted |
K8sPSPAllowedUsers | Restreint UID/GID | Restricted |
K8sPSPCapabilities | Contrôle les capabilities | Restricted |
K8sPSPHostFilesystem | Restreint hostPath | Baseline |
Ces templates permettent d’implémenter les mêmes contrôles que PSA, mais avec plus de flexibilité. Par exemple, vous pouvez autoriser hostPath pour certains namespaces seulement, ce que PSA ne permet pas.
Gatekeeper peut ainsi compléter PSA pour des règles spécifiques non couvertes, ou l’implémenter complètement si vous avez besoin de plus de flexibilité.
enforcementAction : déploiement progressif
Section intitulée « enforcementAction : déploiement progressif »Déployer une policy directement en mode bloquant est risqué. Gatekeeper offre trois modes d’enforcement pour une adoption progressive et sécurisée.
| Valeur | Comportement | Phase |
|---|---|---|
dryrun | Accepte, enregistre dans status | Découverte |
warn | Accepte, affiche warning | Sensibilisation |
deny | Bloque la requête | Production |
Comment utiliser ces modes ?
- Démarrez avec
dryrun: Les violations sont enregistrées dans le champstatusde la Constraint, mais aucune requête n’est bloquée. Lancez l’audit pour voir les ressources existantes non conformes. - Passez à
warn: Les développeurs voient des warnings lors de leurs déploiements, mais peuvent continuer. Cela les sensibilise avant le blocage. - Activez
deny: Une fois tous les workloads corrects, passez au blocage effectif.
spec: enforcementAction: dryrun # Étape 1 : découverte # enforcementAction: warn # Étape 2 : alerter # enforcementAction: deny # Étape 3 : enforcementAudit : conformité des ressources existantes
Section intitulée « Audit : conformité des ressources existantes »Gatekeeper scanne périodiquement les ressources déjà déployées :
# Voir les violations détectées par l'auditkubectl get k8sdenyprivileged deny-privileged-containers -o yamlstatus: auditTimestamp: "2026-03-24T10:30:00Z" totalViolations: 2 violations: - enforcementAction: deny kind: Pod message: "Conteneur 'debug' en mode privileged interdit" name: debug-pod namespace: productionTester localement avec gator
Section intitulée « Tester localement avec gator »# Installer gatorbrew install gator
# Tester un template + constraint contre une ressourcegator test \ --filename template.yaml \ --filename constraint.yaml \ --filename pod-to-test.yaml
# Vérifier la syntaxe Rego d'un templategator verify --filename template.yamlDepuis v3.22+, gator policy ajoute même une gestion “brew-like” de la policy library :
# Installer des policies depuis la librairiegator policy install privileged-containersDiagnostiquer un rejet d’admission
Section intitulée « Diagnostiquer un rejet d’admission »Un Pod refusé peut l’être par plusieurs mécanismes. Avant de supposer que Gatekeeper est la cause, vérifiez systématiquement ces sources possibles. Le message d’erreur vous indique généralement la source.
| Message / Indice | Source probable | Commande de diagnostic |
|---|---|---|
admission webhook "validation.gatekeeper.sh" denied | Gatekeeper | kubectl get constraints |
violates PodSecurity | PSA | kubectl get ns -o yaml (labels) |
exceeded quota | ResourceQuota | kubectl describe quota |
forbidden: User cannot | RBAC | kubectl auth can-i |
admission webhook "..." denied (autre) | Autre webhook | kubectl get validatingwebhookconfigurations |
Commandes de diagnostic Gatekeeper
Section intitulée « Commandes de diagnostic Gatekeeper »# Lister tous les webhookskubectl get validatingwebhookconfigurations
# Lister les ConstraintTemplateskubectl get constrainttemplates
# Lister tous les Constraints actifskubectl get constraints
# Détails d'un Constraint (violations, status)kubectl describe k8sdenyprivileged deny-privileged-containers
# Logs du controller (rejets récents)kubectl logs -l control-plane=controller-manager -n gatekeeper-system --tail=50
# Logs d'audit (violations ressources existantes)kubectl logs -l control-plane=audit-controller -n gatekeeper-system --tail=50En cas d’urgence
Section intitulée « En cas d’urgence »Si Gatekeeper bloque des déploiements critiques :
# Option 1 : passer le Constraint en dryrunkubectl patch k8sdenyprivileged deny-privileged-containers \ --type='merge' -p '{"spec":{"enforcementAction":"dryrun"}}'
# Option 2 : désactiver le webhook temporairementkubectl delete validatingwebhookconfiguration gatekeeper-validating-webhook-configuration
# ⚠️ Penser à le réactiver après résolutionMutation avec Gatekeeper
Section intitulée « Mutation avec Gatekeeper »Gatekeeper supporte la mutation (stable depuis v3.10+). Ce guide se concentre sur la validation, mais voici un exemple minimal :
apiVersion: mutations.gatekeeper.sh/v1kind: Assignmetadata: name: add-default-security-contextspec: applyTo: - groups: [""] kinds: ["Pod"] versions: ["v1"] match: scope: Namespaced location: "spec.containers[name:*].securityContext.runAsNonRoot" parameters: assign: value: truePour un guide complet sur la mutation Gatekeeper, voir la documentation officielle.
Bonnes pratiques
Section intitulée « Bonnes pratiques »Sécurité
Section intitulée « Sécurité »- Excluez les namespaces système (kube-system, gatekeeper-system) pour éviter de bloquer le cluster
- Commencez en dryrun avant
deny— découvrez les violations sans impact - Limitez le scope avec
match.namespacespour les performances
Opérationnel
Section intitulée « Opérationnel »- Réutilisez la librairie avant de créer des templates custom
- Testez avec gator localement avant de déployer
- Surveillez l’audit pour la conformité continue
- Documentez vos Constraints — le Rego n’est pas lisible par tous
Performance
Section intitulée « Performance »À retenir
Section intitulée « À retenir »- Gatekeeper = OPA pour Kubernetes, basé sur le moteur CNCF Graduated OPA
- Modèle à 2 niveaux : ConstraintTemplate (logique Rego) + Constraint (application)
- Rego : puissant pour la logique complexe, mais courbe d’apprentissage
- Audit intégré pour scanner les ressources existantes — avantage unique
- gator pour tester localement (pas
opa eval) - Librairie PSS pour implémenter les Pod Security Standards
- Admission webhook : composant critique, tester hors production
- v3.22+ intègre VAP : Gatekeeper peut cohabiter avec les policies natives