Акция Панель управления ispmanager для VDS — первый месяц бесплатно
до 31.07.2026 Подробнее
Выберите продукт

Kubernetes RBAC for CI/CD: ServiceAccount, RoleBinding and least privilege

Разберём Kubernetes RBAC с позиции DevOps и CI/CD: как выдавать минимальные права ServiceAccount, когда выбирать RoleBinding или ClusterRoleBinding, как быстро проверять доступ kubectl auth can-i и избегать типовых ошибок в правилах.
Kubernetes RBAC for CI/CD: ServiceAccount, RoleBinding and least privilege

Kubernetes RBAC чаще всего вспоминают в момент, когда пайплайн внезапно получает Forbidden, а «быстрый фикс» в виде cluster-admin уже однажды приводил к инцидентам. Ниже — практичный подход к RBAC для DevOps/CI: как проектировать права под пайплайны, как использовать ServiceAccount, чем отличаются RoleBinding и ClusterRoleBinding, как применять принцип least privilege и как быстро диагностировать доступ командой kubectl auth can-i.

RBAC в Kubernetes: что реально проверяется

RBAC (Role-Based Access Control) отвечает на вопрос: «может ли конкретный субъект выполнить конкретное действие над конкретным ресурсом». Проверка строится на тройке:

  • кто: пользователь, группа или ServiceAccount;
  • что делает: get, list, watch, create, update, patch, delete (и специальные глаголы вроде impersonate);
  • над чем: ресурс (pods, deployments, jobs, secrets), API-группа и область видимости (namespace или cluster).

Частая ловушка: RBAC не «даёт доступ к namespace целиком», он даёт доступ к конкретным ресурсам и операциям. Поэтому запрос «дай доступ в неймспейс» на практике превращается в набор правил на наиболее используемые ресурсы и подресурсы этого неймспейса.

Если сомневаетесь, какие права нужны пайплайну, начните с минимального набора (read-only), а затем добавляйте точечно то, что ломает деплой. Это и есть рабочая тактика least privilege.

Role и ClusterRole: где живут правила

Role — набор правил в пределах одного namespace. Подходит, когда CI управляет объектами внутри конкретного окружения: например, dev или staging.

ClusterRole — набор правил на уровне кластера. Он нужен в двух случаях:

  • ресурс кластерный (например, nodes, persistentvolumes, namespaces, clusterroles);
  • вы хотите переиспользовать один и тот же набор правил в разных namespaces (а привязки делать отдельно).

Вторая причина особенно удобна в GitOps: один набор правил хранится в одном месте, а область действия ограничивается привязками.

RoleBinding и ClusterRoleBinding: что к чему привязывает

RoleBinding создаётся в namespace и выдаёт права субъекту в рамках этого namespace. Он может ссылаться как на Role, так и на ClusterRole.

ClusterRoleBinding выдаёт права на весь кластер (или на все namespaces для namespaced-ресурсов). Для CI это обычно «слишком широко», использовать стоит только по необходимости и с понятным обоснованием.

Схема связей ServiceAccount, Role/ClusterRole и RoleBinding/ClusterRoleBinding в Kubernetes

ServiceAccount для CI: базовый шаблон

Для пайплайна правильный субъект почти всегда — отдельный ServiceAccount в нужном namespace. Он живёт рядом с приложением и хорошо ревьюится в репозитории манифестов.

Минимальная конструкция: ServiceAccount + Role (или ClusterRole) + RoleBinding.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Пример: деплой приложения в одном namespace без прав «на всё»

Ниже — пример, который обычно покрывает типовой CI-деплой: обновить Deployment, посмотреть статус Pods/ReplicaSets, читать события, при необходимости оценить прогресс rollout. Обратите внимание: мы не даём доступ к secrets и не выдаём delete «на всякий случай».

apiVersion: v1
kind: Namespace
metadata:
  name: staging
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-deployer
  namespace: staging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ci-deployer-role
  namespace: staging
rules:
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods", "pods/log", "events"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-deployer-binding
  namespace: staging
subjects:
  - kind: ServiceAccount
    name: ci-deployer
    namespace: staging
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ci-deployer-role

Что это даёт на практике:

  • пайплайн сможет применить патч к Deployment (например, поменять image tag);
  • сможет читать состояние подов и логи (если оставили pods/log);
  • не сможет читать секреты, создавать CRD, трогать другие namespaces.

Least privilege в CI/CD: как не скатиться в cluster-admin

Принцип least privilege удобнее внедрять не как «идеальную схему сразу», а как процесс:

  1. Определите границу ответственности: один namespace (лучше) или несколько (реже).
  2. Выдайте read-only на ключевые ресурсы (get/list/watch).
  3. Добавляйте write-доступ строго под операции пайплайна (часто patch/update на deployments, иногда create на jobs).
  4. Отдельно решите вопрос с секретами: CI почти никогда не должен читать Kubernetes Secrets «как есть».

Почему чтение Secrets — самый частый RBAC-антипаттерн

Если дать CI права get на secrets, вы фактически превращаете любой компрометированный runner/токен в ключ от всех учёток приложения в этом namespace. Даже если «runner внутри периметра», это плохой размен.

