1 - Utilisation de l'autorisation RBAC

Le contrôle d'accès basé sur les rôles (RBAC) est une méthode permettant de réguler l'accès aux ressources informatiques ou réseau en fonction des rôles des utilisateurs individuels au sein de votre organisation.

L'autorisation RBAC utilise le groupe d'API rbac.authorization.k8s.io pour prendre les décisions d'autorisation, ce qui vous permet de configurer dynamiquement les politiques via l'API Kubernetes.

Pour activer RBAC, démarrez l'API server avec l'indicateur --authorization-mode défini sur une liste séparée par des virgules qui inclut RBAC ; par exemple :

kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options

Objets de l'API

L'API RBAC déclare quatre types d'objets Kubernetes : Role, ClusterRole, RoleBinding et ClusterRoleBinding. Vous pouvez décrire les objets, ou les modifier, en utilisant des outils tels que kubectl, comme tout autre objet Kubernetes.

Role et ClusterRole

Un Role ou ClusterRole RBAC contient des règles qui représentent un ensemble de permissions. Les permissions sont purement additives (il n'y a pas de règles de "refus").

Un rôle définit toujours les autorisations dans un namespace particulier; lorsque vous créez un Role, vous devez spécifier le namespace auquel il appartient.

ClusterRole, en revanche, est une ressource sans namespace. Les ressources portent des noms différents (Role et ClusterRole) parce qu'un objet Kubernetes doit toujours être soit avec un namespace ou soit sans namespace; Il ne peut pas être les deux.

Les ClusterRoles ont plusieurs usages. Vous pouvez utiliser une ClusterRole pour :

  1. définir les autorisations sur les ressources avec un namespace et obtenir l'accès à l'intérieur d'un ou plusieurs namespaces
  2. définir les permissions sur les ressources avec un namespace et obtenir l'accès à travers tous les namespaces.
  3. définir les permissions sur les ressources à l'échelle du cluster

Si vous souhaitez définir un rôle au sein d'un namespace, utilisez un Role; si vous souhaitez définir un rôle à l'échelle du cluster, utilisez un ClusterRole.

Exemple de Role

Voici un exemple de rôle dans le namespace "default" qui peut être utilisé pour accorder un accès en lecture aux pods:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Exemple de ClusterRole

Un ClusterRole peut être utilisé pour accorder les mêmes permissions qu'un Role. Étant donné que les ClusterRoles sont à l'échelle des clusters, vous pouvez également les utiliser pour accorder l'accès à:

  • des ressources à l'échelle du cluster (comme nodes)

  • des endpoints non liés aux ressources (comme /healthz)

  • des ressources à namespaces (comme les pods), dans tous les namespaces.

    Par exemple: vous pouvez utiliser un ClusterRole pour autoriser un utilisateur particulier à exécuter kubectl get pods --all-namespaces

Voici un exemple de ClusterRole qui peut être utilisé pour accorder un accès en lecture à secrets dans un namespace particulier, ou dans tous les namespaces (selon la façon dont il est lié):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Secret
  # objects is "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

Le nom d'un Role ou d'un objet ClusterRole doit être un nom de segment de chemin valide.

RoleBinding et ClusterRoleBinding

Un RoleBinding accorde les permissions définies dans un rôle à un utilisateur ou à un ensemble d'utilisateurs. Il contient une liste de sujets (utilisateurs, groupes, ou comptes de service), et une référence au rôle accordé. Un RoleBinding accorde des permissions dans un namespace spécifique alors qu'un ClusterRoleBinding accorde cet accès à l'échelle du cluster.

Le nom d'un objet RoleBinding ou ClusterRoleBinding doit être un nom de segment de chemin valide.

Exemples de RoleBinding

Voici un exemple de RoleBinding qui accorde le Role "pod-reader" à l'utilisateur "jane" dans le namespace "default". Ceci permet à "jane" de lire les pods dans le namespace "default".

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
  name: jane # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

Un RoleBinding peut également faire référence à un ClusterRole pour accorder les permissions définies dans ce ClusterRole aux ressources du namespace du RoleBinding. Ce type de référence vous permet de définir un ensemble de rôles communs à l'ensemble de votre cluster, puis de les réutiliser dans plusieurs namespaces.

Par exemple, même si le RoleBinding suivant fait référence à un ClusterRole, "dave" (le sujet, sensible à la casse) ne pourra lire que les Secrets dans le namespace "development", car le namespace du RoleBinding (dans son metadata) est "development".

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
# You need to already have a ClusterRole named "secret-reader".
kind: RoleBinding
metadata:
  name: read-secrets
  #
  # The namespace of the RoleBinding determines where the permissions are granted.
  # This only grants permissions within the "development" namespace.
  namespace: development
subjects:
- kind: User
  name: dave # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Exemple de ClusterRoleBinding

Pour accorder des permissions sur l'ensemble d'un cluster, vous pouvez utiliser un ClusterRoleBinding. Le ClusterRoleBinding suivant permet à tout utilisateur du groupe "manager" de lire secrets dans n'importe quel namespace.

apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Après avoir créé un lien, vous ne pouvez pas modifier le Role ou le ClusterRole auquel il fait référence. Si vous essayez de modifier le roleRef d'un lien, vous obtenez une erreur de validation. Si vous souhaitez changer le roleRef d'un lien, vous devez supprimer l'objet binding et en créer un autre.

Il y a deux raisons à cette restriction :

  1. Rendre roleRef immuable permet d'accorder à quelqu'un la permission update sur un objet de liaison existant, afin qu'il puisse gérer la liste des sujets, sans pouvoir changer le rôle qui est accordé à ces sujets.
  2. Un lien vers un rôle différent est un lien fondamentalement différent. Le fait d'exiger qu'un lien soit supprimé/créé afin de modifier le roleRef garantit que la liste complète des sujets dans le binding est destinée à recevoir le nouveau rôle (par opposition à l'activation ou à la modification accidentelle uniquement du roleRef sans vérifier que tous les sujets existants doivent recevoir les permissions du nouveau rôle).

L'utilitaire de ligne de commande kubectl auth reconcile crée ou met à jour un fichier manifeste contenant des objets RBAC, et gère la suppression et la recréation des objets de liaison si nécessaire pour modifier le rôle auquel ils se réfèrent. Voir utilisation de la commande et exemples pour plus d'informations.

Référence aux ressources

Dans l'API Kubernetes, la plupart des ressources sont représentées et accessibles à l'aide d'une chaîne de caractères de leur nom d'objet, comme pods pour un Pod. RBAC fait référence aux ressources en utilisant exactement le même nom que celui qui apparaît dans l'URL du endpoint de l'API concerné. Certaines API Kubernetes impliquent une sous-ressource, comme les logs d'un Pod. Une requête pour les logs d'un Pod ressemble à ceci :

GET /api/v1/namespaces/{namespace}/pods/{name}/log

Dans ce cas, pods est la ressource à namespace pour les ressources Pods, et log est une sous-ressource de pods. Pour représenter cela dans un rôle RBAC, utilisez une barre oblique (/) pour délimiter la ressource et la sous-ressource. Pour permettre à un sujet de lire pods et d'accéder également à la sous-ressource log pour chacun de ces Pods, vous écrivez :

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]

Vous pouvez également faire référence à des ressources par leur nom pour certaines demandes par le biais de la liste resourceNames. Lorsque cela est spécifié, les demandes peuvent être limitées à des instances individuelles d'une ressource. Voici un exemple qui limite son sujet à seulement get ou update une ConfigMap nommée my-configmap:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: configmap-updater
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing ConfigMap
  # objects is "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-configmap"]
  verbs: ["update", "get"]

Plutôt que de faire référence à des ressources et des verbes individuels, vous pouvez utiliser le symbole astérisque * pour faire référence à tous ces objets. Pour les nonResourceURLs, vous pouvez utiliser le symbole astérisque * comme suffixe de correspondance glob et pour les apiGroups et les resourceNames un ensemble vide signifie que tout est autorisé. Voici un exemple qui autorise l'accès pour effectuer toute action actuelle et future sur toutes les ressources actuelles et futures (remarque, ceci est similaire au rôle cluster-admin intégré).

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: example.com-superuser  # DO NOT USE THIS ROLE, IT IS JUST AN EXAMPLE
rules:
- apiGroups: ["example.com"]
  resources: ["*"]
  verbs: ["*"]

ClusterRoles agrégés

Vous pouvez agréger plusieurs ClusterRoles en un seul ClusterRole combiné. Un contrôleur, qui s'exécute dans le cadre du plan de contrôle du cluster, recherche les objets ClusterRole avec une aggregationRule définie. L'aggregationRule définit un label selector que le contrôleur utilise pour faire correspondre d'autres objets ClusterRole qui devraient être combinés dans le champ de règles de celui-ci.

Voici un exemple de ClusterRole agrégé :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # The control plane automatically fills in the rules

Si vous créez un nouvel ClusterRole qui correspond au sélecteur d'étiquette d'une ClusterRole agrégé existant, ce changement déclenche l'ajout des nouvelles règles dans le ClusterRole agrégé. Voici un exemple qui ajoute des règles au ClusterRole "monitoring", en créant un autre ClusterRole étiqueté rbac.example.com/aggregate-to-monitoring: true.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-endpoints
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
# When you create the "monitoring-endpoints" ClusterRole,
# the rules below will be added to the "monitoring" ClusterRole.
rules:
- apiGroups: [""]
  resources: ["services", "endpointslices", "pods"]
  verbs: ["get", "list", "watch"]

Les rôles par défaut destinés aux utilisateurs utilisent l'agrégation ClusterRole. Cela vous permet, en tant qu'administrateur de cluster, d'inclure des règles pour les ressources personnalisées, telles que celles servies par CustomResourceDefinitions ou les serveurs API agrégés, afin d'étendre les rôles par défaut.

Par exemple : les ClusterRoles suivants permettent aux rôles par défaut "admin" et "edit" de gérer la ressource personnalisée nommée CronTab, tandis que le rôle "view" ne peut effectuer que des actions de lecture sur les ressources CronTab. Vous pouvez supposer que les objets CronTab sont nommés "crontabs" dans les URLs telles que vues par le serveur API.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: aggregate-cron-tabs-edit
  labels:
    # Add these permissions to the "admin" and "edit" default roles.
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
rules:
- apiGroups: ["stable.example.com"]
  resources: ["crontabs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: aggregate-cron-tabs-view
  labels:
    # Add these permissions to the "view" default role.
    rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
  resources: ["crontabs"]
  verbs: ["get", "list", "watch"]

Role examples

Les exemples suivants sont des extraits d'objets Role ou ClusterRole, montrant uniquement la section rules.

Autoriser la lecture des ressources "pods" dans l' API Group central :

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Pod
  # objects is "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

Autoriser la lecture/écriture des Déploiements (au niveau HTTP : objets avec "deployments" dans la partie ressource de leur URL) dans les groupes API "apps" :

rules:
- apiGroups: ["apps"]
  #
  # at the HTTP level, the name of the resource for accessing Deployment
  # objects is "deployments"
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Autorise la lecture des Pods dans le groupe d'API central, ainsi que de lire ou d'écrire des ressources Job dans le groupe d'API "batch" :

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Pod
  # objects is "pods"
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
  #
  # at the HTTP level, the name of the resource for accessing Job
  # objects is "jobs"
  resources: ["jobs"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

Autoriser la lecture d'un ConfigMap nommé "my-config" (doit être lié avec un RoleBinding pour limiter à un seul ConfigMap dans un seul namespace).

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing ConfigMap
  # objects is "configmaps"
  resources: ["configmaps"]
  resourceNames: ["my-config"]
  verbs: ["get"]

Autoriser la lecture des ressources "nodes"dans le groupe central (parce qu'un Nœud est à l'échelle-du-cluster, il doit être dans un ClusterRole lié à un ClusterRoleBinding pour être effectif) :

rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Node
  # objects is "nodes"
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

Autorise les requêtes GET et POST vers l'endpoint non ressource /healthz et tous les sous-chemins (doit être dans un ClusterRole lié à un ClusterRoleBinding pour être effectif) :

rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
  verbs: ["get", "post"]

Référence à des subjects

Un RoleBinding ou ClusterRoleBinding lie un rôle à des sujets. Les sujets peuvent être des groupes, des utilisateurs ou des ServiceAccounts.

Kubernetes représente les noms d'utilisateurs sous forme de chaînes de caractères. Il peut s'agir: de noms simples, tels que "alice"; de noms de style e-mail, tels que "bob@example.com"; ou des IDs d'utilisateur numériques représentés sous forme de chaîne de caractères. Il vous appartient, en tant qu'administrateur de cluster, de configurer les modules d'authentification afin que l'authentification produise des noms d'utilisateur dans le format que vous souhaitez.

Dans Kubernetes, les modules Authenticator fournissent des informations sur les groupes. Les groupes, comme les utilisateurs, sont représentés sous forme de chaînes de caractères et cette chaîne n'a aucune exigence de format, si ce n'est que le préfixe system: est réservé.

Les ServiceAccounts ont des noms préfixés par system:serviceaccount:, et appartiennent à des groupes qui ont des noms préfixés par system:serviceaccounts:.

Exemples de RoleBinding

Les exemples suivants sont des extraits de RoleBinding qui ne montrent que la section des subjects.

Pour un utilisateur nommé alice@example.com :

subjects:
- kind: User
  name: "alice@example.com"
  apiGroup: rbac.authorization.k8s.io

Pour un groupe nommé frontend-admins:

subjects:
- kind: Group
  name: "frontend-admins"
  apiGroup: rbac.authorization.k8s.io

Pour le compte de service par défaut dans le namespace "kube-system" :

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

Pour tous les comptes de service dans le namespace "qa" :

subjects:
- kind: Group
  name: system:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

Pour tous les comptes de service dans n'importe quel namespace :

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

Pour tous les utilisateurs authentifiés :

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

Pour tous les utilisateurs non authentifiés :

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

Pour tous les utilisateurs :

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

Rôles par défaut et liaisons de rôles

Les serveurs API créent un ensemble d'objets ClusterRole et ClusterRoleBinding par défaut. Beaucoup d'entre eux sont préfixés system:, ce qui indique que la ressource est directement gérée par le plan de contrôle du cluster. Tous les ClusterRoles et ClusterRoleBindings par défaut sont étiquetés avec kubernetes.io/bootstrapping=rbac-defaults.

Auto-reconciliation

À chaque démarrage, le serveur API met à jour les rôles de cluster par défaut avec toutes les permissions manquantes, et met à jour les liaisons de rôles de cluster par défaut avec tous les sujets manquants. Cela permet au cluster de réparer les modifications accidentelles, et aide à maintenir les rôles et les liaisons de rôles à jour lorsque les autorisations et les sujets changent dans les nouvelles versions de Kubernetes.

Pour ne pas participer à cette reconciliation, définissez l'annotation rbac.authorization.kubernetes.io/autoupdate sur un rôle ou un rolebinding de cluster par défaut sur false. Sachez que les autorisations et les sujets par défaut manquants peuvent entraîner des clusters non fonctionnels.

L'auto-réconciliation est activée par défaut si l'autorisateur RBAC est actif.

Rôles de détection de l'API

Les liaisons de rôles par défaut autorisent les utilisateurs authentifiés et non authentifiés à lire les informations de l'API qui sont jugées sûres pour être accessibles au public (y compris les CustomResourceDefinitions). Pour désactiver l'accès anonyme non authentifié, ajoutez --anonymous-auth=false à la configuration du serveur d'API.

Pour afficher la configuration de ces rôles via kubectl, exécutez :

kubectl get clusterroles system:discovery -o yaml
Rôles de détection de l'API RBAC de Kubernetes
ClusterRole par défautClusterRoleBinding par défautDescription
system:basic-userGroupe system:authenticatedPermet à un utilisateur d'accéder en lecture seule aux informations de base le concernant. Avant la v1.14, ce rôle était également lié à system:unauthenticated par défaut.
system:discoveryGroupe system:authenticatedPermet un accès en lecture seule aux points de terminaison de découverte d'API nécessaires pour découvrir et négocier un niveau d'API. Avant la v1.14, ce rôle était également lié à l'option system:unauthenticated par défaut.
system:public-info-viewerGroupes system:authenticated et system:unauthenticatedPermet un accès en lecture seule à des informations non sensibles sur le cluster. Introduit dans Kubernetes v1.14.

Rôle des utilisateurs

Certains des ClusterRoles par défaut ne sont pas précédés du préfixe system:. Il s'agit de rôles destinés à l'utilisateur. Ils incluent les rôles de super-utilisateur (cluster-admin), les rôles destinés à être accordés à l'échelle du cluster à l'aide de ClusterRoleBindings, et les rôles destinés à être accordés dans des namespaces particuliers à l'aide de RoleBindings (admin, edit, view).

Les ClusterRoles des utilisateurs utilisent l'agrégation de ClusterRole pour permettre aux administrateurs d'inclure des règles pour les ressources personnalisées sur ces ClusterRoles. Pour ajouter des règles aux rôles admin, edit, ou view, créez une ClusterRole avec un ou plusieurs des labels suivants :

metadata:
  labels:
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"

ClusterRole par défautClusterRoleBinding par défautDescription
cluster-adminGroupe system:mastersPermet au super-utilisateur d'effectuer n'importe quelle action sur n'importe quelle ressource. Lorsqu'il est utilisé dans un ClusterRoleBinding, il donne un contrôle total sur chaque ressource dans le cluster et dans tous les namespaces. Lorsqu'il est utilisé dans un RoleBinding, il donne un contrôle total sur chaque ressource dans le namespace du role binding, y compris le namespace lui-même.
adminAucunPermet l'accès administrateur, destiné à être accordé au sein d'un espace de nom en utilisant un RoleBinding.

S'il est utilisé dans un RoleBinding, il permet un accès en lecture/écriture à la plupart des ressources d'un namespace, y compris la possibilité de créer des rôles et des liaisons de rôles dans le namespace. Ce rôle ne permet pas l'accès en écriture au quota de ressources ou au namespace lui-même. Ce rôle ne permet pas non plus l'accès en écriture aux EndpointSlices (ou Endpoints) dans les clusters créés à l'aide de Kubernetes v1.22+. Plus d'informations sont disponibles dans la section "Accès en écriture pour les EndpointSlices et les Endpoints".

editAucunPermet l'accès en lecture/écriture à la plupart des objets d'un namespace.

Ce rôle ne permet pas de visualiser ou de modifier les rôles ou les liaisons de rôles. Cependant, ce rôle permet d'accéder aux Secrets et d'exécuter des Pods comme n'importe quel ServiceAccount du namespace, il peut donc être utilisé pour obtenir les niveaux d'accès API de n'importe quel ServiceAccount du namespace. Ce rôle ne permet pas non plus d'accéder en écriture aux EndpointSlices (ou Endpoints) dans les clusters créés à l'aide de Kubernetes v1.22+. Plus d'informations sont disponibles dans la section "Write Access for EndpointSlices and Endpoints".

viewAucunPermet un accès en lecture seule pour voir la plupart des objets d'un namespace. Il ne permet pas de visualiser les rôles ou les liens entre les rôles. Ce rôle ne permet pas de visualiser les Secrets, car la lecture du contenu des Secrets permet d'accéder aux informations d'identification du ServiceAccount dans le namespace, ce qui permettrait d'accéder à l'API en tant que tout ServiceAccount dans l'espace de noms (une forme d'escalade des privilèges).

Ce rôle ne permet pas de consulter les secrets, car la lecture du contenu des secrets permet d'accéder aux informations d'identification du ServiceAccount dans le namespace, ce qui permettrait d'accéder à l'API en tant que n'importe quel ServiceAccount dans le namespace (une forme d'escalade des privilèges).

Rôles des composants de base

ClusterRole par défautClusterRoleBinding par défautDescription
system:kube-schedulerUtilisateur system:kube-schedulerPermet l'accès aux ressources requises par le composant scheduler.
system:volume-schedulerUtilisateur system:kube-schedulerPermet l'accès aux ressources de volume requises par le composant kube-scheduler.
system:kube-controller-managerutilisateur system:kube-controller-managerPermet l'accès aux ressources requises par le composant gestionnaire de contrôleur. Les autorisations requises par les contrôleurs individuels sont détaillées dans les rôles des contrôleurs.
system:nodeAucunPermet l'accès aux ressources requises par le kubelet, y compris l'accès en lecture à tous les secrets, et l'accès en écriture à tous les objets d'état des pods.

Vous devriez utiliser le Node authorizer et le plugin d'admission NodeRestriction au lieu du rôle system:node, et autoriser l'octroi d'un accès API aux kubelets en fonction des Pods programmés pour s'exécuter sur eux.

Le rôle system:node n'existe que pour la compatibilité avec les clusters Kubernetes mis à niveau à partir de versions antérieures à la v1.8.

system:node-proxierUtilisateur system:kube-proxyPermet l'accès aux ressources requises par le composant kube-proxy.

Autres rôles des composants

Default ClusterRoleDefault ClusterRoleBindingDescription
system:auth-delegatorAucunPermet de déléguer les contrôles d'authentification et d'autorisation. Il est couramment utilisé par les serveurs API complémentaires pour l'authentification et l'autorisation unifiées.
system:heapsterAucunRôle du composant Heapster Heapster (déprécié).
system:kube-aggregatorAucunRole for the kube-aggregator component.
system:kube-dnskube-dns compte de service kube-dns dans le namespace du kube-systemRôle du composant kube-dns .
system:kubelet-api-adminAucunPermet un accès complet à l'API kubelet.
system:node-bootstrapperAucunPermet d'accéder aux ressources nécessaires pour effectuer un kubelet TLS bootstrapping.
system:node-problem-detectorAucunRôle du component node-problem-detector .
system:persistent-volume-provisionerAucunPermet d'accéder aux ressources requises par la plupart des fournisseurs de volumes dynamiques .
system:monitoringGroupe system:monitoringAutorise l'accès en lecture aux endpoints de monitoring du control-plane (c'est-à-dire les endpoints kube-apiserver liveness and readiness (/healthz, /livez, /readyz), les endpoints de contrôle de l'état individuel (/healthz/*, /livez/*, /readyz/*), et /metrics). Il convient de noter que les endpoints des contrôles de l'état individuel et les endpoints des mesures peuvent exposer des informations sensibles.

Rôles des contrôleurs intégrés

Le gestionnaire de contrôleurs Kubernetes exécute les contrôleurs qui sont intégrés au plan de contrôle Kubernetes. Lorsqu'il est invoqué --use-service-account-credentials, kube-controller-manager démarre chaque contrôleur en utilisant un compte de service distinct. Des rôles correspondants existent pour chaque contrôleur intégré, préfixés par system:controller:. Si le gestionnaire de contrôleur n'est pas démarré avec --use-service-account-credentials, il exécute toutes les boucles de contrôle en utilisant ses propres informations d'identification, qui doivent se voir attribuer tous les rôles pertinents. Ces rôles sont les suivants :

  • system:controller:attachdetach-controller
  • system:controller:certificate-controller
  • system:controller:clusterrole-aggregation-controller
  • system:controller:cronjob-controller
  • system:controller:daemon-set-controller
  • system:controller:deployment-controller
  • system:controller:disruption-controller
  • system:controller:endpoint-controller
  • system:controller:expand-controller
  • system:controller:generic-garbage-collector
  • system:controller:horizontal-pod-autoscaler
  • system:controller:job-controller
  • system:controller:namespace-controller
  • system:controller:node-controller
  • system:controller:persistent-volume-binder
  • system:controller:pod-garbage-collector
  • system:controller:pv-protection-controller
  • system:controller:pvc-protection-controller
  • system:controller:replicaset-controller
  • system:controller:replication-controller
  • system:controller:resourcequota-controller
  • system:controller:root-ca-cert-publisher
  • system:controller:route-controller
  • system:controller:service-account-controller
  • system:controller:service-controller
  • system:controller:statefulset-controller
  • system:controller:ttl-controller

Prévention de l'escalade des privilèges et bootstrapping

L'API RBAC empêche les utilisateurs d'escalader les privilèges en modifiant les rôles ou les liaisons de rôles. Cette interdiction étant appliquée au niveau de l'API, elle s'applique même lorsque l'autorisateur RBAC n'est pas utilisé.

Restrictions à la création ou à la mise à jour des rôles

Vous ne pouvez créer/mettre à jour un rôle que si au moins l'une des choses suivantes est vraie :

  1. Vous disposez déjà de toutes les autorisations contenues dans le rôle, à la même échelle que l'objet en cours de modification (à l'échelle du cluster pour un ClusterRole, dans le même namespace ou à l'échelle du cluster pour un Role).
  2. Vous avez l'autorisation explicite d'exécuter le verbe escalader sur la ressource roles ou clusterroles dans le groupe API rbac.authorization.k8s.io.

Par exemple, si l'user-1 n'a pas la possibilité de lister les Secrets à l'échelle du cluster, il ne peut pas créer un ClusterRole contenant cette permission. Pour permettre à un utilisateur de créer/mettre à jour des rôles :

  1. Attribuez-leur un rôle qui leur permet de créer/mettre à jour des objets Role ou ClusterRole, selon leurs besoins.
  2. Leur accorder la permission d'inclure des autorisations spécifiques dans les rôles qu'ils créent/mettent à jour :
    • implicitement, en leur accordant ces autorisations (s'ils tentent de créer ou de modifier un Role ou un ClusterRole avec des autorisations qui ne leur ont pas été accordées, la demande d'API sera interdite)
    • ou explicitement, en leur donnant la permission de spécifier n'importe quelle permission dans un Role ou un ClusterRole, en leur donnant la permission d'exécuter le verbe escalader sur les roles ou les ressources clusterroles dans le groupe API rbac.authorization.k8s.io.

Restrictions à la création ou à la mise à jour de l'attribution de rôles

Vous ne pouvez créer/mettre à jour un lien de rôle que si vous disposez déjà de toutes les autorisations contenues dans le rôle référencé (à la même portée que le lien de rôle) ou si vous avez été autorisé à exécuter le verbe bind sur le rôle référencé. Par exemple, si l'user-1 n'a pas la possibilité de lister les Secrets à l'échelle du cluster, il ne peut pas créer un ClusterRoleBinding pour un rôle qui accorde cette permission. Pour permettre à un utilisateur de créer/mettre à jour des liaisons de rôle :

  1. Accordez-leur un rôle qui leur permet de créer/mettre à jour des objets RoleBinding ou ClusterRoleBinding, selon leurs besoins.
  2. Leur accorder les autorisations nécessaires pour lier un rôle particulier : implicitement, en leur donnant les permissions contenues dans le rôle. explicitement, en leur donnant la permission d'exécuter le verbe bind sur le rôle particulier (ou ClusterRole).

Par exemple, ce ClusterRole et ce RoleBinding permettraient à user-1 d'accorder à d'autres utilisateurs les rôles admin, edit et view dans l'espace de noms user-1-namespace :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["rolebindings"]
  verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
  resources: ["clusterroles"]
  verbs: ["bind"]
  # omit resourceNames to allow binding any ClusterRole
  resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: user-1-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: user-1

Lors du démarrage des premiers rôles et des premières liaisons de rôles, il est nécessaire d'accorder à l'utilisateur initial des autorisations qu'il n'a pas encore. Pour amorcer les premiers rôles et les premières liaisons de rôles :

  • Utilisez un identifiant avec le groupe "system:masters", qui est lié au rôle de super-utilisateur "cluster-admin" par les liaisons par défaut.

Utilitaires de ligne de commande

kubectl create role

Crée un objet Rôle définissant les autorisations au sein d'un espace de noms unique. Exemples :

  • Créer un rôle nommé "pod-reader" qui permet aux utilisateurs d'effectuer les opérations get, watch et list sur les pods :

    kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
    
  • Créer un rôle nommé "pod-reader" avec les resourceNames spécifiés:

    kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
  • Créer un rôle nommé "foo" avec les apiGroups spécifiés:

    kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
    
  • Créer un rôle nommé "foo" avec des permissions de sous-ressources:

    kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
    
  • Créer un rôle nommé "my-component-lease-holder" avec des permissions pour obtenir/mettre à jour une ressource avec un nom spécifique:

    kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component
    

kubectl create clusterrole

Crée un ClusterRole. Exemples:

  • Créer un ClusterRole nommé "pod-reader" qui permet à l'utilisateur d'effectuer les opérations get, watch et list sur les pods :

    kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
    
  • Créer un ClusterRole nommé "pod-reader" avec les resourceNames spécifiés :

    kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
    
  • Créer un ClusterRole nommé "foo" avec les apiGroups spécifiés:

    kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
    
  • Créer un ClusterRole nommé "foo" avec des permissions de sous-ressources :

    kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
    
  • Créer un ClusterRole nommé "foo" avec un nonResourceURL spécifié:

    kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
    
  • Créer un ClusterRole nommé "monitoring" avec une aggregationRule spécifiée:

    kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"
    

kubectl create rolebinding

Attribue un rôle ou un ClusterRole dans un espace de noms spécifique. Exemples:

  • Dans le namespace "acme", accordez les permissions du rôle de cluster "admin" à un utilisateur nommé "bob":

    kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
    
  • Dans le namespace "acme", accorder les permissions du CLusterRole "view" au compte de service du namespace "acme" nommé "myapp" :

    kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
    
  • Dans le namespace "acme", accorder les permissions du ClusterRole "view" à un compte de service de le namespace "myappnamespace" nommé "myapp" :

    kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
    

kubectl create clusterrolebinding

Attribue un ClusterRole à l'ensemble du cluster (tous les espaces de noms). Exemples:

  • Sur l'ensemble du cluster, accordez les permissions du ClusterRole "cluster-admin" à un utilisateur nommé "root":

    kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
    
  • Sur l'ensemble du cluster, accorder les permissions du ClusterRole "system:node-proxier" à un utilisateur nommé "system:kube-proxy":

    kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
    
  • Sur l'ensemble du cluster, accorder les permissions du ClusterRole "view" à un compte de service nommé "myapp" dans l'espace de noms "acme":

    kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
    

kubectl auth reconcile

Crée ou met à jour les objets de l'API rbac.authorization.k8s.io/v1 à partir d'un fichier manifeste.

Les objets manquants sont créés et le namespace contenant est créé pour les objets à namespace, si nécessaire.

Les rôles existants sont mis à jour pour inclure les autorisations dans les objets d'entrée, et supprimer les permissions supplémentaires si --remove-extra-permissions est spécifiée.

Les liaisons existantes sont mises à jour pour inclure les sujets dans les objets d'entrée, et supprimer les sujets supplémentaires si --remove-extra-subjects est spécifiée.

Exemples:

  • Test d'application d'un fichier manifeste d'objets RBAC, avec affichage des modifications apportées:

    kubectl auth reconcile -f my-rbac-rules.yaml --dry-run=client
    
  • Appliquer un fichier manifeste d'objets RBAC, en préservant toutes les autorisations supplémentaires (dans les rôles) et tous les sujets supplémentaires (dans les liaisons):

    kubectl auth reconcile -f my-rbac-rules.yaml
    
  • Appliquer un fichier manifeste d'objets RBAC, en supprimant toutes les autorisations supplémentaires (dans les rôles) et tous les sujets supplémentaires (dans les liaisons) :

    kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
    

Autorisations du ServiceAccount

Les règles RBAC par défaut accordent des autorisations aux composants du plan de contrôle, aux nœuds et aux contrôleurs, mais n'accordent aucunes permissions aux comptes de service en dehors du namespace kube-system (au-delà des autorisations de découverte accordées à tous les utilisateurs authentifiés).

Cela vous permet d'attribuer des rôles particuliers à des ServiceAccounts particuliers en fonction des besoins. Des attributions de rôles plus fines offrent une plus grande sécurité, mais demandent plus d'efforts de gestion. Des attributions plus larges peuvent donner un accès API inutile (et potentiellement escaladant) aux ServiceAccounts, mais elles sont plus faciles à administrer.

Dans l'ordre, de la plus sûre à la moins sûre, les approches sont les suivantes:

  1. Attribuer un rôle à un compte de service spécifique à une application (meilleure pratique)

    Cela nécessite que l'application spécifie un serviceAccountName dans son pod spec, et que le compte de service soit créé (via l'API, le manifeste de l'application, kubectl create serviceaccount, etc.).

    Par exemple, accorder au compte de service "my-sa" l'autorisation de lecture seule dans "my-namespace":

    kubectl create rolebinding my-sa-view \
      --clusterrole=view \
      --serviceaccount=my-namespace:my-sa \
      --namespace=my-namespace
    
  2. Attribuer un rôle au compte de service "par défaut" dans un namespace

    Si une application ne spécifie pas de serviceAccountName, elle utilise le compte de service "par défaut".

    Par exemple, accorder au compte de service "default" l'autorisation de lecture seule dans "my-namespace" :

    kubectl create rolebinding default-view \
      --clusterrole=view \
      --serviceaccount=my-namespace:default \
      --namespace=my-namespace
    

    De nombreux modules complémentaires s'exécutent sous le compte de service "default" dans le namespace du kube-system. Pour permettre à ces modules complémentaires de fonctionner avec un accès de super-utilisateur, accordez les permissions cluster-admin au compte de service "default" dans le namespace kube-system.

    kubectl create clusterrolebinding add-on-cluster-admin \
      --clusterrole=cluster-admin \
      --serviceaccount=kube-system:default
    
  3. Attribuer un rôle à tous les comptes de service d'un namespace

    Si vous souhaitez que toutes les applications d'un namespace disposent d'un rôle, quel que soit le compte de service qu'elles utilisent, vous pouvez attribuer un rôle au groupe de comptes de service de cet namespace.

    Par exemple, accordez l'autorisation de lecture seule dans "my-namespace" à tous les comptes de service de cet namespace:

    kubectl create rolebinding serviceaccounts-view \
      --clusterrole=view \
      --group=system:serviceaccounts:my-namespace \
      --namespace=my-namespace
    
  4. Accorder un rôle limité à tous les comptes de service à l'échelle du cluster (déconseillé)

    Si vous ne souhaitez pas gérer les autorisations par namespace, vous pouvez accorder un rôle à l'échelle du cluster à tous les comptes de service.

    Par exemple, accordez l'autorisation de lecture seule dans tous les espaces de noms à tous les comptes de service du cluster :

    kubectl create clusterrolebinding serviceaccounts-view \
      --clusterrole=view \
     --group=system:serviceaccounts
    
  5. Accorder un accès de super-utilisateur à tous les comptes de service à l'échelle du cluster (fortement déconseillé).

    Si vous ne vous souciez pas du tout des autorisations de partitionnement, vous pouvez accorder un accès de super-utilisateur à tous les comptes de service.

    kubectl create clusterrolebinding serviceaccounts-cluster-admin \
      --clusterrole=cluster-admin \
      --group=system:serviceaccounts
    

Accès en écriture pour les EndpointSlices et les Endpoints

Les clusters Kubernetes créés avant Kubernetes v1.22 incluent un accès en écriture à EndpointSlices (et Endpoints) dans les rôles agrégés "edit" et "admin". Pour pallier à la CVE-2021-25740, cet accès ne fait pas partie des rôles agrégés dans les clusters que vous créez à l'aide de Kubernetes v1.22 ou ultérieur.

Les clusters existants qui ont été mis à niveau vers Kubernetes v1.22 ne seront pas soumis à ce changement. L'annonce du CVE comprend des recommandations pour restreindre cet accès dans les clusters existants.

Si vous souhaitez que les nouveaux clusters conservent ce niveau d'accès dans les rôles agrégés, vous pouvez créer le ClusterRole suivant :

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    kubernetes.io/description: |-
      Add endpoints write permissions to the edit and admin roles. This was
      removed by default in 1.22 because of CVE-2021-25740. See
      https://issue.k8s.io/103675. This can allow writers to direct LoadBalancer
      or Ingress implementations to expose backend IPs that would not otherwise
      be accessible, and can circumvent network policies or security controls
      intended to prevent/isolate access to those backends.
      EndpointSlices were never included in the edit or admin roles, so there
      is nothing to restore for the EndpointSlice API.      
  labels:
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
  name: custom:aggregate-to-edit:endpoints # you can change this if you wish
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["create", "delete", "deletecollection", "patch", "update"]

Mise à niveau à partir d'ABAC

Les clusters qui exécutaient à l'origine d'anciennes versions de Kubernetes utilisaient souvent des politiques ABAC permissives, notamment en accordant un accès API complet à tous les comptes de service.

Les règles RBAC par défaut accordent des autorisations étendues aux composants du plan de contrôle, aux nœuds et aux contrôleurs, mais n'accordent aucune autorisation aux comptes de service en dehors du namespace kube-system (au-delà des autorisations de découverte accordées à tous les utilisateurs authentifiés).

Bien que beaucoup plus sûre, cette solution peut perturber les charges de travail existantes qui s'attendent à recevoir automatiquement les autorisations de l'API. Voici deux approches pour gérer cette transition:

Autorisateurs parallèles

Exécutez les autorisateurs RBAC et ABAC, et spécifiez un fichier de stratégie qui contient la stratégie ABAC existante:

--authorization-mode=...,RBAC,ABAC --authorization-policy-file=mypolicy.json

Pour expliquer en détail la première option de ligne de commande : si les autorisateurs précédents, tels que Node, refusent une demande, l'autorisateur RBAC tente d'autoriser la demande d'API. Si RBAC refuse également cette demande d'API, l'Authorizer ABAC est alors exécuté. Cela signifie que toute demande autorisée par les stratégies RBAC ou ABAC est autorisée.

Lorsque kube-apiserver est exécuté avec un niveau de log de 5 ou plus pour le composant RBAC (--vmodule=rbac*=5 ou --v=5), vous pouvez voir les refus RBAC dans le log du serveur API (préfixé par RBAC). Vous pouvez utiliser ces informations pour déterminer quels rôles doivent être accordés à quels utilisateurs, groupes ou comptes de service.

Une fois que vous avez accordé des rôles aux comptes de service et que les charges de travail fonctionnent sans message de refus RBAC dans les journaux du serveur, vous pouvez supprimer l'ABAC Authorizer.

Autorisations RBAC permissives

Vous pouvez répliquer une stratégie ABAC permissive à l'aide de liaisons de rôles RBAC.

Après la transition vers l'utilisation de RBAC, vous devez ajuster les contrôles d'accès pour votre cluster afin de vous assurer qu'ils répondent à vos besoins en matière de sécurité de l'information.