Что такое ServiceAccount и как он связан с RBAC?
Что такое ServiceAccount
ServiceAccount — это объект Kubernetes, представляющий учётные данные, которые используют процессы внутри кластера (обычно контейнеры в Pod) для аутентификации перед API-сервером. Каждая namespace имеет набор ServiceAccount; если в Pod не задано serviceAccountName, по умолчанию используется default в том же namespace. ServiceAccount — namespaced ресурс, он нужен не для пользователей людей, а для машин/контейнеров.
Pod получает учётные данные ServiceAccount автоматически: ранее это делалось через секрет типа kubernetes.io/service-account-token, который монтировался в контейнер как файл с bearer-токеном; в современных версиях чаще используются механизмы TokenRequest + projected service account tokens — временные, привязанные к Pod токены с ограниченным временем жизни и указанием audience. Монтирование токена можно отключить флагом automountServiceAccountToken: false в Pod/ServiceAccount, если токен не нужен.
Как это связано с RBAC
RBAC (Role-Based Access Control) управляет правами доступа к ресурсам Kubernetes. ServiceAccount выступает одним из типов субъектов (subject) в RBAC и может получать права через привязки ролей:
-
Role — набор правил (rules) в пределах namespace. Правило описывает apiGroups, resources, verbs (например, get, list, watch, create, update, delete). Role действует только в своём namespace.
-
ClusterRole — похожа на Role, но с кластерной областю применения (может содержать правила на ресурсы кластерного уровня или быть переиспользована для многих namespace).
-
RoleBinding — привязывает Role или ClusterRole к субъектам (пользователям, группам или ServiceAccount) в конкретном namespace. Через RoleBinding можно ссылаться как на Role, так и на ClusterRole. RoleBinding ограничен namespace; binding действует для указанных subjects в этом namespace.
-
ClusterRoleBinding — привязка ClusterRole на уровне всего кластера; позволяет назначать права ServiceAccount независимо от namespace (обычно указывается namespace в subject).
Пример: если вы хотите, чтобы приложение могло читать ConfigMap только в своём namespace, создаёте ServiceAccount, Role с verbs: ["get","list"] для ресурса configmaps, а затем RoleBinding, который связывает Role с этим ServiceAccount.
Пример манифестов (упрощённо)
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: my-ns
\---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-reader
namespace: my-ns
rules:
\- apiGroups: \[""\]
resources: \["configmaps"\]
verbs: \["get", "list"\]
\---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-configmap-reader
namespace: my-ns
subjects:
\- kind: ServiceAccount
name: my-app-sa
namespace: my-ns
roleRef:
kind: Role
name: configmap-reader
apiGroup: rbac.authorization.k8s.io
В Pod указываете:
spec:
serviceAccountName: my-app-sa
Практические детали и рекомендации
-
Принцип наименьших привилегий: давайте ServiceAccount только те права, которые реально нужны приложению.
-
Не используйте default ServiceAccount для production-нагрузок — создавайте отдельные SA и привязывайте минимальные роли.
-
Отключайте автоматическое монтирование токена (automountServiceAccountToken: false) для Pod, которые не обращаются к API.
-
Для краткоживущих токенов и безопасного использования в мультисервисных сценариях пользуйтесь projected service account tokens (TokenRequest), они поддерживают аудиторию и срок жизни.
-
RoleBinding в namespace может привязать ClusterRole — это удобный способ дать одинаковые права разным namespace без дублирования Role. ClusterRoleBinding даёт права глобально и требует осторожности.
-
ServiceAccount — основной инструмент для аутентификации и авторизации контроллеров, CI/CD агентов, operators и приложения внутри кластера.