Learning Platform
Глоссарий Troubleshooting
Урок 15.03 · 28 мин
Продвинутый
RBACRoleRoleBindingClusterRoleverbsAPI groupskubectl auth can-i

RBAC: Role-Based Access Control

RBAC отвечает на единственный вопрос: «У этого identity есть право выполнить эту операцию над этим ресурсом?». Identity — User, Group или ServiceAccount; операция — verb (get, list, create, …); ресурс — pods, deployments, secrets и т.д. Всё остальное — это сочетание четырёх объектов: Role + RoleBinding (namespaced) и ClusterRole + ClusterRoleBinding (cluster-scoped). На CKAD без RBAC не сдать одну-две задачи из 16; в production без RBAC — кластер не аудит-compliant.


sudo: super user, sudoers и принцип least privilege

Четыре объекта: scope-матрица

RBAC objects: namespaced vs cluster-scoped
RoleNamespaced object. Перечисляет правила (rules) — какие verbs на какие resources разрешены. Действует только в namespace, где создан. Привязывается через RoleBinding в том же namespace.
RoleBindingNamespaced object. Связывает Role (или ClusterRole — см. ниже) с subjects: User, Group, ServiceAccount. Действует только в своём namespace.
ClusterRoleCluster-scoped object. Перечисляет правила для cluster-scoped resources (nodes, persistent volumes, ClusterRoles сами) ИЛИ для namespaced ресурсов с возможностью переиспользования в любом namespace.
ClusterRoleBindingCluster-scoped object. Связывает ClusterRole с subjects на уровне всего кластера. Используется для cluster-admin permissions и для cluster-wide read-only ролей.
комбинацияRoleBinding может ссылаться на ClusterRole — это даёт permissions ClusterRole, но ограниченные namespace того RoleBinding. Это паттерн переиспользования: одна ClusterRole 'view' и куча RoleBindings в разных namespaces.
NOTE

Ключевая комбинация на CKAD: RoleBinding может ссылаться на ClusterRole. Это удобный способ переиспользовать built-in ClusterRoles (view, edit) на namespace-level. Никакой “доступ ко всему кластеру” от этого не появляется — RoleBinding всё ещё ограничен своим namespace.


Role: что в spec

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  resourceNames: ["my-app"]
  verbs: ["get", "patch"]

Структура rules — это список независимых правил, объединённых OR (permissions аддитивны):

  • apiGroups — список API groups. "" (пустая строка) — это core API group (Pods, Services, ConfigMaps, Nodes). Другие группы: apps (Deployment, StatefulSet), batch (Job, CronJob), networking.k8s.io (Ingress, NetworkPolicy), rbac.authorization.k8s.io, policy и т.д.
  • resources — типы ресурсов. Plural в lower-case: pods, не Pod. Подресурсы через слэш: pods/log (логи), pods/exec (exec), pods/portforward.
  • verbs — действия. get, list, watch, create, update, patch, delete, deletecollection, * (все).
  • resourceNames — опционально, ограничить правило конкретными именами ресурсов. Например, разрешить patch только Deployment my-app, а не любой.
WARNING

resourceNames работает только для verbs, которые указывают имя: get, update, patch, delete. Для list/watch/create resourceNames бесполезен — list возвращает всё, что разрешено по другим правилам.


Verbs: список и tricky cases

RBAC verbs
readget — получить один объект по имени. list — получить все объекты в scope. watch — long-poll API на изменения. Для view ClusterRole — это эти три verb на большинство ресурсов.
writecreate — создать новый объект. update — full update (PUT). patch — частичный update (PATCH, strategic merge или JSON patch). delete — удалить один. deletecollection — удалить все по селектору.
all* — все verbs. Используется в admin ClusterRoles. Анти-паттерн в namespace Role — обычно явно указывайте verbs.
non-resourceSpecial non-resource URLs: /healthz, /metrics, /version, /api. Для них используется nonResourceURLs вместо resources. Применимо только в ClusterRole.
customНекоторые resources имеют дополнительные verbs: pods/exec — verb 'create' на ресурс pods/exec; bind на ClusterRole; use на PodSecurityPolicy (deprecated); impersonate на users/groups/serviceaccounts.
DANGER

