Что такое 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 и приложения внутри кластера.