Introduction
Le contrôle d'accès basé sur les rôles (RBAC) de Kubernetes est un mécanisme de sécurité central qui régule l'accès aux ressources du cluster. Parmi ses composants, ClusterRole et ClusterRoleBinding sont essentiels pour octroyer des permissions qui s'étendent à l'ensemble du cluster ou à plusieurs espaces de noms. Comprendre l'architecture ClusterRole est crucial pour les développeurs, consultants DevOps et équipes techniques de startups qui doivent appliquer le principe du moindre privilège et résoudre les échecs d'autorisation.
Cet article explique l'architecture ClusterRole de Kubernetes avec des exemples pratiques. Il couvre les composants de base, l'interaction entre ClusterRole et ClusterRoleBinding, le flux d'autorisation des requêtes, et comment concevoir, déployer et déboguer les politiques RBAC. Chaque section fournit des commandes concrètes, les sorties attendues et les étapes de récupération pour garantir la sécurité opérationnelle et la confiance.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire de version et d'environnement
Avant de modifier toute configuration RBAC, établissez une image claire de l'environnement du cluster. Cela inclut la version de Kubernetes, la configuration du serveur d'API et les ressources RBAC existantes. Un inventaire en lecture seule aide à identifier les problèmes de compatibilité potentiels et établit une base de référence pour le dépannage.
Vérifier la version de Kubernetes et la disponibilité du RBAC
Le RBAC est activé par défaut dans Kubernetes 1.6 et versions ultérieures. Vérifiez la version du serveur et assurez-vous que l'API authorization.k8s.io/v1 est disponible :
kubectl version --short
# Exemple de sortie :
# Client Version: v1.27.3
# Kustomize Version: v5.0.1
# Server Version: v1.27.3
kubectl api-versions | grep rbac
# Sortie attendue :
# rbac.authorization.k8s.io/v1
Si l'API rbac.authorization.k8s.io/v1 est absente, vérifiez les indicateurs du serveur d'API. Sur les clusters gérés (par exemple, EKS, GKE, AKS), le RBAC est toujours activé. Pour les clusters auto-gérés, inspectez le manifeste kube-apiserver :
sudo cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep authorization-mode
# Attendu : --authorization-mode=Node,RBAC
Inventorier les ClusterRoles et les liaisons existants
Listez tous les ClusterRoles et ClusterRoleBindings pour comprendre les permissions actuelles. Recherchez les rôles trop permissifs ou les liaisons inattendues :
kubectl get clusterroles
# Exemple de sortie (tronquée) :
# NAME CREATED AT
# admin 2023-01-10T08:12:31Z
# cluster-admin 2023-01-10T08:12:31Z
# edit 2023-01-10T08:12:31Z
# view 2023-01-10T08:12:31Z
# system:aggregate-to-admin 2023-01-10T08:12:31Z
# ...
kubectl get clusterrolebindings
# Exemple de sortie :
# NAME ROLE AGE
# cluster-admin ClusterRole/cluster-admin 45d
# system:basic-user ClusterRole/system:basic-user 45d
# my-app-admin-binding ClusterRole/my-app-admin 2d
Pour identifier quels sujets (utilisateurs, groupes ou comptes de service) sont liés à un ClusterRole spécifique, utilisez kubectl describe :
kubectl describe clusterrolebinding cluster-admin
# Exemple de sortie :
# Name: cluster-admin
# Labels: kubernetes.io/bootstrapping=rbac-defaults
# Annotations: rbac.authorization.kubernetes.io/autoupdate: true
# Role:
# Kind: ClusterRole
# Name: cluster-admin
# Subjects:
# Kind Name Namespace
# ---- ---- ---------
# Group system:masters
Prérequis pour tester les modifications de ClusterRole
Lorsque vous testez des modifications RBAC, évitez de modifier les rôles existants qui pourraient affecter les charges de travail en production. Créez plutôt un espace de noms dédié et un compte de service pour les expériences. Cela limite le rayon d'impact et facilite le nettoyage :
kubectl create namespace rbac-test
kubectl create serviceaccount test-sa -n rbac-test
Enregistrez l'état du cluster avant toute modification. Stockez le YAML actuel des ClusterRoles et ClusterRoleBindings critiques pour un retour en arrière :
kubectl get clusterrole cluster-admin -o yaml > cluster-admin-backup.yaml
kubectl get clusterrolebinding cluster-admin -o yaml > cluster-admin-binding-backup.yaml
Chemin de configuration sécurisé
La conception de ressources ClusterRole et ClusterRoleBinding suit un flux de travail sécurisé et itératif. Cette section fournit une approche étape par étape pour créer des rôles à moindre privilège avec des exemples concrets et des étapes de vérification.
Comprendre ClusterRole et ClusterRoleBinding
Un ClusterRole est une ressource non liée à un espace de noms qui définit un ensemble de permissions (règles) sur les ressources Kubernetes. Un ClusterRoleBinding accorde ces permissions à des sujets (utilisateurs, groupes ou comptes de service) dans tout le cluster. Si vous devez uniquement accorder des permissions dans un espace de noms spécifique, utilisez plutôt un Role et un RoleBinding.
Une règle ClusterRole se compose de :
apiGroups: Le groupe d'API de la ressource (par exemple,""pour le noyau,appspour les déploiements).resources: Le type de ressource (par exemple,pods,deployments,secrets).verbs: Les actions autorisées (par exemple,get,list,create,update,delete).
Étape 1 : Définir un ClusterRole minimal
Supposons qu'un compte de service de surveillance ait besoin d'un accès en lecture aux pods et aux nœuds dans tous les espaces de noms. Créez un ClusterRole nommé pod-reader :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader
rules:
- apiGroups: [""] # groupe API noyau
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
Appliquez le manifeste :
kubectl apply -f pod-reader-clusterrole.yaml
# Sortie attendue :
# clusterrole.rbac.authorization.k8s.io/pod-reader created
Étape 2 : Vérifier les permissions du ClusterRole
Utilisez kubectl describe pour afficher les permissions accordées :
kubectl describe clusterrole pod-reader
# Exemple de sortie :
# Name: pod-reader
# Labels: <none>
# Annotations: <none>
# PolicyRule:
# Resources Non-Resource URLs Resource Names Verbs
# --------- ----------------- -------------- -----
# pods [] [] [get list watch]
# nodes [] [] [get list watch]
Étape 3 : Créer un ClusterRoleBinding pour un compte de service
Liez le ClusterRole pod-reader à un compte de service monitoring-sa dans l'espace de noms monitoring. Cela accorde les permissions à l'échelle du cluster à ce compte de service :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-pods-global
subjects:
- kind: ServiceAccount
name: monitoring-sa
namespace: monitoring
roleRef:
kind: ClusterRole
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Appliquez et vérifiez :
kubectl apply -f pod-reader-binding.yaml
# Sortie attendue :
# clusterrolebinding.rbac.authorization.k8s.io/read-pods-global created
kubectl describe clusterrolebinding read-pods-global
# Exemple de sortie :
# Name: read-pods-global
# Labels: <none>
# Annotations: <none>
# Role:
# Kind: ClusterRole
# Name: pod-reader
# Subjects:
# Kind Name Namespace
# ---- ---- ---------
# ServiceAccount monitoring-sa monitoring
Étape 4 : Tester l'accès avec kubectl auth can-i
Avant de déployer une application qui utilise le compte de service, vérifiez ses permissions effectives avec kubectl auth can-i :
kubectl auth can-i list pods --as=system:serviceaccount:monitoring:monitoring-sa --all-namespaces
# Sortie attendue : yes
kubectl auth can-i create deployments --as=system:serviceaccount:monitoring:monitoring-sa
# Sortie attendue : no
Cela confirme que le compte de service peut lister les pods dans tous les espaces de noms mais ne peut pas créer de déploiements.
Étape 5 : Appliquer les principes du moindre privilège
Examinez la règle pour vous assurer qu'elle n'accorde que ce qui est nécessaire. Par exemple, si l'agent de surveillance n'a besoin que de lire les métriques des pods, a-t-il besoin de nodes ? Supprimez les permissions inutiles pour minimiser les risques. Réappliquez et testez après chaque modification.
Vérification et diagnostics
Après avoir appliqué la configuration RBAC, une vérification systématique permet de détecter rapidement les erreurs de configuration. Cette section couvre les méthodes pour confirmer que les ClusterRoles et ClusterRoleBindings se comportent comme prévu et comment diagnostiquer les problèmes.
Vérifier les permissions effectives pour différents sujets
Utilisez kubectl auth can-i pour vérifier les permissions des utilisateurs, des groupes et des comptes de service. Cette commande simule une requête API et renvoie yes ou no sans modifier les ressources.
Exemple : Vérifiez si un utilisateur hypothétique alice peut supprimer des pods dans l'espace de noms default :
kubectl auth can-i delete pods --as alice -n default
# Sortie attendue : no
Vérifiez si le groupe system:masters peut tout faire :
kubectl auth can-i '*' '*' --as-group system:masters
# Sortie attendue : yes
Inspecter les journaux d'audit du serveur d'API
Si une requête est refusée de manière inattendue, activez et inspectez les journaux d'audit. Pour les clusters gérés, consultez la documentation de votre fournisseur pour l'accès aux journaux d'audit. Pour les clusters auto-gérés, configurez une politique d'audit qui enregistre les refus RBAC.
Exemple d'extrait de politique d'audit pour enregistrer toutes les requêtes :
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
Ensuite, recherchez dans le journal d'audit l'utilisateur et la ressource spécifiques :
grep '"user":{"username":"alice"}' /var/log/kubernetes/audit/audit.log | grep 'pods'
Recherchez les entrées "responseStatus":{"code":403} pour confirmer le refus.
Valider la syntaxe du ClusterRole et la compatibilité de l'API
Effectuez un essai à blanc d'un manifeste pour détecter les erreurs avant de l'appliquer :
kubectl apply -f pod-reader-clusterrole.yaml --dry-run=client
# Sortie attendue :
# clusterrole.rbac.authorization.k8s.io/pod-reader created (dry run)
Pour une validation côté serveur, utilisez --dry-run=server :
kubectl apply -f pod-reader-clusterrole.yaml --dry-run=server
# Sortie attendue :
# clusterrole.rbac.authorization.k8s.io/pod-reader created (server dry run)
Diagnostiquer les problèmes courants
| Symptôme | Cause probable | Commande de diagnostic |
|---|---|---|
403 Forbidden lors de l'accès à une ressource | Le sujet n'est lié à aucun rôle ou les verbes sont insuffisants | kubectl auth can-i <verb> <resource> --as <subject> |
| Les modifications de rôle ne prennent pas effet | Mise en cache ou espace de noms de liaison incorrect | kubectl get clusterrolebinding <name> -o yaml pour inspecter les sujets et roleRef |
| Un compte de service dans un espace de noms ne peut pas accéder à une ressource à l'échelle du cluster | Le ClusterRoleBinding fait référence à un mauvais espace de noms dans le sujet | kubectl describe clusterrolebinding <name> et vérifiez l'espace de noms du sujet |
Error from server (NotFound): clusterroles.rbac.authorization.k8s.io "foo" not found | Non-correspondance du nom du ClusterRole dans la liaison | Comparez roleRef.name dans la liaison avec le nom réel du ClusterRole |
Modes de défaillance et récupération
Malgré une conception soignée, les erreurs de configuration RBAC peuvent entraîner des échecs d'autorisation ou des accès non intentionnels. Cette section explore les modes de défaillance courants et fournit des étapes de récupération concrètes.
Scénario 1 : ClusterRoleBinding trop permissif
Un membre de l'équipe lie accidentellement le ClusterRole cluster-admin à un compte de service utilisé par une application web. Cela accorde à l'application un contrôle total sur le cluster.
Détection :
kubectl get clusterrolebindings -o wide
# Recherchez les liaisons qui référencent cluster-admin et un sujet non système
kubectl describe clusterrolebinding risky-binding
# Exemple de sortie :
# Role:
# Kind: ClusterRole
# Name: cluster-admin
# Subjects:
# Kind Name Namespace
# ---- ---- ---------
# ServiceAccount web-app-sa production
Récupération :
Supprimez immédiatement le ClusterRoleBinding :
kubectl delete clusterrolebinding risky-binding
# Sortie attendue :
# clusterrolebinding.rbac.authorization.k8s.io "risky-binding" deleted
Ensuite, créez une nouvelle liaison avec le ClusterRole à moindre privilège approprié. Par exemple, si l'application web n'a besoin que de lire les configmaps, créez un ClusterRole avec get et list sur configmaps et liez-le.
Scénario 2 : Permissions manquantes pour un utilisateur légitime
Un développeur signale qu'il ne peut pas lister les pods dans l'espace de noms development. L'erreur est Error from server (Forbidden): pods is forbidden: User "bob" cannot list resource "pods" in API group "" in the namespace "development".
Diagnostic :
Vérifiez les liaisons existantes pour bob :
kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq '.items[] | select(.subjects[]?.name == "bob")'
Si aucune liaison ne référence bob, créez un RoleBinding dans l'espace de noms development avec les permissions appropriées. Ou, si l'utilisateur fait partie d'un groupe (par exemple, developers), assurez-vous que le groupe est lié.
kubectl auth can-i list pods -n development --as bob
# Sortie attendue : no
Récupération :
Créez un Role et un RoleBinding pour un accès limité à l'espace de noms (pas un ClusterRoleBinding, pour limiter le rayon d'impact) :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: development
subjects:
- kind: User
name: bob
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Appliquez et vérifiez :
kubectl apply -f bob-pod-reader.yaml
kubectl auth can-i list pods -n development --as bob
# Sortie attendue : yes
Scénario 3 : Mauvaise configuration de l'agrégation de ClusterRole
Les ClusterRoles avec des étiquettes d'agrégation (rbac.authorization.k8s.io/aggregate-to-...) peuvent hériter involontairement de permissions d'autres ClusterRoles. Par exemple, un ClusterRole étiqueté aggregate-to-admin recevra automatiquement toutes les règles des ClusterRoles portant cette étiquette. Si un administrateur ajoute accidentellement une règle large à un rôle agrégé, elle se propage à tous les rôles portant l'étiquette.
Détection :
kubectl get clusterroles -l rbac.authorization.k8s.io/aggregate-to-admin
Examinez les règles de ces rôles pour détecter des ajouts inattendus.
Récupération :
Supprimez la règle incriminée du ClusterRole source et réappliquez. Ou supprimez l'étiquette d'agrégation du rôle affecté si l'agrégation n'est pas nécessaire.
Liste de vérification des opérations
Utilisez la liste de vérification suivante avant et après avoir apporté des modifications RBAC pour garantir la sécurité et la correction.
Liste de vérification avant modification
- [ ] Confirmez la version de Kubernetes et que l'API RBAC est disponible :
kubectl api-versions | grep rbac.authorization.k8s.io/v1 - [ ] Inventoriez les ClusterRoles et ClusterRoleBindings existants susceptibles d'être affectés :
kubectl get clusterroles,clusterrolebindings -o wide - [ ] Sauvegardez les ressources RBAC critiques :
kubectl get clusterrole <name> -o yaml > backup.yaml - [ ] Identifiez le sujet exact (utilisateur, groupe, compte de service) et les permissions requises.
- [ ] Écrivez le manifeste ClusterRole ou ClusterRoleBinding avec des règles à moindre privilège.
- [ ] Effectuez un essai à blanc du manifeste :
kubectl apply -f manifest.yaml --dry-run=server - [ ] Examinez les modifications dans un système de contrôle de version et obtenez l'approbation des pairs si nécessaire.
Liste de vérification après modification
- [ ] Appliquez le manifeste :
kubectl apply -f manifest.yaml - [ ] Inspectez la ressource :
kubectl describe clusterrole <name>oukubectl describe clusterrolebinding <name> - [ ] Testez les permissions effectives pour le sujet :
kubectl auth can-i <verb> <resource> --as <subject> - [ ] Pour les comptes de service, déployez un pod de test utilisant le compte de service et tentez l'opération.
- [ ] Vérifiez les journaux d'audit (si disponibles) pour les refus ou autorisations inattendus.
- [ ] Documentez la modification, y compris pourquoi elle était nécessaire et comment revenir en arrière.
Exemple : Vérification des permissions pour un nouveau compte de service
Supposons que vous ayez créé un compte de service ci-deployer dans l'espace de noms ci et lié un ClusterRole deployer qui permet de créer des déploiements. Vérifiez :
kubectl auth can-i create deployments --as=system:serviceaccount:ci:ci-deployer -n production
# Sortie attendue : yes (si le ClusterRole accorde create sur les déploiements à l'échelle du cluster)
Si la sortie attendue est no, examinez la configuration du ClusterRole et du ClusterRoleBinding.
Conclusion
L'architecture ClusterRole de Kubernetes est un outil puissant pour gérer les permissions à l'échelle du cluster, mais elle exige une conception et une vérification minutieuses. En suivant une approche systématique — inventorier l'environnement, appliquer des configurations à moindre privilège, tester avec kubectl auth can-i et savoir comment récupérer des échecs — vous pouvez maintenir un cluster sécurisé et fiable.
Comme prochaine étape, passez en revue les ClusterRoles et ClusterRoleBindings existants de votre cluster. Identifiez les liaisons qui accordent plus de permissions que nécessaire. Créez un plan pour les remplacer par des rôles étroitement définis, testez les modifications à l'aide des méthodes d'essai à blanc et can-i décrites dans cet article, et documentez la procédure de retour en arrière. N'oubliez pas de vérifier les ressources associées telles que les Roles, RoleBindings et ServiceAccounts pour assurer une posture de sécurité cohérente.
Un flux de travail technique fiable rend les échecs visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de la récupération avant qu'un incident ne force la décision.