Introduction
Le contrôle d'accès basé sur les rôles (RBAC) de Kubernetes est un composant essentiel pour sécuriser les clusters. À mesure que les clusters se développent, les évaluations RBAC peuvent devenir un goulot d'étranglement en termes de performances. Les ClusterRoleBindings, qui accordent des autorisations à l'échelle du cluster, sont souvent surutilisés, ce qui entraîne une augmentation de la charge et de la latence du serveur d'API. Cet article fournit des conseils pratiques sur l'optimisation des performances des ClusterRoleBindings avec des exemples concrets, vous aidant à identifier les goulots d'étranglement, à mettre en œuvre des optimisations en toute sécurité, à vérifier les améliorations et à revenir en arrière si nécessaire.
L'autorisation RBAC dans Kubernetes est évaluée à chaque requête API. Le serveur d'API Kubernetes utilise une chaîne d'autorisation qui inclut le RBAC. L'autoriseur RBAC vérifie les rôles et les liaisons de l'utilisateur demandeur pour déterminer les actions autorisées. Les ClusterRoleBindings sont évalués quel que soit l'espace de noms, ce qui peut ajouter une surcharge, en particulier lorsqu'il existe de nombreuses liaisons larges. En limitant les autorisations aux espaces de noms avec des RoleBindings, vous réduisez la portée de l'autorisation et améliorez potentiellement les performances du serveur d'API.
Ce guide s'adresse aux administrateurs de cluster, aux ingénieurs de plateforme et aux professionnels DevOps qui gèrent des clusters Kubernetes et souhaitent optimiser le RBAC sans compromettre la sécurité. Nous allons parcourir un scénario courant, démontrer le processus de conversion, mesurer l'impact et fournir des étapes de récupération.
Inventaire de la version et de l'environnement
Avant de procéder à l'optimisation, faites l'inventaire de votre environnement Kubernetes. Vérifiez la version du serveur d'API et assurez-vous qu'il prend en charge le RBAC (toutes les versions prises en charge le font). Pour ce guide, nous supposons Kubernetes 1.24 ou plus récent. Le RBAC est stable depuis Kubernetes 1.8, mais les comportements en matière de performances peuvent varier selon les versions en raison des améliorations de l'autoriseur.
Prérequis :
- kubectl configuré avec un accès cluster-admin pour l'inspection et les modifications.
- Compréhension de vos ressources RBAC : ClusterRoles, ClusterRoleBindings, Roles, RoleBindings, ServiceAccounts, Users, Groups.
- Pipeline de métriques (par exemple, Prometheus) pour capturer les métriques du serveur d'API.
- Accès aux journaux d'audit (si activés) pour les décisions d'autorisation détaillées.
- Un cluster de test ou de staging pour une expérimentation en toute sécurité.
Exemple de topologie : Dans un cluster de démarrage typique, il peut y avoir de nombreux ClusterRoleBindings accordant des autorisations larges à des groupes comme developers ou system:authenticated. Cet accès large augmente le temps d'évaluation. Nous utiliserons un cluster hypothétique avec 50 nœuds et 500 utilisateurs, où la latence des requêtes API pour les points de terminaison à forte intensité RBAC est élevée. Le cluster exécute Kubernetes 1.28. Le serveur d'API gère environ 1 200 requêtes par seconde au pic, avec une latence p99 pour les opérations de liste de pods à 800 ms. L'objectif est de réduire la latence p99 de 30 % sans casser l'accès.
Vérifiez votre version de Kubernetes :
kubectl version --short
# Sortie :
# Client Version: v1.28.0
# Server Version: v1.28.2
Listez les ClusterRoleBindings existants :
kubectl get clusterrolebindings
# Exemple de sortie (tronquée) :
NAME ROLE AGE
cluster-admin cluster-admin 3y
dev-team-view view 1y
system:basic-user system:basic-user 3y
system:discovery system:discovery 3y
system:public-info-viewer system:public-info-viewer 3y
...
Identifiez les sujets larges :
kubectl get clusterrolebindings -o custom-columns='NAME:.metadata.name,SUBJECTS:.subjects[*].kind,SUBJECT_NAMES:.subjects[*].name,ROLE:.roleRef.name'
# Exemple de sortie :
NAME SUBJECTS SUBJECT_NAMES ROLE
dev-team-view Group dev-team view
system:authenticated Group system:authenticated system:basic-user
Dans cet exemple, dev-team-view accorde le rôle view à l'ensemble du groupe dev-team dans tous les espaces de noms. C'est un candidat idéal pour la limitation de portée.
Chemin de configuration sûr
Optimisez les ClusterRoleBindings en toute sécurité en limitant les autorisations aux espaces de noms lorsque cela est possible. Remplacez les ClusterRoleBindings par des RoleBindings pour les ressources limitées à l'espace de noms.
Un ClusterRoleBinding accorde des autorisations dans tous les espaces de noms (et les ressources à portée de cluster). Un RoleBinding accorde des autorisations uniquement dans un espace de noms spécifique. Cependant, vous pouvez référencer un ClusterRole dans un RoleBinding ; les autorisations sont alors limitées à cet espace de noms. C'est un modèle recommandé car il réutilise les ClusterRoles existants tout en réduisant la portée de la liaison.
Exemple : ClusterRoleBinding original
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dev-team-view
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
Cette liaison permet à tout membre de dev-team de voir les ressources dans tous les espaces de noms. Si l'équipe ne travaille que dans app-dev et app-staging, remplacez-la par des RoleBindings dans chaque espace de noms.
Remplacer par un RoleBinding dans chaque espace de noms requis
Créez un RoleBinding dans l'espace de noms app-dev :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-view
namespace: app-dev
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: view
apiGroup: rbac.authorization.k8s.io
Créez un RoleBinding similaire dans app-staging (seul l'espace de noms change). Appliquez les deux fichiers :
kubectl apply -f rolebinding-app-dev.yaml
kubectl apply -f rolebinding-app-staging.yaml
Ensuite, supprimez le ClusterRoleBinding original :
kubectl delete clusterrolebinding dev-team-view
Important : Avant de supprimer, vérifiez que les nouveaux RoleBindings sont en place et que l'accès fonctionne. Utilisez --dry-run=client pour prévisualiser la suppression. Envisagez également d'utiliser kubectl auth reconcile pour gérer le RBAC de manière déclarative.
Impact : L'évaluation RBAC peut devenir plus efficace car l'autoriseur peut élaguer plus tôt les liaisons non pertinentes. L'autoriseur RBAC Kubernetes construit une liste de toutes les liaisons (à la fois de cluster et d'espace de noms) pour un utilisateur donné. Avec un ClusterRoleBinding, cette liaison est toujours prise en compte. Avec des RoleBindings, seules les liaisons de l'espace de noms demandé sont évaluées. Cela réduit l'espace de recherche et peut diminuer l'utilisation du processeur et la latence. Cependant, le gain de performance réel dépend de la version de Kubernetes et de l'implémentation de l'autoriseur. Testez d'abord dans un environnement de staging.
Optimisations sûres supplémentaires :
- Évitez d'utiliser
system:authenticatedetsystem:unauthenticateddans les liaisons ; ils s'appliquent à chaque identité. - Utilisez des groupes spécifiques plutôt que des groupes énormes.
- Auditez et supprimez régulièrement les liaisons inutilisées.
- Envisagez d'utiliser
kubectl auth reconcile -f manifests/pour garantir un état cohérent.
Vérification et diagnostics
Mesurez la latence des requêtes API avant et après les modifications. Utilisez kubectl avec une journalisation verbeuse pour voir le temps d'une requête.
Utilisation de kubectl -v=6
kubectl get pods --as=system:serviceaccount:app-dev:test-sa -v=6 2>&1 | grep -E 'GET|POST|round_trip'
La sortie verbeuse inclut le temps aller-retour. Extrait d'exemple :
I0125 10:00:00.123456 12345 round_trippers.go:553] GET https://api.example.com:6443/api/v1/namespaces/app-dev/pods 200 OK in 123 milliseconds
Notez la partie in X milliseconds.
Utilisation des métriques Prometheus
Comparez les histogrammes avant et après les modifications.
apiserver_request_duration_seconds_bucket{verb="GET", resource="pods"}
Exemple de vérification de la métrique pour la latence p99 :
histogram_quantile(0.99, sum(rate(apiserver_request_duration_seconds_bucket{resource="pods"}[5m])) by (le))
Résultat attendu : réduction de la latence après la limitation des liaisons. Dans un scénario typique, la latence p99 pour les requêtes de liste de pods peut passer de 800 ms à 450 ms.
Journaux d'audit
Activez la journalisation d'audit pour voir les décisions d'autorisation. Chaque décision a authorization.k8s.io/decision et authorization.k8s.io/reason. L'examen des journaux d'audit peut montrer si des requêtes sont refusées en raison d'erreurs de limitation.
Exemple d'événement d'audit (tronqué) :
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/app-dev/pods",
"verb": "list",
"user": {"username": "system:serviceaccount:app-dev:test-sa"},
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "RBAC: allowed by RoleBinding 'dev-team-view' in namespace 'app-dev'"
}
}
Vérification après modification
Assurez-vous que l'utilisateur ou le groupe a toujours l'accès nécessaire :
kubectl auth can-i list pods --as=dev-user --namespace=app-dev
# Sortie : yes
Et refuser en dehors de l'espace de noms :
kubectl auth can-i list pods --as=dev-user --namespace=other-ns
# Sortie : no
Vous pouvez également lister toutes les autorisations pour un utilisateur :
kubectl auth can-i --list --as=dev-user --namespace=app-dev
Modes de défaillance et récupération
Des modifications de liaison trop agressives peuvent casser l'accès. Si un développeur perd des autorisations requises, les applications peuvent échouer. Modes de défaillance courants :
- Oublier de créer un RoleBinding dans un espace de noms nécessaire.
- Mal configurer le type/nom du sujet.
- Supprimer un ClusterRoleBinding qui était également utilisé pour des ressources à portée de cluster (par exemple, les nœuds).
- Conditions de course entre la suppression et l'application de nouvelles liaisons.
Étapes de récupération :
- Conservez la définition originale du ClusterRoleBinding dans un fichier avant la suppression.
- Si des problèmes d'accès surviennent, réappliquez la liaison originale :
kubectl apply -f original-clusterrolebinding.yaml
- Sinon, annulez les RoleBindings et recréez le ClusterRoleBinding.
Exemple de retour en arrière
Supposons que vous ayez remplacé le ClusterRoleBinding dev-team-view par des RoleBindings mais que vous ayez oublié l'espace de noms app-staging. Un développeur signale qu'il ne peut pas lister les pods dans app-staging. Pour restaurer rapidement l'accès :
# Réappliquer le ClusterRoleBinding original
kubectl apply -f original-clusterrolebinding.yaml
# Sortie : clusterrolebinding.rbac.authorization.k8s.io/dev-team-view created
Vérifiez ensuite l'accès :
kubectl auth can-i list pods --as=dev-user --namespace=app-staging
# Sortie : yes
Après avoir corrigé le RoleBinding dans app-staging, vous pouvez supprimer à nouveau le ClusterRoleBinding après vérification.
Mesures préventives
- Testez les modifications avec un espace de noms canari ou un cluster de staging avant la production.
- Utilisez
kubectl auth can-ide manière intensive avant et après. - Implémentez les modifications RBAC via GitOps avec revue.
- Surveillez les métriques d'erreur d'autorisation (
apiserver_authorization_decision_total{decision="deny"}) pour les pics. - Conservez les plans de retour en arrière comme code dans le contrôle de version.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour identifier et convertir systématiquement les ClusterRoleBindings en RoleBindings.
- [ ] Inventorier tous les ClusterRoleBindings et identifier les sujets larges (groupes,
system:authenticated,system:unauthenticated). - [ ] Déterminer quelles liaisons peuvent être converties en RoleBindings dans des espaces de noms spécifiques.
- [ ] Documenter les liaisons originales pour le retour en arrière (enregistrer les fichiers YAML dans Git).
- [ ] Appliquer d'abord les modifications à un environnement de staging.
- [ ] Mesurer la latence du serveur d'API avant et après.
- [ ] Vérifier l'accès pour les utilisateurs représentatifs/comptes de service.
- [ ] Surveiller les erreurs d'autorisation dans les journaux d'application.
- [ ] Revenir en arrière si des erreurs se produisent.
Tableau de référence des commandes
| Étape | Commande | Résultat attendu |
|---|---|---|
| Lister les ClusterRoleBindings | kubectl get clusterrolebindings | Liste de toutes les liaisons |
| Vérifier les autorisations | kubectl auth can-i --list --as=user --namespace=ns | Liste des autorisations |
| Appliquer un RoleBinding | kubectl apply -f rolebinding.yaml | Liaison créée |
| Supprimer l'ancienne liaison | kubectl delete clusterrolebinding name | Liaison supprimée |
| Mesurer la latence | kubectl get pods -v=6 2>&1 | grep round_trip | Temps en ms |
| Vérifier l'accès | kubectl auth can-i list pods --as=user --namespace=ns | yes ou no |
| Vérifier les métriques | Requête PromQL | Valeur de latence p99 |
| Journaux d'audit | kubectl logs -n kube-system kube-apiserver... | Décision allow/deny |
Exemple d'exécution pour un pilote
Pour l'exemple dev-team-view :
- Enregistrer la liaison originale :
kubectl get clusterrolebinding dev-team-view -o yaml > original-clusterrolebinding.yaml
- Créer des RoleBindings dans
app-devetapp-stagingcomme indiqué précédemment.
- Appliquer les RoleBindings :
kubectl apply -f rolebinding-app-dev.yaml
kubectl apply -f rolebinding-app-staging.yaml
- Vérifier l'accès pour un membre de l'équipe dans les deux espaces de noms :
kubectl auth can-i list pods [email protected] --namespace=app-dev
# yes
kubectl auth can-i list pods [email protected] --namespace=app-staging
# yes
kubectl auth can-i list pods [email protected] --namespace=other-ns
# no
- Supprimer le ClusterRoleBinding :
kubectl delete clusterrolebinding dev-team-view
- Mesurer la latence et comparer avec la référence.
Conclusion
L'optimisation des performances des ClusterRoleBindings Kubernetes consiste à réduire la portée et la complexité de l'autorisation. En inventoriant les liaisons, en les limitant aux espaces de noms et en mesurant l'impact, vous pouvez améliorer la réactivité du serveur d'API. Testez toujours en staging, conservez des plans de retour en arrière et vérifiez l'accès des utilisateurs. Commencez par un pilote étroit et mesurable comme suggéré dans les preuves, et suivez une approche structurée pour réduire les retouches.
Points clés à retenir :
- Les ClusterRoleBindings sont puissants mais peuvent avoir un impact sur les performances lorsqu'ils sont surutilisés.
- Convertissez-les en RoleBindings dans des espaces de noms spécifiques pour limiter la portée de l'évaluation.
- Utilisez
kubectl auth can-iet les métriques Prometheus pour vérifier et surveiller. - Ayez toujours un plan de retour en arrière.
En appliquant ces pratiques, vous pouvez maintenir un cluster Kubernetes sécurisé et performant.