← Kubernetes: безопасность
8 мин · средне · Урок 3 из 3

RBAC: Role и RoleBinding

Четыре объекта RBAC, разбор полей Role и RoleBinding, и kubectl auth can-i как способ не гадать над 403.

Четыре объекта RBAC

ServiceAccount name: app-sa namespace: demo кому RoleBinding subjects: app-sa roleRef: pod-reader что Role name: pod-reader verbs: get, list
RoleBinding не хранит прав, в нём только два имени: кому и что.

RBAC (role-based access control) в Kubernetes опирается на четыре kind:

Типовая связка «дать 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"]

Разбор полей:

В 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: когда что

Роль и привязкаГде действуют права
Role + RoleBindingресурсы одного namespace
ClusterRole + RoleBindingnamespaced-ресурсы только этого namespace
ClusterRole + ClusterRoleBindingвесь кластер, включая nodes, PV, CRD

Распространённая ошибка: создать Role на nodes в каком-то namespace и получить отказ. Nodes это cluster-scoped ресурс, на namespace-уровне их нет вообще.

Что часто ломается

Связанные команды

# Создать 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

Коротко

Прошли материал до конца? Отметьте урок пройденным.