
Le Security Context définit les privilèges et restrictions d’exécution pour vos Pods et conteneurs. Il contrôle l’identité d’exécution, les capabilities Linux, l’accès au système de fichiers et les restrictions de privilèges. C’est votre outil principal pour appliquer le principe du moindre privilège au niveau des workloads Kubernetes.
Ce guide couvre les paramètres essentiels pour la CKAD et les bonnes pratiques de production.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Ce qu’est un Security Context et où il s’applique (Pod vs conteneur)
- Contrôler l’identité d’exécution avec runAsUser, runAsGroup, runAsNonRoot, supplementalGroups
- Gérer les capabilities Linux (add/drop)
- Protéger le filesystem avec readOnlyRootFilesystem et fsGroup
- Bloquer l’escalade de privilèges avec allowPrivilegeEscalation
Qu’est-ce qu’un Security Context ?
Section intitulée « Qu’est-ce qu’un Security Context ? »Un Security Context est un ensemble de paramètres de sécurité qui définissent les privilèges et restrictions d’un Pod ou d’un conteneur :
| Ce que ça contrôle | Exemples de paramètres |
|---|---|
| Identité d’exécution | runAsUser, runAsGroup, runAsNonRoot, supplementalGroups |
| Capabilities Linux | capabilities.add, capabilities.drop |
| Accès filesystem | readOnlyRootFilesystem, fsGroup |
| Escalade de privilèges | allowPrivilegeEscalation, privileged |
| Profils de sécurité | seccompProfile, seLinuxOptions, procMount |
Pod Security Context vs Container Security Context
Section intitulée « Pod Security Context vs Container Security Context »apiVersion: v1kind: Podmetadata: name: security-demospec: # ─── Security Context au niveau POD ─── securityContext: runAsUser: 1000 # UID pour tous les conteneurs runAsGroup: 3000 # GID pour tous les conteneurs fsGroup: 2000 # GID pour les volumes montés supplementalGroups: # Groupes secondaires - 4000 - 5000
containers: - name: app image: nginx:1.28 # ─── Security Context au niveau CONTENEUR ─── securityContext: runAsNonRoot: true # Refuse démarrage si root readOnlyRootFilesystem: true # Filesystem en lecture seule allowPrivilegeEscalation: false # Bloque setuid/setgid capabilities: drop: - ALL add: - NET_BIND_SERVICERègle de priorité
Section intitulée « Règle de priorité »| Paramètre défini au niveau… | Comportement |
|---|---|
| Pod uniquement | S’applique à tous les conteneurs |
| Conteneur uniquement | S’applique à ce conteneur |
| Pod ET conteneur | La valeur du conteneur écrase celle du Pod |
Contrôler l’identité d’exécution
Section intitulée « Contrôler l’identité d’exécution »runAsUser et runAsGroup
Section intitulée « runAsUser et runAsGroup »Ces paramètres définissent l’UID et le GID sous lesquels le processus principal du conteneur s’exécute :
apiVersion: v1kind: Podmetadata: name: user-demospec: securityContext: runAsUser: 1000 # UID 1000 (non-root) runAsGroup: 3000 # GID 3000 containers: - name: app image: busybox:1.36 command: ["sh", "-c", "id && sleep 3600"]Vérification :
kubectl apply -f user-demo.yamlkubectl logs user-demo# uid=1000 gid=3000 groups=3000runAsNonRoot
Section intitulée « runAsNonRoot »Ce paramètre demande à Kubernetes de refuser le démarrage si le conteneur s’exécuterait en root :
spec: containers: - name: app image: nginx:1.28 securityContext: runAsNonRoot: truesupplementalGroups
Section intitulée « supplementalGroups »Ce paramètre définit les groupes secondaires ajoutés à tous les processus des conteneurs du Pod :
apiVersion: v1kind: Podmetadata: name: groups-demospec: securityContext: runAsUser: 1000 runAsGroup: 1000 supplementalGroups: - 4000 # Groupe pour accéder à certains fichiers - 5000 # Groupe pour accéder à d'autres ressources containers: - name: app image: busybox:1.36 command: ["sh", "-c", "id && sleep 3600"]Vérification :
kubectl logs groups-demo# uid=1000 gid=1000 groups=1000,4000,5000| Paramètre | Rôle |
|---|---|
runAsGroup | Groupe principal du processus |
fsGroup | Groupe propriétaire des volumes montés |
supplementalGroups | Groupes secondaires du processus |
Exemple complet identité
Section intitulée « Exemple complet identité »apiVersion: v1kind: Podmetadata: name: secure-userspec: securityContext: runAsUser: 1000 runAsGroup: 1000 runAsNonRoot: true supplementalGroups: [4000] containers: - name: app image: nginx:1.28 securityContext: allowPrivilegeEscalation: falseProtéger le filesystem et les volumes
Section intitulée « Protéger le filesystem et les volumes »readOnlyRootFilesystem
Section intitulée « readOnlyRootFilesystem »Ce paramètre rend le système de fichiers racine du conteneur en lecture seule :
apiVersion: v1kind: Podmetadata: name: readonly-demospec: containers: - name: app image: nginx:1.28 securityContext: readOnlyRootFilesystem: true volumeMounts: - name: tmp mountPath: /tmp - name: cache mountPath: /var/cache/nginx - name: run mountPath: /var/run volumes: - name: tmp emptyDir: {} - name: cache emptyDir: {} - name: run emptyDir: {}Le paramètre fsGroup définit le GID propriétaire des volumes montés :
apiVersion: v1kind: Podmetadata: name: fsgroup-demospec: securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 2000 # Les fichiers des volumes appartiennent au groupe 2000 containers: - name: app image: busybox:1.36 command: ["sh", "-c", "ls -la /data && sleep 3600"] volumeMounts: - name: data mountPath: /data volumes: - name: data emptyDir: {}Vérification :
kubectl logs fsgroup-demo# drwxrwsrwx 2 root 2000 4096 Mar 22 10:00 .Le dossier /data appartient au groupe 2000, et le bit setgid (s) est activé.
Contrôler les privilèges
Section intitulée « Contrôler les privilèges »allowPrivilegeEscalation
Section intitulée « allowPrivilegeEscalation »Ce paramètre contrôle si un processus peut obtenir plus de privilèges que son parent (via setuid/setgid binaries) :
spec: containers: - name: app image: nginx:1.28 securityContext: allowPrivilegeEscalation: falsecapabilities
Section intitulée « capabilities »Les capabilities sont des permissions granulaires qui remplacent le modèle binaire “root ou pas root”. Au lieu de donner tous les droits root, vous accordez uniquement les capabilities nécessaires.
Capabilities courantes
Section intitulée « Capabilities courantes »| Capability | Ce qu’elle permet |
|---|---|
NET_BIND_SERVICE | Écouter sur un port < 1024 |
NET_RAW | Créer des raw sockets (ping, tcpdump) |
SYS_PTRACE | Tracer des processus (debug) |
CHOWN | Changer le propriétaire des fichiers |
SETUID / SETGID | Changer d’identité (escalade potentielle) |
DAC_OVERRIDE | Ignorer les permissions de fichiers |
Drop ALL + add spécifique
Section intitulée « Drop ALL + add spécifique »La bonne pratique est de supprimer toutes les capabilities puis d’ajouter uniquement celles nécessaires :
apiVersion: v1kind: Podmetadata: name: cap-demospec: containers: - name: app image: nginx:1.28 securityContext: capabilities: drop: - ALL add: - NET_BIND_SERVICE # Nginx écoute sur port 80Vérification des capabilities actives :
kubectl exec -it cap-demo -- cat /proc/1/status | grep Cap# CapPrm: 0000000000000400# CapEff: 0000000000000400privileged (à éviter absolument)
Section intitulée « privileged (à éviter absolument) »Le mode privileged: true désactive une grande partie de l’isolation habituelle du conteneur :
# ⚠️ NE JAMAIS FAIRE EN PRODUCTIONspec: containers: - name: dangerous image: busybox securityContext: privileged: true # Désactive l'isolation conteneurProfils de sécurité complémentaires
Section intitulée « Profils de sécurité complémentaires »seccompProfile
Section intitulée « seccompProfile »Le profil Seccomp limite les appels système (syscalls) qu’un conteneur peut effectuer :
spec: securityContext: seccompProfile: type: RuntimeDefault # Utilise le profil par défaut du runtime| Type | Description |
|---|---|
RuntimeDefault | Profil par défaut du runtime (recommandé) |
Unconfined | Pas de restriction (déconseillé) |
Localhost | Profil personnalisé sur le nœud |
seLinuxOptions
Section intitulée « seLinuxOptions »Pour les clusters avec SELinux activé (RHEL, OpenShift) :
spec: securityContext: seLinuxOptions: level: "s0:c123,c456"procMount
Section intitulée « procMount »Le paramètre procMount contrôle comment /proc est monté dans le conteneur. Par défaut, /proc est masqué partiellement pour la sécurité. Les Pod Security Standards contraignent ce paramètre au niveau Baseline et Restricted.
Template de départ pour la production
Section intitulée « Template de départ pour la production »Voici un template de Security Context comme point de départ pour les workloads de production :
apiVersion: v1kind: Podmetadata: name: production-securespec: securityContext: runAsUser: 1000 runAsGroup: 1000 runAsNonRoot: true fsGroup: 1000 seccompProfile: type: RuntimeDefault
containers: - name: app image: myapp:1.0.0 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: memory: "64Mi" cpu: "100m" limits: memory: "128Mi" cpu: "500m" volumeMounts: - name: tmp mountPath: /tmp
volumes: - name: tmp emptyDir: {}Checklist de sécurité
Section intitulée « Checklist de sécurité »| Paramètre | Valeur recommandée | Pourquoi |
|---|---|---|
runAsNonRoot | true | Refuse le démarrage si root |
runAsUser | >= 1000 | UID non-root explicite |
allowPrivilegeEscalation | false | Bloque setuid/setgid (à définir explicitement) |
readOnlyRootFilesystem | true | Empêche l’écriture non contrôlée |
capabilities.drop | ALL | Supprime toutes les capabilities |
privileged | false (ou absent) | Jamais true en production |
seccompProfile | RuntimeDefault | Limite les syscalls autorisés |
Relation avec Pod Security Standards
Section intitulée « Relation avec Pod Security Standards »Les Pod Security Standards (PSS) définissent trois niveaux de restriction :
| Niveau | Ce qui est autorisé |
|---|---|
| Privileged | Tout — aucune restriction |
| Baseline | Restrictions minimales — pas de privileged, pas de hostNetwork, procMount limité |
| Restricted | Hardening complet — ensemble plus large de contraintes |
Tester la configuration
Section intitulée « Tester la configuration »Commande rapide CKAD
Section intitulée « Commande rapide CKAD »Générez un Pod avec Security Context :
# Créer un Pod de basekubectl run secure-test --image=nginx:1.28 \ --dry-run=client -o yaml > secure-pod.yaml
# Éditer pour ajouter le securityContextVérifier l’utilisateur effectif
Section intitulée « Vérifier l’utilisateur effectif »kubectl exec -it secure-test -- id# uid=1000 gid=1000 groups=1000Vérifier les capabilities
Section intitulée « Vérifier les capabilities »kubectl exec -it secure-test -- cat /proc/1/status | grep -i capVérifier readOnlyRootFilesystem
Section intitulée « Vérifier readOnlyRootFilesystem »kubectl exec -it secure-test -- touch /test.txt# touch: /test.txt: Read-only file systemDépannage
Section intitulée « Dépannage »Problèmes courants
Section intitulée « Problèmes courants »| Symptôme | Cause probable | Solution |
|---|---|---|
Error: container has runAsNonRoot and image will run as root | Image définit USER 0, ou Kubernetes ne peut pas valider | Ajouter runAsUser: 1000 explicitement |
| Pod ne démarre pas, permission denied | runAsUser incompatible avec l’image | Vérifier l’UID attendu par l’image |
| Application ne peut pas écrire | readOnlyRootFilesystem: true | Monter des emptyDir pour les dossiers d’écriture |
| Bind port 80 échoue | capabilities.drop: ALL | Ajouter NET_BIND_SERVICE ou utiliser port > 1024 |
| Fichiers volumes non accessibles | fsGroup non supporté par le volume | Vérifier la compatibilité du backend de stockage |
Debug avec kubectl
Section intitulée « Debug avec kubectl »# Voir les événementskubectl describe pod <pod-name>
# Vérifier les paramètres de sécurité appliquéskubectl get pod <pod-name> -o yaml | grep -A 20 securityContext
# Tester interactivementkubectl run debug --image=busybox --rm -it -- shÀ retenir pour la CKAD
Section intitulée « À retenir pour la CKAD »Pour l’examen CKAD, maîtrisez ces paramètres essentiels :
- runAsNonRoot: true — refuse le démarrage si Kubernetes ne peut pas valider un utilisateur non-root
- runAsUser: 1000 — définit explicitement l’UID (souvent requis avec runAsNonRoot)
- allowPrivilegeEscalation: false — à définir explicitement pour bloquer les escalades
- capabilities.drop: [ALL] — supprime toutes les capabilities, puis
addsi nécessaire - readOnlyRootFilesystem: true — avec des emptyDir pour les dossiers d’écriture
Différence Pod vs conteneur : les valeurs conteneur écrasent les valeurs Pod.
À retenir pour la production
Section intitulée « À retenir pour la production »Au-delà de la CKAD, ajoutez ces pratiques :
- seccompProfile: RuntimeDefault — limite les syscalls autorisés
- supplementalGroups — pour les accès à des groupes secondaires
- fsGroup avec vérification — testez la compatibilité avec vos volumes
- Combinaison avec PSS/PSA — appliquez les standards au niveau namespace
- Test des images — vérifiez que l’image supporte vraiment vos contraintes