
Un ServiceAccount est l'identité Kubernetes de votre application. Chaque Pod est associé à un ServiceAccount. Lorsqu'un Pod doit appeler l'API Kubernetes, il peut utiliser les credentials montés pour ce ServiceAccount, sauf si ce montage est désactivé. Ce guide vous montre comment créer des ServiceAccounts dédiés avec les permissions minimales nécessaires.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le rôle des ServiceAccounts comme identité
- Créer un ServiceAccount dédié
- Configurer les permissions avec Role et RoleBinding
- Maîtriser les tokens projetés modernes
- Désactiver le montage de token quand inutile
- Appliquer les bonnes pratiques de sécurité
Tableau de décision rapide
Section intitulée « Tableau de décision rapide »Ce tableau donne la combinaison d'objets à retenir selon le besoin. La ligne la plus utile est la quatrième : un Pod qui n'appelle jamais l'API Kubernetes ne doit tout simplement pas recevoir de token, et c'est le cas de la majorité des applications web classiques.
| Besoin | Outil recommandé |
|---|---|
| Pod lit des ressources dans son namespace | Role + RoleBinding |
| Même permission réutilisée dans plusieurs namespaces | ClusterRole + RoleBinding (par namespace) |
| Accès réellement global au cluster | ClusterRole + ClusterRoleBinding |
| Pod n'appelle jamais l'API Kubernetes | automountServiceAccountToken: false |
| Test ponctuel d'un token | kubectl create token |
Pourquoi des ServiceAccounts dédiés ?
Section intitulée « Pourquoi des ServiceAccounts dédiés ? »Par défaut, un Pod utilise le ServiceAccount default du namespace. Ce n'est pas dangereux en soi, mais c'est rarement un bon choix pour une application de production :
| Problème | Conséquence |
|---|---|
| Identité partagée | Plusieurs workloads apparaissent sous la même identité vis-à-vis de l'API |
| Traçabilité réduite | La corrélation d'audit devient moins fine |
| Permissions héritées | Tout RoleBinding sur default s'applique à tous les Pods |
Une nuance utile pour ne pas se tromper de cible : le risque n'est pas le nom default, c'est le partage d'identité entre des workloads qui n'ont pas les mêmes besoins, et la tentation d'attacher à cette identité commune des permissions trop larges. Un RoleBinding posé sur default s'applique d'un coup à tous les Pods du namespace qui n'ont pas déclaré autre chose.
Solution : Un ServiceAccount par application (ou groupe d'applications avec le même besoin).
Créer un ServiceAccount
Section intitulée « Créer un ServiceAccount »L'objet est volontairement minimal : un nom et un namespace suffisent. Un ServiceAccount est local à son namespace, deux objets portant le même nom dans deux namespaces différents sont deux identités distinctes. À sa création il ne dispose d'aucun droit, il faudra un Role et un RoleBinding pour lui en accorder.
apiVersion: v1kind: ServiceAccountmetadata: name: app-sa namespace: mon-appOu en une ligne :
kubectl create serviceaccount app-sa -n mon-appAdoptez une convention dès le premier ServiceAccount, <app>-sa par
exemple. Ce n'est pas cosmétique : c'est ce qui rend lisible la sortie de
kubectl get rolebindings -o wide le jour où vous cherchez qui a le droit de
faire quoi.
Configurer RBAC
Section intitulée « Configurer RBAC »RBAC (Role-Based Access Control) définit ce que le ServiceAccount peut faire. Le modèle repose sur trois éléments qu'il faut relier : un sujet (ici le ServiceAccount), un ensemble de règles décrivant des actions autorisées, et un binding qui associe les deux. Kubernetes fonctionne en refus par défaut, tout ce qui n'est pas explicitement autorisé est interdit, et il n'existe aucune règle de refus à écrire.
Concepts RBAC
Section intitulée « Concepts RBAC »Quatre objets suffisent à couvrir tous les cas, et leur nom porte à confusion. Retenez que le préfixe Cluster indique la portée de l'objet, pas nécessairement celle des permissions accordées : c'est le binding choisi qui tranche.
| Ressource | Portée | Description |
|---|---|---|
| Role | Namespace | Permissions dans un namespace |
| ClusterRole | Cluster | Définition de permissions réutilisable |
| RoleBinding | Namespace | Associe Role ou ClusterRole à un sujet dans un namespace |
| ClusterRoleBinding | Cluster | Associe ClusterRole à un sujet pour tout le cluster |
Créer un Role
Section intitulée « Créer un Role »Un Role liste les permissions accordées dans un namespace :
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: pod-reader namespace: mon-apprules:- apiGroups: [""] # "" = core API group resources: ["pods"] verbs: ["get", "list", "watch"]- apiGroups: [""] resources: ["pods/log"] verbs: ["get"]Les verbes disponibles :
| Verbe | Action |
|---|---|
| get | Lire une ressource |
| list | Lister les ressources |
| watch | Observer les changements |
| create | Créer une ressource |
| update | Modifier une ressource |
| patch | Modifier partiellement |
| delete | Supprimer une ressource |
Créer un RoleBinding
Section intitulée « Créer un RoleBinding »Le RoleBinding connecte le Role au ServiceAccount :
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: read-pods namespace: mon-appsubjects:- kind: ServiceAccount name: app-sa namespace: mon-approleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.ioRéutiliser un ClusterRole dans plusieurs namespaces
Section intitulée « Réutiliser un ClusterRole dans plusieurs namespaces »Cas fréquent : vous avez besoin des mêmes permissions dans plusieurs namespaces, mais pas sur tout le cluster.
Solution : Créez un ClusterRole (définition réutilisable), puis un RoleBinding par namespace.
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: configmap-readerrules:- apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"]Puis, dans chaque namespace où c'est nécessaire :
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: app-configmap-reader namespace: namespace-asubjects:- kind: ServiceAccount name: app-sa namespace: namespace-aroleRef: kind: ClusterRole # Référence le ClusterRole name: configmap-reader apiGroup: rbac.authorization.k8s.ioCette combinaison est la plus utile des quatre, et la moins connue : une définition centrale de permissions, réutilisée sans copier-coller, mais dont la portée effective reste limitée au namespace du RoleBinding. Corriger la définition en un seul endroit corrige tous les namespaces à la fois.
Permissions vraiment cluster-wide
Section intitulée « Permissions vraiment cluster-wide »Certaines charges de travail ont besoin de voir l'ensemble du cluster : un agent de supervision qui collecte les métriques de tous les namespaces, un opérateur qui surveille ses ressources personnalisées partout. Dans ce cas seulement, le ClusterRoleBinding accorde les permissions sur la totalité du cluster, y compris les namespaces créés après le binding.
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: namespace-readerrules:- apiGroups: [""] resources: ["namespaces"] verbs: ["get", "list"]---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: app-namespace-readersubjects:- kind: ServiceAccount name: app-sa namespace: mon-approleRef: kind: ClusterRole name: namespace-reader apiGroup: rbac.authorization.k8s.ioAssocier à un Pod
Section intitulée « Associer à un Pod »Le champ serviceAccountName se déclare dans la spécification du Pod. Sur un Deployment, il se place donc dans spec.template.spec et non directement sous le spec du Deployment, confusion fréquente qui fait échouer l'application du manifeste. Si le champ est omis, Kubernetes attribue le ServiceAccount default du
namespace. Et le ServiceAccount d'un Pod existant ne se modifie pas : l'API
refuse avec un message qui énumère les rares champs mutables d'un Pod, à savoir
les images des conteneurs, activeDeadlineSeconds, les tolérations en ajout
seul et terminationGracePeriodSeconds. Changer l'identité d'un workload impose
donc de le recréer, ce qui se planifie.
apiVersion: v1kind: Podmetadata: name: mon-pod namespace: mon-appspec: serviceAccountName: app-sa containers: - name: app image: mon-image:1.0.0Pour un Deployment :
apiVersion: apps/v1kind: Deploymentmetadata: name: mon-appspec: replicas: 3 template: spec: serviceAccountName: app-sa containers: - name: app image: mon-image:1.0.0Tokens : comprendre le mécanisme moderne
Section intitulée « Tokens : comprendre le mécanisme moderne »Le token est la preuve d'identité que le Pod présente à l'API server pour être reconnu comme « ce ServiceAccount ». Sa gestion a profondément changé au fil des versions de Kubernetes : les jetons permanents stockés dans des Secrets ont cédé la place à des jetons projetés, de courte durée et renouvelés automatiquement. Comprendre cette différence évite de reproduire des pratiques devenues risquées.
Tokens projetés (bound service account tokens)
Section intitulée « Tokens projetés (bound service account tokens) »Les clusters Kubernetes modernes montent des tokens projetés et liés au Pod. Ces tokens sont :
- À durée limitée, renouvelés automatiquement avant expiration
- Audience-bound, portent une audience contrôlée (typiquement l'API server)
- Liés au Pod, invalidés si le Pod est supprimé
Structure du répertoire monté :
/var/run/secrets/kubernetes.io/serviceaccount/├── ca.crt # Certificat CA du cluster├── namespace # Namespace du Pod└── token # Token JWT (renouvelé automatiquement)Côté serveur, rien n'est pris pour argent comptant : l'API server vérifie la signature du token, son expiration, les claims d'audience, et la validité des objets auxquels il est lié. Un token présenté après suppression du Pod qui le portait est donc refusé, même s'il n'a pas encore expiré.
Créer un token manuellement
Section intitulée « Créer un token manuellement »Pour tester une identité ou intégrer un composant externe :
# Token avec durée par défaut (1h)kubectl create token app-sa -n mon-app
# Token avec durée personnaliséekubectl create token app-sa -n mon-app --duration=24hLe token créé par cette commande vit une heure par défaut, valeur
vérifiée sur le cluster de cette formation en comparant les claims iat et
exp, et son audience est l'API server lui-même,
https://kubernetes.default.svc.cluster.local.
La sortie est un JWT signé par l'API server. En décodant son header avec
base64, vous obtenez l'algorithme et l'identifiant de clé :
kubectl create token app-sa -n mon-app | cut -d. -f1 | base64 -d# {"alg":"RS256","kid":"LxkUHA9ITF5w3mg80D102dT48j1E4k1DsNIgUcHOrRg"}Le payload, deuxième segment, porte huit claims sur ce cluster : aud
(audience), iss (issuer), sub (sujet), le trio temporel iat, nbf et
exp, l'identifiant unique jti, et un bloc kubernetes.io qui rattache le
token au namespace, au ServiceAccount et, pour un token projeté, au
Pod lui-même. C'est ce dernier rattachement qui rend le token inutilisable
dès que le Pod disparaît.
Un mot sur ce qu'il ne faut pas en faire : ces tokens conviennent à un test ponctuel ou à une intégration, pas à un stockage durable. Les écrire dans un fichier, une variable d'environnement permanente ou un dépôt recrée exactement le problème que les tokens projetés ont supprimé, un secret de longue durée qu'on ne sait plus révoquer.
Signature externe via KMS (GA en Kubernetes 1.36)
Section intitulée « Signature externe via KMS (GA en Kubernetes 1.36) »Par défaut, l'API server signe les tokens ServiceAccount avec une clé
privée stockée localement (--service-account-signing-key-file). Cette clé
ne quitte jamais le control plane, mais elle reste un secret hautement
sensible : sa compromission permettrait de forger n'importe quelle identité
de pod.
Kubernetes 1.36 fait passer en GA la signature externe : l'API server délègue l'opération de signature à un service externe via un endpoint Unix domain socket. La clé privée vit alors dans un KMS (HashiCorp Vault, AWS KMS, GCP KMS, Azure Key Vault…) et n'est jamais exposée au control plane.
Architecture
Section intitulée « Architecture »L'API server ne fabrique plus la signature lui-même : il transmet la demande au service externe par une socket Unix locale et reçoit le jeton signé en retour. La clé privée reste donc chez le fournisseur de signature, et le control plane n'en détient jamais de copie.
Configurer l'API server
Section intitulée « Configurer l'API server »Sur kubeadm, ajouter dans /etc/kubernetes/manifests/kube-apiserver.yaml :
spec: containers: - name: kube-apiserver command: - kube-apiserver - --service-account-signing-endpoint=unix:///var/run/k8s-signer/signer.sock # Garder --service-account-issuer pour la cohérence des claims - --service-account-issuer=https://kubernetes.default.svc.cluster.local volumeMounts: - name: signer-socket mountPath: /var/run/k8s-signer volumes: - name: signer-socket hostPath: path: /var/run/k8s-signer type: DirectoryLe service de signature (Vault avec le plugin vault-plugin-secrets-kubernetes
ou un binaire maison conforme au protocole gRPC signing.k8s.io/v1) écoute
sur la même socket Unix.
Trois situations justifient cette complexité supplémentaire. Les architectures zero-trust, où aucun secret ne doit résider sur les nœuds. Les environnements multi-clusters qui veulent une autorité de signature unique, un seul KMS signant les tokens de plusieurs clusters. Et les contraintes de conformité, PCI-DSS, FedRAMP ou eIDAS, qui exigent des clés privées gérées par un module matériel.
Compatibilité avec les tokens existants
Section intitulée « Compatibilité avec les tokens existants »L'activation de la signature externe est transparente côté workloads : les tokens projetés montés dans les pods continuent d'avoir le même format JWT RS256, le même issuer et la même structure de claims. Seul le porteur de la clé privée change. Aucune adaptation des SDK Kubernetes (client-go, fabric8, kubernetes-python) n'est nécessaire.
Sur EKS, GKE et AKS, ce réglage ne vous concerne pas : ces plateformes exposent leur propre intégration KMS, souvent déjà active, et le flag --service-account-signing-endpoint n'est pas accessible côté client. La signature externe y est gérée par le control plane managé.
Éviter les anciens tokens en Secret
Section intitulée « Éviter les anciens tokens en Secret »Les versions antérieures de Kubernetes créaient des tokens statiques dans des Secrets de type kubernetes.io/service-account-token. Ces tokens :
- N'expirent jamais
- Restent valides même après suppression du Pod
- Sont plus difficiles à révoquer
apiVersion: v1kind: Secretmetadata: name: app-sa-token annotations: kubernetes.io/service-account.name: app-satype: kubernetes.io/service-account-tokenDésactiver le montage de token
Section intitulée « Désactiver le montage de token »Par défaut, Kubernetes monte le token du ServiceAccount dans chaque conteneur du Pod, qu'il en ait besoin ou non. Un attaquant qui obtient l'exécution de code dans le conteneur récupère donc immédiatement une identité valide auprès de l'API server. Retirer ce montage quand il est inutile est l'une des mesures les plus rentables du durcissement : coût nul, surface d'attaque réduite.
Quand désactiver ?
Section intitulée « Quand désactiver ? »La checklist sécurité Kubernetes recommande de ne pas monter de token dans les Pods qui n'en ont pas besoin. Exemples :
| Type de workload | Besoin de token ? |
|---|---|
| Frontend statique (nginx, Caddy) | ❌ Non |
| Worker applicatif pur (calcul, ML) | ❌ Non |
| Job batch sans interaction API | ❌ Non |
| Application qui lit des ConfigMaps via API | ✅ Oui |
| Opérateur Kubernetes | ✅ Oui |
| Sidecar qui contacte l'API | ✅ Oui |
Désactiver au niveau Pod
Section intitulée « Désactiver au niveau Pod »Le champ automountServiceAccountToken: false supprime le montage pour ce Pod uniquement. Le répertoire /var/run/secrets/kubernetes.io/serviceaccount/ disparaît alors du conteneur : c'est le contrôle à faire pour valider la configuration.
apiVersion: v1kind: Podmetadata: name: frontendspec: serviceAccountName: frontend-sa automountServiceAccountToken: false containers: - name: nginx image: nginx:1.30@sha256:d5792f71a9496b833bc08ea834a758c46e2b6a6306c10f4be926f38a656cdc1cDésactiver au niveau ServiceAccount
Section intitulée « Désactiver au niveau ServiceAccount »Pour définir un comportement par défaut pour tous les Pods utilisant ce ServiceAccount :
apiVersion: v1kind: ServiceAccountmetadata: name: frontend-sa namespace: mon-appautomountServiceAccountToken: falseQuand les deux niveaux déclarent ce champ, c'est la valeur du Pod qui l'emporte. La combinaison la plus sûre en découle : désactiver le montage par défaut sur le ServiceAccount, et le réactiver explicitement sur les rares Pods qui appellent vraiment l'API.
Exemple complet
Section intitulée « Exemple complet »Cette séquence assemble tout ce qui précède sur un cas réaliste : une application qui doit lire les Pods de son propre namespace. Les trois étapes se déroulent dans l'ordre, la vérification finale avec kubectl auth can-i étant la seule qui prouve réellement que le RBAC est correct. Testez toujours l'autorisation attendue et une opération qui doit échouer.
-
Créez les ressources RBAC
rbac-complet.yaml apiVersion: v1kind: ServiceAccountmetadata:name: app-sanamespace: mon-app---apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:name: pod-readernamespace: mon-apprules:- apiGroups: [""]resources: ["pods"]verbs: ["get", "list", "watch"]---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: read-podsnamespace: mon-appsubjects:- kind: ServiceAccountname: app-sanamespace: mon-approleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.ioFenêtre de terminal kubectl apply -f rbac-complet.yaml -
Déployez votre application
deployment.yaml apiVersion: apps/v1kind: Deploymentmetadata:name: mon-appnamespace: mon-appspec:replicas: 1selector:matchLabels:app: mon-apptemplate:metadata:labels:app: mon-appspec:serviceAccountName: app-sacontainers:- name: appimage: registry.k8s.io/kubectl:v1.37.0@sha256:5ed410ebac5dc976cc717098994dcdb29bbbd38f6bd65f582311f5be4ba719cfcommand: ["sleep", "3600"] -
Vérifiez les permissions
Fenêtre de terminal # Ce que le ServiceAccount peut fairekubectl auth can-i list pods \--as=system:serviceaccount:mon-app:app-sa \-n mon-app# Résultat: yes# Ce qu'il ne peut PAS fairekubectl auth can-i delete pods \--as=system:serviceaccount:mon-app:app-sa \-n mon-app# Résultat: no
Cas d'usage courants
Section intitulée « Cas d'usage courants »Ces trois blocs de règles couvrent la majorité des besoins rencontrés en développement. Ils sont classés du plus restreint au plus ciblé, et se copient tels quels dans un Role. Rappel de lecture : apiGroups: [""] désigne le groupe d'API core, celui des Pods, Services, ConfigMaps et Secrets.
Application qui lit des ConfigMaps
Section intitulée « Application qui lit des ConfigMaps »Le trio get, list, watch correspond au besoin d'un client qui recharge sa configuration à chaud. Le verbe watch est indispensable dès que l'application écoute les changements : sans lui, elle retombe en interrogation périodique.
rules:- apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch"]Opérateur qui gère des Deployments
Section intitulée « Opérateur qui gère des Deployments »Un opérateur écrit vraiment dans le cluster, ses permissions sont donc bien plus larges. La seconde règle est facile à oublier et pourtant nécessaire : sans le droit de créer des events, l'opérateur fonctionne mais ne peut plus rendre compte de ses actions dans kubectl describe.
rules:- apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]- apiGroups: [""] resources: ["events"] verbs: ["create", "patch"]Accès à des Secrets spécifiques uniquement
Section intitulée « Accès à des Secrets spécifiques uniquement »C'est la formulation à privilégier dès qu'il s'agit de Secrets : resourceNames restreint la règle à deux objets nommés, au lieu d'ouvrir la lecture de tous les Secrets du namespace. Le verbe get seul, sans list, empêche en plus d'énumérer ce qui existe.
rules:- apiGroups: [""] resources: ["secrets"] resourceNames: ["app-credentials", "db-password"] verbs: ["get"]Un détail de resourceNames mérite d'être connu avant de s'y fier. Il fonctionne bien avec get, update, patch et delete, qui désignent tous un objet précis. Avec list, la logique diffère : sans resourceNames, la règle liste tout ; avec, elle ne rend que les objets nommés. Un get seul, sans list, reste la formulation la plus stricte puisqu'elle empêche même d'énumérer ce qui existe.
Bonnes pratiques
Section intitulée « Bonnes pratiques »Les recommandations se regroupent en trois temps : nommer et organiser les identités, restreindre ce qu'elles peuvent faire, puis vérifier dans la durée que ces droits restent justifiés. Le troisième volet est le plus négligé, alors que les permissions RBAC ne font que s'accumuler si personne ne les revoit.
Organisation
Section intitulée « Organisation »Ces trois points se décident une fois pour toutes, au moment où la première identité est créée. L'annotation d'usage est celle qu'on saute le plus souvent : c'est pourtant elle qui permet, des mois plus tard, de savoir si un ServiceAccount sert encore à quelque chose avant de le supprimer.
- Un ServiceAccount par application : pas de partage entre applications différentes
- Convention de nommage,
<app>-sapour identifier facilement - Documentation : annotez vos ServiceAccounts avec leur usage
Sécurité
Section intitulée « Sécurité »Ces six règles appliquent le même principe : n'accorder que ce qui est démontré nécessaire. Le joker * dans les verbes mérite une vigilance particulière : il accorde silencieusement les nouveaux verbes introduits par les versions ultérieures de Kubernetes.
- Principe du moindre privilège : n'accordez que les permissions strictement nécessaires
- Évitez
*dans les verbes, Listez explicitement les actions autorisées - Utilisez resourceNames quand possible : limitez l'accès à des ressources spécifiques
- Préférez Role à ClusterRole : scope namespace sauf besoin cluster-wide
- Désactivez automount si inutile : réduisez la surface d'attaque
- Préférez les tokens projetés : évitez les tokens statiques en Secret
Les permissions sont accordées quand un besoin apparaît, presque jamais retirées quand il disparaît. Une revue périodique, appuyée sur kubectl auth can-i --list, est le seul moyen de repérer ces droits devenus orphelins.
- Revoyez régulièrement les permissions : les besoins évoluent
- Utilisez
kubectl auth can-i: testez ce qu'un ServiceAccount peut faire - Activez l'audit logging : tracez les actions sur l'API
Débugger RBAC
Section intitulée « Débugger RBAC »Un message Forbidden indique toujours quel sujet, quel verbe et quelle ressource ont été refusés : lisez-le en entier avant de modifier quoi que ce soit. L'option --as=system:serviceaccount:<namespace>:<nom> rejoue ensuite la question à la place du ServiceAccount, sans déployer le moindre Pod. C'est l'outil de diagnostic principal, à condition de disposer vous-même du droit d'usurpation.
# Lister toutes les permissions d'un ServiceAccountkubectl auth can-i --list \ --as=system:serviceaccount:mon-app:app-sa \ -n mon-app
# Tester une permission spécifiquekubectl auth can-i create deployments \ --as=system:serviceaccount:mon-app:app-sa \ -n mon-app
# Voir les RoleBindings d'un namespacekubectl get rolebindings -n mon-app -o wide
# Voir les ClusterRoleBindings qui concernent un ServiceAccountkubectl get clusterrolebindings -o wide | grep app-sa
# Créer un token pour testerkubectl create token app-sa -n mon-appComprendre les Admission Controllers
Section intitulée « Comprendre les Admission Controllers »Un admission controller est un module de l'API server qui inspecte une ressource après l'autorisation RBAC, et peut la modifier ou la rejeter. C'est lui qui explique les refus les plus déroutants : vous avez le droit de créer un Pod, la requête est bien authentifiée et autorisée, et pourtant elle échoue. Savoir distinguer un refus RBAC d'un refus d'admission fait gagner beaucoup de temps de diagnostic.
Ce point relève explicitement du programme CKAD, qui demande de distinguer authentification, autorisation et contrôle d'admission. La confusion coûte cher en examen comme en production : RBAC peut parfaitement autoriser votre Pod, et un admission controller le refuser juste après.
Le flux complet d'une requête API
Section intitulée « Le flux complet d'une requête API »Quand vous créez un Pod, la requête passe par 3 étapes :
Pourquoi RBAC OK ≠ Pod créé
Section intitulée « Pourquoi RBAC OK ≠ Pod créé »Le vocabulaire de l'erreur permet de trancher sans réfléchir : Forbidden signale un refus RBAC, tandis qu'un message mentionnant un webhook, PodSecurity ou un quota signale un refus d'admission. Le tableau ci-dessous illustre les quatre cas les plus courants.
| Problème | RBAC | Admission | Résultat |
|---|---|---|---|
| Pas de Role pour créer des Pods | ❌ | non atteint | Forbidden |
| Pod privilégié dans namespace restricted | ✅ | ❌ PSA | Rejected |
| ResourceQuota dépassé | ✅ | ❌ Quota | Rejected |
| Image non signée | ✅ | ❌ Policy | Rejected |
Pod Security Admission (PSA)
Section intitulée « Pod Security Admission (PSA) »PSA remplace les anciennes PodSecurityPolicies. Il applique les Pod Security Standards (PSS) au niveau namespace :
| Niveau | Ce qui est autorisé | Cas d'usage |
|---|---|---|
privileged | Tout | Pods système, debug |
baseline | Pas de privileges dangereux | Applications standards |
restricted | Configuration la plus sécurisée | Production, multi-tenant |
# Vérifier le niveau PSA d'un namespacekubectl get namespace mon-app -o yaml | grep pod-securitySi votre Pod est refusé avec une erreur mentionnant pod-security.kubernetes.io, c'est PSA qui bloque.
Diagnostiquer un refus Admission
Section intitulée « Diagnostiquer un refus Admission »Le message de rejet remonte directement quand vous créez le Pod à la main. Créé par un Deployment ou un Job, le Pod n'existe jamais et l'erreur se lit alors dans les événements de l'objet parent, ce qui explique l'impression trompeuse d'un déploiement « bloqué sans raison ».
# L'erreur apparaît dans le message de rejetkubectl apply -f pod.yaml# Error: admission webhook "validate.policy" denied the request...
# Ou via describe sur le parent (Deployment, Job...)kubectl describe deployment mon-app -n mon-namespace# Events:# Warning FailedCreate ... violates PodSecurity "restricted:latest"Ce que le développeur doit savoir
Section intitulée « Ce que le développeur doit savoir »Ces quatre contrôleurs sont configurés par l'équipe plateforme, pas par vous. Votre marge d'action consiste à connaître les contraintes qu'ils imposent et à écrire des manifestes qui les respectent dès le départ, plutôt qu'à découvrir chaque règle par un rejet.
| Admission Controller | Ce qu'il vérifie | Comment s'adapter |
|---|---|---|
| PSA | Privileges, capabilities, volumes | Respecter les Pod Security Standards |
| ResourceQuota | CPU/mémoire du namespace | Vérifier les quotas disponibles |
| LimitRange | Requests/limits par Pod | Définir requests/limits conformes |
| ValidatingWebhook | Règles custom (Kyverno, Gatekeeper) | Consulter les policies actives |
Trois réflexes quand un Pod est rejeté sans que RBAC soit en cause. Regardez les labels PSA du namespace avec kubectl get ns <ns> --show-labels, puis les ResourceQuotas avec kubectl describe quota -n <ns>, et demandez enfin à votre équipe plateforme la liste des policies actives, que rien ne permet de deviner depuis un manifeste.
À retenir
Section intitulée « À retenir »| Concept | Utilisation |
|---|---|
| ServiceAccount | Identité d'un workload dans Kubernetes |
| Role | Permissions dans un namespace |
| ClusterRole | Définition de permissions réutilisable |
| RoleBinding | Associe un rôle à un sujet dans un namespace |
| ClusterRoleBinding | Associe un rôle à un sujet pour tout le cluster |
serviceAccountName | Spécifie l'identité du Pod |
automountServiceAccountToken | Contrôle le montage du token |
kubectl create token | Crée un token ponctuel pour tests |
Règle d'or : Le ServiceAccount est une identité, les permissions viennent de RBAC, et le token ne doit être monté que lorsqu'il y a un vrai besoin.
Testez vos connaissances
Section intitulée « Testez vos connaissances »Ce quiz reprend les distinctions qui posent le plus de difficultés : identité contre permissions, ClusterRole contre ClusterRoleBinding, et les conditions dans lesquelles un token doit être monté.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Pour aller plus loin
Section intitulée « Pour aller plus loin »- CIS Benchmark : Mesurer le durcissement du cluster qui exécute vos ServiceAccounts.
- Pod Security Standards : Encadrer les privilèges des Pods au niveau du namespace.