RBAC: Role и RoleBinding
Четыре объекта RBAC, разбор полей Role и RoleBinding, и kubectl auth can-i как способ не гадать над 403.
Четыре объекта RBAC
RBAC (role-based access control) в Kubernetes опирается на четыре kind:
- Role: набор разрешений внутри одного namespace.
- ClusterRole: то же, но кластерного уровня (или для cluster-wide ресурсов вроде nodes, persistentvolumes).
- RoleBinding: привязывает Role или ClusterRole к субъекту (ServiceAccount, User, Group) в конкретном namespace.
- ClusterRoleBinding: привязывает ClusterRole на кластер целиком.
Типовая связка «дать ServiceAccount в этом namespace такие-то права на такие-то ресурсы» собирается из первых трёх: Role описывает права, RoleBinding выдаёт их конкретному SA.
Role: что можно делать
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: demo
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
Разбор полей:
apiGroups: [""]. Пустая строка значит «core API group» (Pod, Service, ConfigMap, Secret, Namespace и т.д.). Для Deployment было бы["apps"], для Ingress["networking.k8s.io"].resources: ["pods", "pods/log"]. Это ресурсы, на которые выдаются права.pods/logэто subresource, который рулится отдельно от самогоpods. Без негоkubectl logsпадает, даже если Pod видны.verbs: какие операции. Канонический список:get,list,watch,create,update,patch,delete,deletecollection. Звёздочка*значит все.
В Role можно держать несколько rules, каждое со своим набором
apiGroups/resources/verbs.
RoleBinding: кому это разрешено
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-sa-can-read
namespace: demo
subjects:
- kind: ServiceAccount
name: app-sa
namespace: demo
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
subjects это массив, кому даются права. Виды: ServiceAccount, User,
Group. ServiceAccount всегда требует namespace, User/Group обычно
без него.
Забытый namespace у ServiceAccount в subjects не даёт ошибки:
RoleBinding создастся, а права не выдаст. Проверяют это командой
kubectl auth can-i get pods --as=system:serviceaccount:demo:app-sa.
roleRef определяет, что именно даётся. Здесь нельзя передумать после
создания: поле immutable, для смены роли надо удалить и пересоздать
RoleBinding.
Где живут ServiceAccount
Каждый Pod автоматически получает SA. По умолчанию это default из
того же namespace, монтируется как automountServiceAccountToken: true.
Внутри Pod токен лежит в /var/run/secrets/kubernetes.io/serviceaccount/,
оттуда приложение читает его и ходит в API-сервер.
Создать собственный SA:
kubectl create serviceaccount app-sa
Привязать к Pod:
spec:
serviceAccountName: app-sa
kubectl auth can-i: главный инструмент диагностики
Прежде чем гадать «почему оно 403», стоит спросить у API-сервера:
kubectl auth can-i get pods
kubectl auth can-i delete pods
Эта команда отвечает за текущего пользователя. Проверить за другого
subject помогает флаг --as (demo здесь - имя namespace, где живёт
SA):
kubectl auth can-i get pods --as=system:serviceaccount:demo:app-sa
kubectl auth can-i delete pods --as=system:serviceaccount:demo:app-sa
yes или no без долгих расследований. Для отладки сложных Role
очень помогает.
Role vs ClusterRole: когда что
- Доступ только к ресурсам внутри одного namespace: Role.
- Доступ к namespaced-ресурсам в нескольких namespace: ClusterRole плюс RoleBinding в каждом из них.
- Доступ к cluster-scoped ресурсам (nodes, namespaces, persistentvolumes, customresourcedefinitions): только ClusterRole плюс ClusterRoleBinding. RoleBinding на эти ресурсы не сработает.
| Роль и привязка | Где действуют права |
|---|---|
| Role + RoleBinding | ресурсы одного namespace |
| ClusterRole + RoleBinding | namespaced-ресурсы только этого namespace |
| ClusterRole + ClusterRoleBinding | весь кластер, включая nodes, PV, CRD |
Распространённая ошибка: создать Role на nodes в каком-то namespace
и получить отказ. Nodes это cluster-scoped ресурс, на namespace-уровне
их нет вообще.
Что часто ломается
- Привязали ClusterRole через RoleBinding и обнаружили, что cluster-scoped ресурсы не видны. RoleBinding ограничивает ClusterRole только namespaced-частью текущего namespace.
pods/logзабыли в resources,kubectl logsпадает с 403, аget podsработает.- Хотели поменять
roleRef, kubectl выдалRoleBinding.rbac.authorization.k8s.io "x" is invalid: roleRef: Invalid value: ...: cannot change roleRef. Удалить и создать заново.
Связанные команды
# Создать SA, Role, RoleBinding императивно
kubectl create serviceaccount app-sa
kubectl create role pod-reader \
--verb=get,list,watch \
--resource=pods,pods/log
kubectl create rolebinding app-sa-can-read \
--role=pod-reader \
--serviceaccount=demo:app-sa
# Что есть в Role
kubectl get role pod-reader -o yaml
kubectl describe rolebinding app-sa-can-read
# Проверить эффективные права
kubectl auth can-i get pods --as=system:serviceaccount:demo:app-sa
kubectl auth can-i delete pods --as=system:serviceaccount:demo:app-sa
# Структура полей
kubectl explain role.rules
kubectl explain rolebinding.subjects
kubectl explain rolebinding.roleRef
Коротко
- Role и RoleBinding работают внутри namespace, ClusterRole и ClusterRoleBinding - на весь кластер.
- В правиле
apiGroups: [""]означает core-группу; для Deployment нужнаapps. pods/logэто отдельный subresource: без негоkubectl logsдаёт 403 при работающемget pods.- У ServiceAccount в
subjectsобязателенnamespace, иначе привязка тихо не сработает. roleRefimmutable, роль меняют пересозданием RoleBinding.kubectl auth can-i ... --as=system:serviceaccount:<ns>:<sa>отвечает на вопрос о правах вместо угадывания.- Cluster-scoped ресурсы (nodes, PV, CRD) выдаются только через ClusterRole + ClusterRoleBinding.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс