Полное руководство по созданию ролей в Kubernetes: от Role до ClusterRole | AdminWiki
Timeweb Cloud — сервера, Kubernetes, S3, Terraform. Лучшие цены IaaS.
Попробовать

Полное руководство по созданию ролей в Kubernetes: от Role до ClusterRole

05 апреля 2026 10 мин. чтения

Управление доступом в Kubernetes часто начинается с использования встроенных ролей вроде cluster-admin или admin. Это быстро, но опасно: избыточные права — главный вектор атак и причина инцидентов в кластере. Данное руководство — это практический пошаговый план по переходу от широких прав к гранулярному контролю. Вы научитесь создавать безопасные кастомные роли для конкретных задач: от изоляции команд разработки до настройки минимально необходимых прав для CI/CD-систем вроде ArgoCD. Все инструкции проверены на практике в production-средах и сопровождаются готовыми YAML-манифестами, которые можно адаптировать под вашу инфраструктуру.

Мы начнем с основ RBAC и различий между Role и ClusterRole, затем детально разберем структуру правил доступа, включая работу с API-группами и неименованными ресурсами. Основное внимание уделим решению двух высокоприоритетных задач: безопасной интеграции ArgoCD и созданию изолированных ролей для команд dev, staging и prod. В завершение вы получите методологию аудита существующих прав и чек-лист для отладки типовых проблем.

Зачем вам кастомные роли? От базовых концепций RBAC к практической необходимости

RBAC (Role-Based Access Control) — стандартный механизм управления доступом в Kubernetes, основанный на принципе наименьших привилегий (Least Privilege). Его суть в том, что пользователь или сервис получает ровно те права, которые необходимы для выполнения задачи, и не более. Использование встроенной роли cluster-admin для служебного ServiceAccount ArgoCD или admin для всей команды разработки — это грубое нарушение этого принципа, которое может привести к катастрофическим последствиям: от случайного удаления production-нагрузки до полной компрометации кластера через атаку на уязвимый под.

Кастомные роли — это инструмент точной настройки. Они позволяют:

  • Повысить безопасность: ограничить потенциальный ущерб от ошибок или компрометации одной учетной записи.
  • Соответствовать compliance-требованиям: реализовать разделение обязанностей (SoD) между командами.
  • Упростить аудит: четко видеть, кто и к каким ресурсам имеет доступ.

Ключевые сущности RBAC, которые мы будем использовать:

  • Role / ClusterRole: набор правил, определяющих права на ресурсы.
  • ServiceAccount: учетная запись для программного доступа (поды, CI/CD).
  • RoleBinding / ClusterRoleBinding: связь между ролью и субъектом (пользователем, группой, ServiceAccount).

Role vs ClusterRole: в чем разница и когда что использовать

Выбор между Role и ClusterRole — первый и критически важный шаг. Ошибка приведет к тому, что правила доступа просто не будут работать.

Сущность Область видимости Когда использовать Пример
Role Один конкретный Namespace. Права для команды или сервиса в рамках одного проекта/среды (например, доступ к Pods в namespace staging). Разработчики имеют полный доступ к ресурсам в namespace: dev.
ClusterRole Весь кластер (кластерные ресурсы) или шаблон для нескольких Namespace. 1. Доступ к кластерным ресурсам (Nodes, PersistentVolumes). 2. Права, которые должны быть одинаковыми в нескольких Namespace. 3. Использование в агрегированных ClusterRole. 1. Мониторинговый сервис читает метрики Nodes. 2. Роль для ArgoCD, управляющего приложениями в разных Namespace.

Важное замечание: ClusterRole можно привязать к субъекту в конкретном Namespace через RoleBinding. В этом случае права из ClusterRole будут действовать только в пределах этого Namespace. Это удобный шаблон для тиражирования одинаковых правил.

Строим Role с нуля: ресурсы, API-группы и глаголы доступа