Privilege escalation paths: bind на ClusterRole позволяет создавать RoleBinding на эту ClusterRole — то есть давать другим её permissions. escalate позволяет создавать Roles/ClusterRoles с правами, превышающими ваши собственные (иначе apiserver запрещает). impersonate — выполнять запросы от имени другого user/SA. Эти три verbs дают эффективно admin доступ. Никогда не давайте их app-Pods.


RoleBinding: соединение Role и subjects

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-pod-reader
  namespace: default
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: default
- kind: User
  name: [email protected]
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: developers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Поля:

  • subjects — список identities, которым даём permissions. Три типа:
    • ServiceAccount — требует namespace (SA — namespaced object).
    • User — внешняя identity, обычно из OIDC/x509-сертификатов. K8s не управляет users.
    • Group — группа identities. Group attribution делает authenticator (OIDC groups claim, x509 OU и т.д.).
  • roleRef — на какую Role/ClusterRole ссылаемся. kind либо Role, либо ClusterRole. Поле immutable — нельзя поменять roleRef после создания, нужно удалить и пересоздать.
NOTE

roleRef immutable — это защита от accidental privilege escalation. Если бы можно было переключить RoleBinding с маленькой Role на cluster-admin ClusterRole, права subjects вырастали бы без видимого изменения. K8s заставляет удалять и пересоздавать — намного заметнее в audit logs.


ClusterRole: для чего

Три use-case ClusterRole:

  1. Cluster-scoped ресурсы — nodes, persistent volumes, storage classes, custom resource definitions. Role их не покрывает.
  2. Non-resource URLs/healthz, /metrics, /version. Только ClusterRole.
  3. Reusable templates для namespaced ресурсов — определить «view» один раз, привязать через RoleBinding в множестве namespaces.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list"]

Привязка через ClusterRoleBinding (cluster-wide) или RoleBinding (namespace-limited):

# Вариант 1: cluster-wide — alice видит pods во ВСЕХ namespaces
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: alice-cluster-reader
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-pod-reader
  apiGroup: rbac.authorization.k8s.io
---
# Вариант 2: namespace-limited — alice видит pods ТОЛЬКО в production
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: alice-prod-reader
  namespace: production
subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: cluster-pod-reader
  apiGroup: rbac.authorization.k8s.io

Built-in ClusterRoles

K8s поставляется с несколькими default ClusterRoles:

Built-in ClusterRoles
cluster-adminSuperuser, полный доступ ко всему. Verbs: * на * во всех API groups, плюс nonResourceURLs *. Используется ClusterRoleBinding-ом system:masters Group для kubectl admin доступа.
adminNamespace-scoped admin (через RoleBinding). Может создавать roles/rolebindings внутри namespace. Не может менять resource quotas namespace или сам namespace.
editМожет read/write большинство namespaced resources, но НЕ может менять roles, rolebindings, serviceaccounts, resource quotas. Удобная роль для разработчиков в dev namespaces.
viewRead-only большинства namespaced resources, ИСКЛЮЧАЯ secrets (нельзя читать). Это специально: иначе view-роль = scope для утечки credentials.
WARNING

Killer-момент: view ClusterRole не даёт доступ к Secrets. Это сделано специально — иначе view был бы способом утечки credentials. Если разработчику нужно читать Secrets — нужна отдельная Role или edit ClusterRole.


kubectl auth can-i: проверка permissions

# Могу я (текущий user) создать Deployment в default?
kubectl auth can-i create deployments

# Может ли SA app-sa в namespace default создать Pod?
kubectl auth can-i create pods --as=system:serviceaccount:default:app-sa

# Может ли SA читать Secrets в production?
kubectl auth can-i list secrets -n production \
  --as=system:serviceaccount:default:app-sa

# Все мои permissions
kubectl auth can-i --list

Формат --as для SA: system:serviceaccount:<namespace>:<sa-name>. Это формат, который apiserver видит при authentication запроса от Pod с этим SA. Это знание встретится на CKAD.