Практичнее:

  • передавать секреты в CI через защищённое хранилище переменных (а в кластер — через отдельный процесс доставки секретов);
  • разделять «деплой» и «управление секретами» разными ServiceAccount с разными правами;
  • если очень нужно — ограничивать доступ к секретам по именам через resourceNames и документировать риск.

Если тема управления секретами у вас болит регулярно, посмотрите практику ротации и разделения доступа в материале про секреты в Docker Compose: ротация секретов и безопасная работа с ними.

ClusterRole + RoleBinding: переиспользуем правила и не расширяем область

Для нескольких окружений часто хочется иметь один общий набор правил (чтобы не копировать Role в каждый namespace). Здесь удобна связка: ClusterRole с правилами + RoleBinding в каждом namespace.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ci-deployer-common
rules:
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods", "pods/log", "events"]
    verbs: ["get", "list", "watch"]

И привязка в конкретном namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-deployer-common-binding
  namespace: staging
subjects:
  - kind: ServiceAccount
    name: ci-deployer
    namespace: staging
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ci-deployer-common

Ключевой смысл: правила лежат «глобально», но применяются только там, где вы сделали RoleBinding.

Когда без ClusterRoleBinding действительно не обойтись

Для DevOps/CI это редкие, но реальные кейсы:

  • pipeline управляет объектами в разных namespaces без заранее известного списка (например, создаёт namespace под preview-окружение);
  • нужно управлять кластерными ресурсами (например, namespaces, nodes, некоторыми объектами контроллеров/операторов);
  • нужно работать с политиками/допусками на уровне кластера (в зависимости от вашего стека).

Если вы дошли до ClusterRoleBinding, остановитесь и зафиксируйте, почему это оправдано. В большинстве продуктовых деплоев это избыточно.

Диагностика ошибки Forbidden в CI с помощью kubectl auth can-i

Диагностика RBAC: kubectl auth can-i и «почему Forbidden»

Команда kubectl auth can-i помогает быстро понять, проблема в RBAC или в чём-то ещё. Её удобно запускать локально и прямо в CI (как диагностический шаг при падении).

Быстрые проверки

kubectl auth can-i patch deployment -n staging
kubectl auth can-i get pods -n staging
kubectl auth can-i get secrets -n staging

Чтобы проверить права конкретного ServiceAccount, используйте impersonation:

kubectl auth can-i update deployments -n staging --as=system:serviceaccount:staging:ci-deployer
kubectl auth can-i create jobs -n staging --as=system:serviceaccount:staging:ci-deployer

Также полезно посмотреть «карту» разрешений целиком:

kubectl auth can-i --list -n staging --as=system:serviceaccount:staging:ci-deployer

Типовые причины ошибок доступа

  • Не та API-группа. Например, deployments живут в apps, а не в core-группе "".
  • Не тот ресурс. pods/log — отдельный подресурс, на него нужны отдельные правила.
  • Не тот глагол. kubectl apply часто делает patch, а не update.
  • Не тот namespace. RoleBinding действует только там, где создан.
  • Ожидали, что ClusterRole «сам применится». Нет, нужна привязка (RoleBinding или ClusterRoleBinding).

Практика для CI: два ServiceAccount лучше, чем один «универсальный»

В больших проектах удобно разделять роли:

  • ci-deployer: обновляет workload-ресурсы (Deployment/StatefulSet), читает статус, смотрит логи;
  • ci-migrator (опционально): создаёт Job для миграций или выполняет ad-hoc задачи в кластере.

Почему это полезно: миграции часто требуют больше прав или доступа к сервисам, и безопаснее изолировать риск отдельным токеном/учёткой и отдельным сроком жизни доступа.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Мини-чеклист ревью RBAC для пайплайна

  • Есть отдельный ServiceAccount под пайплайн (не default).
  • Используется RoleBinding в нужном namespace; ClusterRoleBinding — только если обосновано.
  • Нет прав на secrets без крайней необходимости; если есть — ограничены resourceNames и всё задокументировано.
  • Есть быстрые проверки через kubectl auth can-i (в идеале — как диагностический шаг при падении).
  • Набор глаголов минимален: чаще достаточно get/list/watch плюс patch/update на конкретные ресурсы.

Итог

Kubernetes RBAC для DevOps/CI — это не про «сделать, чтобы работало любой ценой», а про управляемые и проверяемые границы. Делайте пайплайны субъектами через ServiceAccount, выдавайте права через RoleBinding в конкретных namespaces, избегайте ClusterRoleBinding без причины и всегда подтверждайте гипотезы командой kubectl auth can-i. Такой подход обычно даёт и безопасность (least privilege), и предсказуемость деплоев.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: mount: wrong fs type, bad option, bad superblock — как быстро найти и исправить причину

Ошибка mount: wrong fs type, bad option, bad superblock в Debian/Ubuntu может означать и простую опечатку в имени раздела, и пробл ...
Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: XFS metadata corruption и emergency read-only — пошаговое восстановление

Если XFS-раздел внезапно стал доступен только для чтения, а сервер ушёл в emergency mode, главное — не спешить. Разберём безопасны ...
Debian/Ubuntu: как исправить Failed to fetch при apt update OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить Failed to fetch при apt update

Ошибка Failed to fetch при apt update в Debian и Ubuntu обычно связана не с самим APT, а с DNS, сетью, зеркалом, прокси, временем ...