Comprendre les RBAC dans Kubernetes

Comprendre le fonctionnement des RBAC (Role Based Access Control) dans Kubernetes. Implémenter des RBAC et s'assurer que tout fonctionne comme prévu.

Comprendre les RBAC dans Kubernetes

Vue d'ensemble sur les RBAC

Le RBAC (contrôle d'accès basé sur les rôles) est une méthode de mise en œuvre du contrôle d'accès dans Kubernetes. Il peut être limité à un « espace de noms spécifique » ou étendu à l'ensemble du cluster.

RBAC limité au namespace

Les règles RBAC sont limitées à un espace de noms Kubernetes spécifique et s'appliquent uniquement aux ressources appartenant à cet espace de noms. Nous l'utilisons par exemple lorsque nous souhaitons accorder à un utilisateur ou à un compte de service des autorisations pour effectuer une opération sur certaines ressources uniquement dans un espace de noms spécifique. Pour implémenter le RBAC limité à l'espace de noms, nous utilisons les ressources Role et RoleBinding .

Les ressources Role et RoleBinding doivent être créées dans l'espace de noms dans lequel nous souhaitons limiter le contrôle d'accès.

La ressource Role définit les autorisations. Par exemple, l'autorisation de lister les pods. La ressource RoleBinding associe les autorisations à un utilisateur, un groupe ou un compte de service. L'utilisateur, le groupe ou le compte de service associé se verra alors accorder les autorisations définies dans la ressource Rôle et sera donc autorisé à effectuer les actions associées uniquement dans un espace de noms spécifique.

RBAC à l'échelle du cluster

Les règles RBAC ne se limitent pas à des espaces de noms spécifiques et s'appliquent à l'ensemble du cluster Kubernetes. Elles sont utilisées, par exemple, pour accorder à un utilisateur, un groupe ou un compte de service des autorisations d'action sur certaines ressources (déployées dans des namespace ou non) de l'ensemble du cluster. Pour implémenter un RBAC à l'échelle du cluster, nous utilisons les ressources ClusterRole et ClusterRoleBinding .

La ressource ClusterRole définit les autorisations. Par exemple, l'autorisation de lister les pods. La ressource ClusterRoleBinding associe les autorisations à un utilisateur, un groupe ou un compte de service. L'utilisateur, le groupe ou le compte de service associé se verra alors accorder les autorisations définies dans la ressource ClusterRole et sera ainsi autorisé à effectuer les actions associées à l'échelle du cluster.

Mise en œuvre du RBAC

Ressources Role et ClusterRole

Voici un exemple de manifeste de ressource Role ou ClusterRole :

kind: Role # or ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: podsReader
  namespace: mynamespace # only for Role resource 
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

Cet exemple peut être utilisé pour créer une ressource Role ou ClusterRole en définissant simplement le « type » approprié (Role ou ClusterRole) et en n'utilisant pas le champ « metadata.namespace » pour la ressource ClusterRole car cette ressource ne peut pas être placée dans des espaces de noms.

La section « rules » est la plus intéressante, car c'est là que nous définissons les autorisations. Les éléments suivants sont nécessaires pour définir ces autorisations :

  • apiGroups: une liste de groupes d'API des ressources pour lesquelles nous souhaitons définir un contrôle d'accès, par exemple « apps », « batch », etc. Le paragraphe suivant décrit comment trouver facilement ces informations pour des ressources spécifiques
  • resources: une liste de types de ressources pour lesquels nous souhaitons définir un contrôle d'accès (« deployments », « secrets », « pods », etc.)
  • verbs : actions réalisables sur les ressources. La liste des verbes disponibles, leurs descriptions ainsi que leurs équivalents HTTP est disponible ici.
Comment identifier les groupes d'API de ressources K8s

Pour afficher la liste des ressources prises en charge par notre cluster Kubernetes et les « apiGroups » associés, nous pouvons utiliser la commande « kubectl api-resources ». Voici un exemple :

$ kubectl api-resources
NAME                         SHORTNAMES   APIVERSION    NAMESPACED   KIND
(...)
namespaces                   ns           v1            false        Namespace
nodes                        no           v1            false        Node
persistentvolumeclaims       pvc          v1            true         PersistentVolumeClaim
persistentvolumes            pv           v1            false        PersistentVolume
pods                         po           v1            true         Pod
(...)
controllerrevisions                       apps/v1       true         ControllerRevision
daemonsets                   ds           apps/v1       true         DaemonSet
deployments                  deploy       apps/v1       true         Deployment
replicasets                  rs           apps/v1       true         ReplicaSet
statefulsets                 sts          apps/v1       true         StatefulSet
(...)

La colonne « NAME » indique le nom des ressources prises en charge par notre cluster Kubernetes. La colonne « APIVERSION » est composée de « apiGroups » suivis d'une version après la barre oblique. Par exemple, pour la ressource « deployments », la valeur de « apiGroups » est « apps ».

Pour certaines ressources, l'APIVERSION n'inclut pas leurs « apiGroups ». C'est le cas, par exemple, de la ressource « pods ». Cela signifie que la ressource appartient au groupe d'API « core » et que la valeur à utiliser pour « apiGroups » dans notre définition de ressources Role/ClusterRole est "", comme indiqué dans l’exemple de manifeste de ressource Role/ClusterRole précédent.

Ressources RoleBinding ou ClusterRoleBinding

Voici un exemple de manifeste de ressource RoleBinding ou ClusterRoleBinding :

kind: RoleBinding # or ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: podsReader
  namespace: mynamespace # only for RoleBinding resource 
subjects:
- kind: ServiceAccount # or User or Group
  name: myserviceaccount
  namespace: mynamespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role # or ClusterRole
  name: podsReader

Cet exemple peut être utilisé pour créer une ressource RoleBinding ou ClusterRoleBinding en définissant simplement le « type » approprié (RoleBinding ou ClusterRoleBinding) et en n'utilisant pas le champ « metadata.namespace » pour la ressource ClusterRoleBinding car cette ressource ne peut pas être placée dans des espaces de noms.

Il associe une ressource Role ou ClusterRole existante à un compte de service existant, afin d'accorder au compte de service les autorisations définies dans la ressource Role ou ClusterRole.

Voici une explication du contenu des champs « subjects » et « roleRef » :

  • subjects: définit le(s) sujet(s) sur lequel/lesquels lier une ressource Role ou ClusterRole spécifique
    • kind: le type du sujet. Peut être « User », « Group » ou « ServiceAccount ».
    • name: le nom du sujet (un nom d'utilisateur, un nom de groupe ou un nom de compte de service)
    • namespace: l'espace de noms où trouver le sujet (uniquement pour le type ServiceAccount)
  • roleRef: le Role ou le ClusterRole qui sera lié au sujet
    • apiGroup: la plupart du temps rbac.authorization.k8s.io
    • kind: le type de référence de rôle. Peut être « Role » ou « ClusterRole ».
    • name: le nom du « Role » ou du « ClusterRole » qui sera lié au sujet

Test du RBAC à l'aide de l'emprunt d'identité

Une fois que nous avons configuré RBAC pour autoriser l'accès à des ressources Kubernetes spécifiques pour certains utilisateurs, groupes ou comptes de service, la prochaine chose à faire est de tester que tout fonctionne comme prévu.

Il est plus pratique de pouvoir le faire sans demander aux utilisateurs d'effectuer des actions spécifiques ni configurer des pods avec des comptes de service spécifiques pour vérifier l'accès. C'est là que Kubernetes entre en jeu. d'emprunt d'identité (impersonation) de Kubernetes entre en jeu.

Grâce à la fonctionnalité d'emprunt d'identité (impersonation) , nous pouvons prendre l'identité d'un autre utilisateur, d'un groupe ou d'un compte de service pour effectuer des actions spécifiques (lister des pods à l'intérieur d'un espace de noms spécifique par exemple) et ainsi nous assurer que les règles RBAC sont correctement configurées.

L'utilisateur pour lequel nous exécutons des actions peut être un utilisateur réel d'un système de fournisseur d'identité (par exemple, un utilisateur GCP IAM) ou un utilisateur virtuel. L'utilisateur qui prend l'identité d'un autre utilisateur (réel ou virtuel), d'un groupe ou d'un compte de service, doit d'abord être autorisé à le faire avec un ClusterRole et le ClusterRoleBinding associé, comme suit :

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: impersonation
rules:
- apiGroups: [""] # the core API group
  resources: ["user"] # or group or serviceaccount
  # Users, groups or serviceaccount name(s)
  resourceNames: ["user-to-impersonate@mycompany.com"] 
  verbs: ["impersonate"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: impersonation
subjects:
- kind: User # or Group or ServiceAccount
  name: user-that-impersonate@mycompany.com
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: impersonation

Les ressources utilisateur et groupe sont la plupart du temps des ressources personnalisées disponibles uniquement lorsque nous utilisons le service Kubernetes géré par des fournisseurs de cloud comme GCP, AWS... et correspondent aux utilisateurs et groupes disponibles dans le service IAM (Identity and Access Management) qu'ils fournissent pour la gestion des accès des utilisateurs, des groupes et des services.

L'exemple de manifeste précédent permet à l'utilisateur identifié par l'adresse e-mail « user-that-impersonate@mycompany.com » d'emprunter l'identité de l'utilisateur identifié par l'adresse e-mail « user-to-impersonate@mycompany.com ». Nous pouvons utiliser le même exemple de manifeste pour autoriser l'emprunt d'identité d'un groupe ou d'un compte de service.

Ensuite, « user-that-impersonate@mycompany.com » peut configurer des règles RBAC pour « user-to-impersonate@mycompany.com » et tester la configuration en prenant l'identité de « user-to-impersonate@mycompany.com » à l'aide des commandes « kubectl » suivantes :

# Run a Kubectl command as another user (--as) or group (--as-group)
$ kubectl --as user-to-impersonate@mycompany.com get pods -n frontend

# Test if a specific Kubectl command will work... without actually running it
kubectl auth can-i get pods -n frontend

# Test if a specific Kubectl command will work for a specific user,
# without actually running it
kubectl auth can-i get pods -n frontend --as user-to-impersonate@mycompany.com

C'est tout. Nous disposons désormais des connaissances essentielles pour comprendre, implémenter et tester les règles RBAC dans Kubernetes.


Voilà. J'espère que vous comprenez mieux le RBAC de Kubernetes maintenant.

Vous souhaitez signaler une erreur ou poser une question ? N'hésitez pas à m'envoyer un e-mail à gmkziz@hackerstack.org. Je serai ravi de répondre.

Si vous aimez mes articles, pensez à vous inscrire à ma newsletter afin de recevoir les derniers articles dès qu'ils sont disponibles.

Prenez soin de vous, continuez à apprendre et à bientôt pour le prochain post 🚀