Module 5 – Sécurité, RBAC et gouvernance

Durcissez votre cluster Kubernetes : RBAC fin, Pod Security Standards, NetworkPolicies, Kyverno et audit logging.

Passons en mode gouvernance. Kubernetes n’est pas sécurisé par défaut : à vous de limiter les permissions, d’imposer des politiques et de tracer toutes les actions.

Objectifs

  • Déléguer précisément les droits grâce à RBAC et ServiceAccounts.
  • Appliquer les Pod Security Standards et des NetworkPolicies strictes.
  • Mettre en place des garde-fous (admission controllers, policy engines) et activer l’audit.

1. ServiceAccounts et authentification

Chaque Pod utilise un ServiceAccount (SA). Par défaut, c’est default. Créez-en un dédié :

apiVersion: v1
kind: ServiceAccount
metadata:
  name: deployer
  namespace: tools

Générez un token éphémère (Kubernetes 1.24+) :

kubectl create token deployer -n tools --duration=4h

2. RBAC : Roles et RoleBindings

Attribuer uniquement les verbes nécessaires :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: tools
  name: deployer-role
rules:
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployer-binding
  namespace: tools
subjects:
  - kind: ServiceAccount
    name: deployer
    namespace: tools
roleRef:
  kind: Role
  name: deployer-role
  apiGroup: rbac.authorization.k8s.io

Testez :

kubectl auth can-i create deployments -n tools --as=system:serviceaccount:tools:deployer

3. Pod Security Standards (PSS)

Depuis la 1.25, les PodSecurityPolicies sont retirées. Kubernetes applique désormais trois profils (privileged, baseline, restricted) via des labels sur le namespace.

kubectl label namespace production pod-security.kubernetes.io/enforce=restricted
kubectl label namespace production pod-security.kubernetes.io/audit=baseline

Complétez avec un moteur de policy :

  • OPA Gatekeeper : langage Rego, flexible.
  • Kyverno : règles déclaratives YAML.

Exemple Kyverno – interdire les conteneurs root

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-run-as-nonroot
spec:
  validationFailureAction: enforce
  rules:
    - name: run-as-non-root
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "Les conteneurs doivent tourner en utilisateur non root"
        pattern:
          spec:
            containers:
              - =(securityContext):
                  runAsNonRoot: true

4. NetworkPolicies avancées

Combinez règles ingress/egress :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      role: api
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: data
          podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - ipBlock:
            cidr: 10.10.0.0/16
      ports:
        - protocol: TCP
          port: 443

Ne pas oublier la politique default deny :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

5. Admission controllers et audit

  • Activez l’audit logging (paramètres kube-apiserver) : --audit-log-path, --audit-policy-file.
  • Déployez un webhook mutating (ex. cert-manager) pour injecter des sidecars.
  • Utilisez kubectl get --raw "/api/v1/namespaces/kube-system/configmaps/audit-policy" si votre cluster expose la policy.

Exemple minimal d’audit policy :

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    verbs: ["create", "update", "patch", "delete"]
    resources:
      - group: ""
        resources: ["pods", "secrets"]

6. Lab guidé

  1. Créez les namespaces production, frontend et data (labels env=frontend, name=data).
  2. Appliquez les labels PSS (production en restricted).
  3. Déployez une application api dans production avec un ServiceAccount deployer + Role minimal.
  4. Ajoutez la NetworkPolicy deny-all puis db-egress pour autoriser uniquement PostgreSQL.
  5. Installez Kyverno (helm repo add kyverno https://kyverno.github.io/kyverno) et appliquez la policy require-run-as-nonroot. Testez un Pod sans securityContext : il doit être rejeté.
  6. Activez l’audit logging (si cluster kubeadm) et consultez le fichier /var/log/kubernetes/audit.log.

Solution détaillée

  1. RBAC
    kubectl auth can-i create deployments -n tools --as=system:serviceaccount:tools:deployeryes.
    kubectl auth can-i delete secrets -n tools --as=…no.
  2. PSS
    Créez un Pod volontairement privilégié dans production : il doit être rejeté avec un message violates PodSecurity "restricted".
  3. Kyverno
    Après installation, kubectl apply -f pod-root.yaml (pod sans runAsNonRoot) doit renvoyer forbidden by policy require-run-as-nonroot.
    kubectl get cpol require-run-as-nonroot vérifie l’état.
  4. NetworkPolicies
    Avec deny-all en place, un Pod de backend doit être bloqué (curl postgres → timeout). Après application de db-egress, seul un Pod label role=api peut sortir sur le port 5432.
  5. Audit
    Sur cluster kubeadm, vérifiez /var/log/kubernetes/audit.log. Exemple d’entrée :

    {"verb":"create","user":{"username":"system:serviceaccount:tools:deployer"},"objectRef":{"resource":"deployments","namespace":"tools"}}
    

Ces contrôles attestent que la séparation des rôles et les garde-fous fonctionnent avant de passer aux modules observabilité et GitOps.

Pièges fréquents

  • Attribuer un ClusterRoleBinding plutôt qu’un RoleBinding (accès trop large).
  • Oublier l’ordre des webhooks mutating/validating : un mutating peut modifier l’objet avant validation.
  • Déployer des NetworkPolicies sans CNI compatible (Flannel “pur” les ignore).
  • Laisser le ServiceAccount default avec un token auto-monté : désactivez automountServiceAccountToken si inutile.

Ressources

Checklist

  • ✅ Vous savez créer un ServiceAccount, un Role et un RoleBinding adaptés.
  • ✅ Vous avez mis en place Pod Security restricted et des NetworkPolicies.
  • ✅ Vous savez installer un moteur de policy (Kyverno) et vérifier qu’il bloque les manifestes non conformes.