Module 3d · Sécurité¶
Objectifs
- Durcir un pod : securityContext, non-root, capabilities, lecture seule.
- Cloisonner le réseau avec les NetworkPolicies (deny par défaut).
- Aller plus loin sur le RBAC (least privilege, ServiceAccounts).
- Connaître les bonnes pratiques images/secrets et savoir auditer (
:popeye). - Durée : ~2 h · Pré-requis : Module 3c.
1. Durcir le pod — securityContext¶
Par défaut, un conteneur tourne souvent en root : à éviter.
yaml
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
containers:
- name: app
image: monapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"] # on retire tout, on rajoute le strict nécessaire
| Réglage | Pourquoi |
|---|---|
runAsNonRoot |
empêche l'exécution en root |
readOnlyRootFilesystem |
le conteneur ne peut pas se modifier (limite la persistance d'un attaquant) |
drop: ["ALL"] |
retire toutes les capabilities Linux superflues |
allowPrivilegeEscalation: false |
bloque l'escalade via setuid |
2. Cloisonner le réseau — NetworkPolicy¶
Par défaut, tout pod peut parler à tout pod. Une NetworkPolicy restreint ce trafic.
Le motif sain : tout interdire, puis autoriser au cas par cas.
```yaml
Deny par défaut tout le trafic ENTRANT du namespace¶
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress spec: podSelector: {} # tous les pods policyTypes: ["Ingress"] ```
```yaml
Puis autoriser : seuls les pods "front" peuvent joindre les pods "api" sur 8080¶
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: front-vers-api spec: podSelector: matchLabels: { app: api } ingress: - from: - podSelector: matchLabels: { app: front } ports: - port: 8080 ```
Le CNI doit supporter les NetworkPolicies
Les NetworkPolicies ne font effet que si le plugin réseau les implémente (Calico, Cilium…). Sur certains clusters de lab/vcluster, elles peuvent être ignorées silencieusement : teste toujours l'effet réel (cf. exercice).
3. RBAC — least privilege¶
Rappel du module 3, version sécurité : on donne le minimum.
- Un ServiceAccount dédié par application (jamais
default). - Un Role namespacé plutôt qu'un ClusterRole quand c'est possible.
- On vérifie toujours :
bash
kubectl auth can-i --list --as=system:serviceaccount:demo:monapp
kubectl auth can-i delete pods --as=system:serviceaccount:demo:monapp -n demo
text
:rbac ← inspecter les règles RBAC dans k9s
4. Images & secrets¶
- Images : tag fixe (pas
latest), idéalement digest, base slim/distroless. - Scanner les images (Trivy, Grype) en CI avant déploiement.
- Secrets : jamais en clair dans un manifest ; un
Secretk8s est seulement base64 (≠ chiffré) → chiffrer au repos (etcd) et/ou utiliser un gestionnaire externe (Sealed Secrets, Vault, SOPS).
5. Auditer le cluster — Popeye¶
text
:popeye ← audit : pods sans limits, en root, RBAC trop large, images en latest…
C'est l'outil idéal pour mesurer l'effet des bonnes pratiques de ce module : on audite, on corrige, on ré-audite, le score monte.
6. Exercices¶
Exercice 3d.1 — Non-root
- Déploie un nginx standard, exec dedans,
id→ tu es root. - Ajoute un
securityContextrunAsNonRoot: true+runAsUser: le pod refuse de démarrer (image nginx veut root). Comprends pourquoi, puis utilisenginxinc/nginx-unprivileged.
Exercice 3d.2 — Deny par défaut
- Déploie deux pods
frontetapi(+ Serviceapi). Vérifie quefrontjointapi(wget). - Applique
default-deny-ingress:frontne joint plusapi. - Ajoute
front-vers-api: la communication revient, uniquement depuisfront. - (Si rien ne change après le deny : ton CNI n'applique pas les NetworkPolicies — note-le.)
Exercice 3d.3 — Audit
Lance :popeye, corrige deux findings (ex. limits manquantes, image latest), ré-audite.
7. Ce qu'il faut retenir¶
- Non-root + drop capabilities + rootfs en lecture seule = base du durcissement pod.
- NetworkPolicy : deny par défaut, puis autoriser finement (si le CNI le supporte).
- RBAC = least privilege, un ServiceAccount par app, on vérifie avec
auth can-i. - Un
Secretk8s n'est pas chiffré par défaut : prévoir chiffrement/gestionnaire externe. :popeyepour mesurer et progresser.
➡️ Suite : Module 3e — GitOps avec ArgoCD