Admission Webhooks et OPA/Gatekeeper
Les Admission Webhooks permettent d'intercepter les requêtes API avant qu'elles soient persistées dans etcd. On peut valider (MutatingAdmissionWebhook) ou rejeter (ValidatingAdmissionWebhook) n'importe quelle création ou modification d'objet. C'est le mécanisme qui permet d'imposer des politiques organisationnelles sur le cluster.
Deux types de webhooks
- MutatingAdmissionWebhook : peut modifier l'objet avant persistence (injection de sidecars, ajout de labels, complétion de valeurs par défaut)
- ValidatingAdmissionWebhook : peut accepter ou rejeter l'objet mais ne peut pas le modifier
Les webhooks sont appelés par l'API server via HTTPS. Le endpoint webhook doit être disponible depuis l'API server (dans le cluster ou externe) et présenter un certificat TLS valide.
Exemple de Validating Webhook
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-policy
webhooks:
- name: validate.pods.example.com
admissionReviewVersions: ["v1"]
clientConfig:
service:
name: webhook-service
namespace: webhook-system
path: /validate-pods
caBundle: BASE64_CA_CERT
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail # Fail (bloque si webhook unreachable) | Ignore
sideEffects: NoneOPA/Gatekeeper
OPA (Open Policy Agent) avec son intégration Kubernetes Gatekeeper est la solution standard pour la policy-as-code sur Kubernetes. Il expose un ValidatingAdmissionWebhook et permet de définir des politiques en Rego (le langage d'OPA).
# Installer Gatekeeper
helm install gatekeeper oci://registry-1.docker.io/bitnamicharts/gatekeeper --namespace gatekeeper-system --create-namespace# ConstraintTemplate : définit le type de contrainte et la logique Rego
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Labels manquants : %v", [missing])
}
---
# Constraint : instancie la règle sur des ressources spécifiques
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-team-label
spec:
match:
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment"]
namespaces: ["production"]
parameters:
labels: ["team", "app.kubernetes.io/name"]Kyverno — alternative
Kyverno est une alternative à OPA/Gatekeeper qui utilise du YAML Kubernetes natif plutôt que Rego. Moins puissant pour les politiques complexes, mais plus accessible pour les équipes sans expertise en Rego. Il gère aussi les mutations et les generates (création automatique d'objets dérivés).
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
rules:
- name: check-team-label
match:
any:
- resources:
kinds: ["Deployment"]
namespaces: ["production"]
validate:
message: "Le label 'team' est obligatoire"
pattern:
metadata:
labels:
team: "?*"