Passer au contenu principal

Expertise (Kubernetes)

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: None

OPA/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: "?*"

Sources