Структура манифеста Role или ClusterRole основана на трех ключевых полях: apiGroups, resources и verbs. Понимание каждого из них — залог создания корректной роли.

  • apiGroups: Группа API, к которой принадлежит ресурс. Для основных ресурсов (Pods, Services, ConfigMaps) используется пустая строка "" (часто называемая "core"). Для других — "apps/v1" (Deployments, StatefulSets), "networking.k8s.io/v1" (Ingress), "rbac.authorization.k8s.io/v1" (Role, RoleBinding). Узнать группу можно командой: kubectl api-resources.
  • resources: Множественное имя ресурса (например, pods, deployments, secrets).
  • verbs: Действия, которые можно совершать. Основные: get, list, watch (чтение), create, update, patch, delete (запись). Реже: deletecollection, impersonate, bind.

Пример минимальной роли, разрешающей чтение Pods и Deployments в namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-viewer
  namespace: my-app
rules:
- apiGroups: [""] # Core API
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps/v1"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]

Особый случай: доступ к неименованным ресурсам и субресурсам

Некоторые операции в Kubernetes не привязаны к конкретному ресурсу с именем. Например, чтение логов (kubectl logs) или выполнение команды в контейнере (kubectl exec). Для них используются специальные правила.

  • Неименованные ресурсы (nonResourceURLs): Это пути к API, не являющиеся объектами (например, /api, /apis, /healthz, /logs). Доступ к ним настраивается только в ClusterRole.
  • Субресурсы (subresources): Часть именованного ресурса. Указываются через слэш: pods/log, pods/exec, pods/portforward.

Пример ClusterRole, разрешающей чтение логов, но запрещающей выполнение команд в подах:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: log-reader-only
rules:
- apiGroups: [""]
  resources: ["pods/log"] # Субресурс
  verbs: ["get", "list"]
- nonResourceURLs: ["/logs"] # Неименованный ресурс
  verbs: ["get"]
# Права на pods/exec НЕ включены — это намеренное ограничение.

Предупреждение о безопасности: Право pods/exec эквивалентно получению root-доступа в контейнере. Выдавайте его с крайней осторожностью и только тем субъектам, которым это абсолютно необходимо для отладки.

Практика: безопасная настройка доступа для ArgoCD (CI/CD)

Типичная ошибка — использование ServiceAccount с ролью cluster-admin для ArgoCD. Это дает инструменту непрерывного развертывания неограниченную власть над кластером, включая возможность читать любые Secrets или удалять системные компоненты. Наша задача — создать минимально достаточный набор прав.

Постановка задачи: ServiceAccount для ArgoCD должен иметь возможность создавать, обновлять и удалять рабочие нагрузки (Deployments, Services, Ingress) в целевых namespace, но не иметь доступа к управлению самим ArgoCD, Secrets других приложений или кластерными ресурсами.

Решение:

  1. Создаем отдельный namespace argocd (если еще не создан).
  2. Создаем ServiceAccount argocd-manager в этом namespace.
  3. Создаем ClusterRole с правами только на целевые ресурсы в целевых namespace. Явно запрещаем доступ к ресурсам в namespace argocd и к Secrets.
  4. Привязываем роль через ClusterRoleBinding, ограничивая ее действие только на нужные namespace с помощью RoleBinding в каждом из них (рекомендуемый способ) или через одно ClusterRoleBinding, если ArgoCD управляет многими namespace.