NOTE

kubectl auth can-i --list — must-know для troubleshooting RBAC. Показывает полный набор разрешений текущего user или указанного через —as. Сразу видно, чего не хватает.


Типовое CKAD-задание

Шаги, которые встретятся на экзамене:

# 1. Создать namespace
kubectl create namespace devops

# 2. Создать ServiceAccount
kubectl create serviceaccount deploy-sa -n devops

# 3. Создать Role (можно императивно)
kubectl create role deploy-manager \
  --verb=get,list,watch,create,update,patch \
  --resource=deployments,replicasets \
  -n devops

# 4. Создать RoleBinding
kubectl create rolebinding deploy-sa-binding \
  --role=deploy-manager \
  --serviceaccount=devops:deploy-sa \
  -n devops

# 5. Проверить
kubectl auth can-i create deployments \
  --as=system:serviceaccount:devops:deploy-sa \
  -n devops
# yes

kubectl auth can-i delete deployments \
  --as=system:serviceaccount:devops:deploy-sa \
  -n devops
# no

# 6. Использовать в Pod
kubectl run app --image=nginx \
  --overrides='{"spec":{"serviceAccountName":"deploy-sa"}}' \
  -n devops

На экзамене вместо kubectl create role чаще требуют YAML — но логика та же.


Aggregated ClusterRoles

Продвинутая фича: ClusterRole может агрегировать правила из других ClusterRoles по labels:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      rbac.example.com/aggregate-to-monitoring: "true"
rules: []  # будут заполнены controller'ом

Любой ClusterRole с label rbac.example.com/aggregate-to-monitoring: "true" автоматически вольёт свои rules в monitoring. Используется built-in admin, edit, view — они агрегируют ClusterRoles, добавляемые operators (Prometheus, Istio).

На CKAD это знать необязательно, но если в задаче встретится aggregationRule — не пугаться.


Проверка знанийKnowledge check
Нужно дать ServiceAccount право читать Pods в трёх namespaces (dev, staging, production). Какие объекты создать оптимально?
ОтветAnswer
Создать одну ClusterRole с правилами на Pods (get, list, watch), затем три RoleBinding'а в каждом namespace, ссылающихся на эту ClusterRole. Это паттерн reuse: ClusterRole определяет права один раз, RoleBinding ограничивает scope каждого namespace. Альтернатива (три Role + три RoleBinding) — дублирование.
Проверка знанийKnowledge check
Created RoleBinding ссылается на Role pod-reader. Хочется поменять ссылку на ClusterRole admin. kubectl edit прошёл? Что делать?
ОтветAnswer
Не прошёл — roleRef immutable. Это защита от тихого privilege escalation. Решение: kubectl delete rolebinding NAME, затем kubectl create rolebinding NAME с новым roleRef. В GitOps — манифест перезаписывается, оператор сам удаляет/создаёт.
Проверка знанийKnowledge check
ServiceAccount app-sa в namespace default привязан к built-in ClusterRole view через RoleBinding. Может ли app-sa прочитать Secret в default namespace?
ОтветAnswer
Нет. Built-in view ClusterRole намеренно исключает Secrets — иначе view был бы способом утечки credentials. Это часто упоминаемая на CKAD деталь. Для чтения Secrets нужна отдельная Role с verbs get/list на resources secrets.
Проверка знанийKnowledge check
Как проверить через kubectl, может ли SA monitoring-sa в namespace obs читать Pods во всех namespaces?
ОтветAnswer
kubectl auth can-i list pods -A --as=system:serviceaccount:obs:monitoring-sa. Формат --as для SA — system:serviceaccount:NS:NAME, флаг -A или --all-namespaces проверяет cross-namespace. Если ответ yes — значит SA имеет ClusterRoleBinding на роль с pods get/list/watch. Если yes per-namespace, но no при -A — нужен ClusterRoleBinding.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 5. Нужно дать SA право читать Pods в трёх разных namespaces (dev, staging, production). Какой паттерн оптимален?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5