← Retour au blog

Tutoriel Kyverno : 3 règles Policy as Code pour sécuriser Kubernetes

14/01/2026

Chargement…

🛡️ Kubernetes : Sécurisez votre Cluster avec Kyverno et le Policy-as-Code

INTRODUCTION

La validation manuelle des manifestes YAML est non seulement fastidieuse, mais elle est surtout une source majeure d'incidents de sécurité en production. Comment garantir que personne ne déploie une image :latest ou un conteneur avec les droits root ?

La réponse réside dans le Policy as Code. Dans ce tutoriel, nous allons utiliser Kyverno, un contrôleur d'admission natif pour Kubernetes, pour automatiser la gouvernance de votre cluster. Nous déploierons ensemble trois règles de sécurité concrètes pour bloquer les configurations à risque avant même qu'elles n'atteignent vos nœuds.

Prérequis

Avant de commencer, assurez-vous d'avoir :

  • Un cluster Kubernetes actif (v1.25+ recommandée).
  • kubectl configuré avec les droits cluster-admin.
  • Helm (v3+) pour l'installation des paquets.
  • Une compréhension basique de la syntaxe YAML.

Tutoriel pas à pas

1. Installation de Kyverno

Kyverno s'installe facilement via Helm. Nous allons l'isoler dans son propre namespace pour séparer la couche de gouvernance des applications.

# 1. Ajouter le dépôt Helm officiel de Kyverno
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

# 2. Installer Kyverno (le namespace est créé automatiquement)
helm install kyverno kyverno/kyverno -n kyverno --create-namespace

# 3. Vérifier que le contrôleur est opérationnel
kubectl get pods -n kyverno

💡 Note : En production, il est recommandé d'installer Kyverno en mode haute disponibilité (HA) avec plusieurs réplicas (--set replicaCount=3).

2. Règle 1 : Interdire le tag 'latest'

L'utilisation du tag latest est un anti-pattern critique. Elle empêche la traçabilité des versions et rend les rollbacks hasardeux.

Créez le fichier disallow-latest.yaml :

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Enforce # Bloque le déploiement
  background: true
  rules:
    - name: require-image-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "⛔ L'utilisation du tag 'latest' est interdite. Veuillez spécifier une version immuable."
        pattern:
          spec:
            containers:
              - image: "!*:latest"

Appliquez la politique :

kubectl apply -f disallow-latest.yaml

Test de validation :

# Cette commande doit échouer avec un message explicite de Kyverno
kubectl run test-fail --image=nginx:latest

3. Règle 2 : Forcer le système de fichiers en lecture seule

Pour limiter la surface d'attaque en cas d'intrusion, un conteneur ne devrait pas pouvoir modifier ses propres fichiers binaires ou de configuration.

Créez le fichier require-readonly.yaml :

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-readonly-rootfs
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-readonly-rootfs
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "🔒 Le système de fichiers racine doit être en lecture seule (readOnlyRootFilesystem: true)."
        pattern:
          spec:
            containers:
              - securityContext:
                  readOnlyRootFilesystem: true

Appliquez la politique :

kubectl apply -f require-readonly.yaml

4. Règle 3 : Exiger des Probes de santé

Une application sans sondes de santé est une application que Kubernetes ne peut pas réparer automatiquement.

Créez le fichier require-probes.yaml :

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-probes
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-probes
      match:
        any:
          - resources:
              kinds:
                - Deployment
                - StatefulSet
                - DaemonSet
      validate:
        message: "🩺 Les sondes livenessProbe et readinessProbe sont obligatoires pour la HA."
        pattern:
          spec:
            template:
              spec:
                containers:
                  - livenessProbe: "?*"
                    readinessProbe: "?*"

Appliquez la politique :

kubectl apply -f require-probes.yaml

Sécurité 🔐

Installer Kyverno ne suffit pas, il faut sécuriser le gardien lui-même :

  • RBAC strict : Restreignez drastiquement les droits d'écriture sur les objets ClusterPolicy. Seuls les cluster-admin ou les équipes SecOps doivent pouvoir modifier les règles.
  • Exclusions critiques : Excluez toujours les namespaces système (kube-system, kyverno) de vos politiques globales pour éviter de "briquer" le cluster lors d'une mise à jour.
  • Secrets : Kyverno peut valider la présence de secrets, mais assurez-vous que vos règles ne loguent jamais le contenu des secrets dans les messages d'erreur.

Observabilité 📈

Intégrez Kyverno à votre stack de monitoring existante :

  • Policy Reports : Utilisez kubectl get policyreports -A pour voir un audit de conformité de votre cluster en temps réel.
  • Grafana / Prometheus : Kyverno expose des métriques natives. Importez le dashboard Grafana officiel (ID 15767) pour visualiser les refus, les erreurs et la latence.
  • Logs : Surveillez les logs du pod Kyverno, c'est souvent là que se trouvent les indices si un Webhook ne répond pas.

Tests / Validation ✅ (Shift Left)

La meilleure politique est celle qui est validée avant d'arriver sur le cluster. Intégrez le CLI Kyverno dans votre pipeline CI/CD (GitLab CI, GitHub Actions, Jenkins).

# Exemple de test local ou en CI
kyverno apply disallow-latest.yaml --resource=mon-app-deployment.yaml

Si cette commande échoue, le pipeline s'arrête. C'est le principe du "Fail Fast" : on corrige l'erreur de configuration dans le code source, pas en urgence sur la prod.

Rollback / Plan B ↩️

Une règle bloque un déploiement critique un vendredi soir ? Voici comment réagir sans tout casser :

  1. Passer en mode "Audit" : Cela désactive le blocage mais continue de loguer l'infraction.
    kubectl patch clusterpolicy disallow-latest-tag --type='json' -p='[{"op": "replace", "path": "/spec/validationFailureAction", "value": "Audit"}]'
    
  2. Suppression d'urgence : Si le patch ne passe pas, supprimez la règle temporairement.
    kubectl delete cpol disallow-latest-tag
    

Erreurs fréquentes & diagnostics

Symptôme Cause probable Solution
Impossible de supprimer un Namespace Une politique bloque la suppression des ressources contenues. Vérifiez les ClusterPolicy ciblant les Namespace et ajoutez des exclusions.
Timeout création de Pods Le Webhook Kyverno est injoignable. Vérifiez que les pods Kyverno sont Running et que le service réseau est accessible.

Checklist de mise en prod

  • Installer Kyverno en mode HA (répliques > 1).
  • Déployer les nouvelles politiques en mode Audit pendant 1 semaine pour observer l'impact.
  • Analyser les PolicyReports pour corriger l'existant.
  • Configurer les exclusions (kube-system, monitoring, etc.).
  • Ajouter kyverno apply dans la CI pour valider les Pull Requests.

FAQ

Q1. Kyverno vs OPA (Gatekeeper) : Lequel choisir ? R: Kyverno est souvent préféré par les équipes Ops car il utilise du YAML standard, contrairement à OPA qui nécessite d'apprendre le langage Rego. Kyverno est plus "Kube-native".

Q2. Quel est l'impact sur les performances ? R: Minime (quelques millisecondes). Cependant, assurez-vous d'allouer suffisamment de CPU/RAM au pod Kyverno si vous gérez un cluster avec beaucoup de mouvements (churn).

Conclusion

Vous avez désormais posé les bases d'une gouvernance solide. En automatisant ces contrôles, vous libérez du temps de cerveau pour votre équipe et garantissez que seuls des workloads conformes entrent en production.

Pour aller plus loin, commencez toujours par le mode Audit avant de passer en Enforce ! 🚀