Gymterview
middle

Как работает RBAC в Kubernetes?

RBAC (Role-Based Access Control) — механизм авторизации в Kubernetes, который определяет, какой субъект (пользователь, группа, сервисный аккаунт) может выполнять какие действия (глаголы) над какими ресурсами. RBAC включён по умолчанию и является основным инструментом управления доступом в кластере.

Основные объекты RBAC:

Объект Область действия Описание
Role Namespace Набор разрешений в пределах одного namespace
ClusterRole Кластер Набор разрешений на уровне всего кластера
RoleBinding Namespace Привязывает Role или ClusterRole к субъекту в рамках namespace
ClusterRoleBinding Кластер Привязывает ClusterRole к субъекту на уровне всего кластера

Субъекты RBAC:

  • User — обычный пользователь, управляемый внешней системой аутентификации (LDAP, OIDC и т.д.). Kubernetes не хранит учётные записи пользователей самостоятельно.
  • Group — группа пользователей для упрощения управления правами.
  • ServiceAccount — учётная запись для подов и внутренних сервисов кластера. В отличие от User, ServiceAccount — это полноценный ресурс Kubernetes.

1. Создание ServiceAccount для Java-приложения:

Пример
apiVersion: v1
kind: ServiceAccount
metadata:
  name: banking-service-sa
  namespace: banking
automountServiceAccountToken: false  # Не монтировать токен по умолчанию

Параметр automountServiceAccountToken: false означает, что токен сервисного аккаунта не будет автоматически смонтирован в файловую систему пода. Это важно, потому что смонтированный токен может быть использован злоумышленником для доступа к Kubernetes API при компрометации контейнера.

2. Role с минимальными правами (принцип наименьших привилегий):

Пример
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: banking-service-role
  namespace: banking
rules:
# Чтение ConfigMaps (для конфигурации приложения)
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "watch"]
  resourceNames: ["banking-service-config"]  # Доступ только к конкретному ConfigMap

# Чтение секретов (только конкретных)
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
  resourceNames: ["banking-db-credentials"]

Поле resourceNames ограничивает доступ конкретными именованными ресурсами — без него Role даёт доступ ко всем ресурсам указанного типа в namespace, что нарушает принцип наименьших привилегий.

3. RoleBinding — привязка роли к субъекту:

Пример
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: banking-service-binding
  namespace: banking
subjects:
- kind: ServiceAccount
  name: banking-service-sa
  namespace: banking
roleRef:
  kind: Role
  name: banking-service-role
  apiGroup: rbac.authorization.k8s.io

RoleBinding связывает субъект (ServiceAccount) с набором разрешений (Role). После создания этого ресурса сервисный аккаунт banking-service-sa получит только те права, которые определены в banking-service-role.

4. Использование ServiceAccount в Deployment:

Пример
apiVersion: apps/v1
kind: Deployment
metadata:
  name: banking-service
  namespace: banking
spec:
  template:
    spec:
      serviceAccountName: banking-service-sa
      automountServiceAccountToken: true  # Включить только если приложению нужен доступ к K8s API
      containers:
      - name: app
        image: registry.bank.local/banking-service:1.0.0

Значение automountServiceAccountToken: true на уровне Pod spec переопределяет настройку ServiceAccount. Устанавливайте его в true только в том случае, если приложению действительно необходим программный доступ к Kubernetes API (например, для service discovery или работы с ConfigMap).

5. ClusterRole для кросс-namespace доступа (пример для мониторинга):

Пример
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-reader
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods"]
  verbs: ["get", "list"]

ClusterRole отличается от Role тем, что работает на уровне всего кластера. Это необходимо, например, для систем мониторинга (Prometheus), которые должны собирать метрики из подов во всех namespace-ах.

Проверка прав (диагностика):

Пример
# Проверить, может ли ServiceAccount получить секреты
kubectl auth can-i get secrets \
    --as=system:serviceaccount:banking:banking-service-sa \
    -n banking

# Вывести все права ServiceAccount в данном namespace
kubectl auth can-i --list \
    --as=system:serviceaccount:banking:banking-service-sa \
    -n banking

Команда kubectl auth can-i позволяет проверить, имеет ли конкретный субъект право на выполнение определённого действия. Это полезно для аудита и отладки проблем с доступом.

Типичные ошибки при настройке RBAC:

Ошибка Почему это опасно Как правильно
Привязка cluster-admin к сервисному аккаунту приложения Даёт полные права на всё в кластере — любая компрометация контейнера ведёт к компрометации всего кластера Создавать отдельную Role с минимально необходимыми правами
Разрешение * (wildcard) на все ресурсы и глаголы Фактически эквивалент admin-доступа Указывать конкретные ресурсы и глаголы
Использование default ServiceAccount Имеет автоматически монтируемый токен и может иметь унаследованные права Создавать именованный ServiceAccount для каждого сервиса
Отсутствие resourceNames в Role Даёт доступ ко всем ресурсам данного типа, а не к конкретным Указывать resourceNames везде, где это возможно

Рекомендации для банковских систем:

  • Один микросервис — один ServiceAccount с минимально необходимыми правами. Это обеспечивает изоляцию: компрометация одного сервиса не даёт доступа к ресурсам другого.
  • Регулярный аудит RBAC с помощью специализированных инструментов: kubectl-who-can (кто имеет доступ к ресурсу), rbac-lookup (какие права у субъекта), rakkess (обзор прав в namespace).
  • Интеграция с корпоративным IdP (LDAP/Active Directory) через OIDC для аутентификации пользователей-администраторов.
  • Запрет automountServiceAccountToken по умолчанию — включать только для сервисов, которым действительно нужен доступ к Kubernetes API.