Как работает 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.