Пример ClusterRole для ArgoCD:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: argocd-manager-role
rules:
# Правило для основных рабочих нагрузок
- apiGroups: ["apps", ""]
  resources: ["deployments", "statefulsets", "daemonsets", "replicasets", "services", "configmaps", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Правило для Ingress
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Правило для чтения Secrets ТОЛЬКО в namespace argocd (для собственной конфигурации)
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
  resourceNames: ["argocd-secret"] # Конкретный секрет
  # Ограничение по namespace будет задано в RoleBinding, а не здесь.

Далее создаем RoleBinding в каждом целевом namespace (например, my-app-production), который связывает наш ClusterRole с ServiceAccount ArgoCD:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: argocd-manager-binding
  namespace: my-app-production # Целевой namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: argocd-manager-role
subjects:
- kind: ServiceAccount
  name: argocd-manager
  namespace: argocd # Namespace, где создан ServiceAccount

Такой подход изолирует права ArgoCD в каждом namespace и соответствует принципу наименьших привилегий. Для более глубокого понимания работы с развертываниями рекомендуем наше полное руководство по Kubernetes Deployment.

Альтернатива: использование AppProject для изоляции внутри ArgoCD

ArgoCD предоставляет встроенный механизм AppProject для дополнительной изоляции. Вместо того чтобы полагаться только на RBAC Kubernetes, вы можете ограничить, к каким ресурсам, кластерам и namespace имеет доступ каждое приложение ArgoCD. Это создает второй уровень защиты.

В AppProject можно задать:

  • Разрешенные источники (репозитории Git).
  • Разрешенные целевые namespace.
  • Разрешенные кластеры (для мультикластерных сценариев).
  • Список ресурсов, которые можно/нельзя изменять (например, запрет на изменение ресурсов Kind: Secret).

Сочетание тонко настроенного RBAC на уровне Kubernetes и политик AppProject в ArgoCD дает максимально безопасную конфигурацию. Подробнее о настройке ArgoCD читайте в нашем отдельном руководстве.

Изоляция команд: роли для dev, staging и prod в одном кластере

Организация работы нескольких команд в одном кластере требует четкого разделения прав. Цель — предотвратить ситуацию, когда разработчик по ошибке удалил ресурс в production.

Архитектура решения:

  1. Создаем отдельные namespace: project-dev, project-staging, project-prod.
  2. Создаем ServiceAccount для каждой команды или среды.
  3. Создаем специфичные Role в каждом namespace.
  4. Привязываем роли через RoleBinding внутри соответствующих namespace.
  5. Дополняем изоляцию ResourceQuota и LimitRange для контроля за ресурсами.

Пример роли для разработчиков (namespace: project-dev):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: project-dev
  name: developer-full-access
rules:
- apiGroups: ["", "apps", "networking.k8s.io", "batch"]
  resources: ["*"] # Полный доступ ко всем ресурсам в этих группах
  verbs: ["*"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"] # К Secrets — только чтение

Пример роли для инженеров staging (namespace: project-staging):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: project-staging
  name: staging-engineer
rules:
- apiGroups: ["", "apps"]
  resources: ["deployments", "services", "pods", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch"] # Нет delete
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
# Дополнительно: RoleBinding, дающее этой роли права на чтение в project-prod

Пример роли для продакшен-инженеров (namespace: project-prod):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: project-prod
  name: production-operator
rules:
- apiGroups: ["", "apps"]
  resources: ["deployments", "services", "pods"]
  verbs: ["get", "list", "watch", "patch"] # Только patch, нет update/delete
- apiGroups: ["batch"]
  resources: ["jobs", "cronjobs"]
  verbs: ["get", "list", "watch"]
# Явный запрет на delete в любых ресурсах

Такая схема гарантирует, что права каждой команды ограничены своей зоной ответственности, а доступ к production — максимально ограничен и контролируем.

От аудита к безопасности: как декомпозировать широкие роли

Если в вашем кластере уже используются широкие роли (например, многие ServiceAccount привязаны к cluster-admin), необходим планомерный подход к исправлению ситуации. Резкая отмена прав может сломать рабочие процессы.

Методология декомпозиции:

  1. Аудит текущих привязок:
    kubectl get clusterrolebindings -o wide && kubectl get rolebindings --all-namespaces -o wide
    Определите, какие ServiceAccount или пользователи имеют избыточные права.
  2. Анализ реального использования прав: Используйте команду kubectl auth can-i --as=system:serviceaccount:<namespace>:<sa-name> <verb> <resource> для проверки гипотез. Но лучше — анализ логов аудита кластера (audit logs), чтобы увидеть, какие API-вызовы действительно делает сервис.
  3. Создание новой, узкой роли: На основе данных аудита создайте Role или ClusterRole с минимально необходимыми правами.
  4. Параллельная привязка и тестирование: Создайте новое RoleBinding для ServiceAccount, оставив старое. Протестируйте работу сервиса с новыми правами. Инструменты вроде rbac-lookup помогут визуализировать привязки.
  5. Удаление старой привязки: После успешного тестирования удалите старый RoleBinding или ClusterRoleBinding.

Инструменты проверки: kubectl auth can-i и не только

Команда kubectl auth can-i — основной инструмент для проверки прав.

  • Проверка от имени конкретного ServiceAccount:
    kubectl auth can-i create deployments --as=system:serviceaccount:argocd:argocd-manager -n my-app
  • Проверка всех прав для ServiceAccount в namespace (с помощью плагина kubectl-who-can или скриптов).
  • Просмотр эффективных прав:
    kubectl describe rolebinding <binding-name> -n <namespace>

Для анализа сложных связей и поиска неиспользуемых прав рекомендуется настроить сбор аудит-логов кластера и использовать специализированные инструменты анализа RBAC. Если вы работаете с кастомными ресурсами, убедитесь в их корректности с помощью гайда по диагностике Custom Resources.

Чек-лист безопасности и отладка типовых проблем

Чек-лист безопасности при создании ролей:

  1. Принцип наименьших привилегий: Каждая роль должна решать одну конкретную задачу.
  2. Запрет на wildcard ('*') в ресурсах: Избегайте resources: ["*"], особенно в сочетании с широкими глаголами. Явно перечисляйте ресурсы.
  3. Осторожность с глаголами write: update, patch, delete должны быть явно обоснованы.
  4. Избегайте опасных комбинаций: Например, create pods + patch pods позволяет запустить произвольный контейнер. Если такая комбинация необходима, рассмотрите использование Pod Security Standards.
  5. Проверка манифестов: Всегда используйте kubectl apply --dry-run=client -f role.yaml перед применением.

Алгоритм отладки проблем с доступом:

  1. Существуют ли объекты?
    kubectl get serviceaccount <name> -n <namespace>
    kubectl get role/rolebinding <name> -n <namespace>
  2. Правильно ли они связаны?
    Проверьте roleRef в RoleBinding: ссылается ли он на правильную роль? Совпадают ли apiGroup и kind?
    Проверьте subjects в RoleBinding: правильно ли указаны kind, name и namespace ServiceAccount?
  3. Действуют ли права?
    Используйте kubectl auth can-i для проверки конкретного действия от имени ServiceAccount.
  4. Есть ли ошибки в событиях?
    kubectl get events -n <namespace> --sort-by='.lastTimestamp'

Таблица частых ошибок:

Симптом Возможная причина Решение
"User cannot list pods in namespace" 1. RoleBinding ссылается на Role в другом namespace.
2. В правилах Role отсутствует глагол list.
3. ServiceAccount не указан в subjects RoleBinding.
Проверить namespace всех объектов. Проверить verbs в Role. Проверить subjects в RoleBinding.
Права есть, но операция запрещена (403) 1. Попытка доступа к субресурсу (logs, exec) без явного правила.
2. Admission Webhook (например, Pod Security) блокирует операцию.
Добавить правило для субресурса (pods/log). Проверить логи admission-контроллеров.
RoleBinding есть, но права не применяются Используется RoleBinding для привязки ClusterRole, но не указан namespace в metadata RoleBinding. Убедиться, что RoleBinding создан в нужном namespace и его metadata.namespace указан.

Создание гранулярных ролей — это непрерывный процесс, тесно связанный с развитием вашей инфраструктуры. Регулярный аудит прав, использование представленных практик и инструментов позволит поддерживать высокий уровень безопасности кластера без ущерба для эффективности работы команд.

Поделиться:
Сохранить гайд? В закладки браузера