Базовая безопасность: RBAC и доступы

Рейтинг: 60.1% · 14 голосов
Kubernetes для разработчиков: поды, деплойменты, сервисы, ingress, конфиги и отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
anton_k8s
Сообщения: 26
Зарегистрирован: 12 май 2026, 03:23

Базовая безопасность: RBAC и доступы

Сообщение anton_k8s »

АкадемияKubernetes на практикеГлава 13 из 19
Оглавление курса (19)
  1. Зачем нужен Kubernetes и из чего состоит кластер
  2. Поднимаем локальный кластер: minikube и kind
  3. Поды: базовая единица запуска
  4. Deployment и ReplicaSet: управляем репликами
  5. Service: сетевой доступ к подам
  6. ConfigMap и Secret: выносим конфигурацию
  7. Ingress: пускаем трафик снаружи
  8. Хранилище: Volumes и PersistentVolumeClaim
  9. Namespaces, requests и limits
  10. Health checks: liveness и readiness пробы
  11. Отладка: почему под не стартует
  12. Helm: пакетный менеджер для Kubernetes
  13. Базовая безопасность: RBAC и доступы (вы здесь)
  14. Job и CronJob: разовые и периодические задачи
  15. StatefulSet и DaemonSet: stateful-нагрузки и системные агенты
  16. Стратегии обновления и планирование: rollout и rollback, graceful shutdown, nodeSelector, affinity, taints
  17. Автомасштабирование: HPA по метрикам, обзор VPA и Cluster Autoscaler
  18. Наблюдаемость: логи, метрики, events, обзор Prometheus и Grafana
  19. Безопасность глубже: securityContext, Pod Security Standards, NetworkPolicy, шифрование секретов
Кластер у вас уже живет: приложение задеплоено через Helm, пробы настроены, лимиты выставлены. Осталась тема, которую обычно откладывают до первого инцидента, а зря. RBAC отвечает на вопрос "кому что можно в кластере", и настраивается он проще, чем выглядит со стороны.

Как Kubernetes решает, что вам можно:

Любой запрос к API-серверу проходит три этапа. Сначала аутентификация: кто ты. Потом авторизация: можно ли тебе это действие. И третий этап, admission control: цепочка контроллеров, которая может изменить или отклонить запрос уже после успешной авторизации, через нее работают, например, Pod Security Admission и validating-вебхуки. В этой главе занимаемся вторым этапом. За авторизацию по умолчанию отвечает RBAC (Role-Based Access Control), он включен практически везде, от minikube до managed-кластеров в Yandex Cloud.

В RBAC всего четыре типа объектов. Role описывает набор разрешений внутри одного namespace. ClusterRole делает то же самое на весь кластер, плюс покрывает кластерные ресурсы, то есть не привязанные ни к какому namespace: nodes, persistentvolumes, сами namespaces. RoleBinding привязывает роль к субъекту в рамках namespace, ClusterRoleBinding во всем кластере. Субъектом может быть пользователь, группа или ServiceAccount.

Запретить что-то в RBAC нельзя, правил deny не существует. По умолчанию закрыто все, роли только добавляют разрешения. Поэтому думать надо в терминах минимально необходимого доступа, а не отрезания лишнего.

Практика: read-only доступ к подам

Типовая задача: сервису мониторинга нужно читать поды и их логи в namespace shop, и ничего больше.

Код: Выделить всё

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: shop
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
verbs это действия: get, list, watch, create, update, patch, delete, deletecollection. Пустой apiGroups означает core-группу, где живут поды. pods/log это субресурс, без него kubectl logs работать не будет.

Отдельная категория, спец-verbs: escalate и bind позволяют выдавать через RBAC права шире собственных, impersonate разрешает выполнять запросы от чужого имени, use дает применять политики (в ванильном Kubernetes после удаления PodSecurityPolicy в 1.25 почти не встречается, в OpenShift нужен для SecurityContextConstraints). Все четыре опасны, выдавайте их только осознанно. И не пишите wildcard "*" в verbs, resources или apiGroups: такая роль молча подхватит в том числе разрешения, которые появятся в кластере позже, с новыми CRD или версиями API.

Прежде чем сочинять роль с нуля, посмотрите встроенные. В каждом кластере уже есть ClusterRole view (чтение почти всего в namespace, кроме секретов), edit (правка большинства ресурсов) и admin (почти полный контроль в namespace, включая раздачу прав через RoleBinding). Для типового read-only доступа стандартная практика это забиндить готовый view, а не писать свое. Наш pod-reader учебный, и он заметно уже, чем view.

Теперь субъект и привязка. Поды ходят в API под ServiceAccount, по умолчанию это ServiceAccount с именем default и пустыми правами.

Код: Выделить всё

apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitoring
  namespace: shop
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: monitoring-pod-reader
  namespace: shop
subjects:
- kind: ServiceAccount
  name: monitoring
  namespace: shop
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
В Deployment остается прописать serviceAccountName: monitoring в спеке пода.

Важный паттерн на будущее: ClusterRole можно привязать обычным RoleBinding, и тогда ее права действуют только в namespace биндинга. Так одна роль переиспользуется в любом числе namespace без копипасты Role. Например, read-only доступ через встроенный view:

Код: Выделить всё

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: monitoring-view
  namespace: shop
subjects:
- kind: ServiceAccount
  name: monitoring
  namespace: shop
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
Нужен тот же доступ в namespace billing, делаете там еще один такой RoleBinding, роль трогать не надо.

Проверять права созданием тестовых подов не нужно, есть kubectl auth can-i:

Код: Выделить всё

kubectl auth can-i list pods -n shop \
  --as=system:serviceaccount:shop:monitoring
# yes

kubectl auth can-i delete pods -n shop \
  --as=system:serviceaccount:shop:monitoring
# no

# показать вообще все, что разрешено субъекту в namespace
kubectl auth can-i --list -n shop \
  --as=system:serviceaccount:shop:monitoring
Флаг --as подставляет любого субъекта, для ServiceAccount формат system:serviceaccount:<namespace>:<имя>. Команда экономит часы, сразу видно, какого именно разрешения не хватает.

Если токен нужен внешнему скрипту, учтите: с версии 1.24 секреты с токенами для ServiceAccount автоматически не создаются. Токен запрашивается явно и живет ограниченное время:

Код: Выделить всё

kubectl create token monitoring -n shop --duration=1h
С живыми людьми чуть иначе: Kubernetes не хранит пользователей, их дает внешняя система. В managed-кластерах (Yandex Cloud, VK Cloud) это IAM облака, в самосборных обычно клиентские сертификаты или OIDC. Для RBAC разницы нет: в subjects пишете kind: User или kind: Group и делаете binding точно так же.

Типичные грабли:

Выдать всем cluster-admin "временно, чтобы заработало". Откатывать потом тяжело, никто не помнит, кому и зачем выдавали. Лечится регулярным просмотром kubectl get clusterrolebindings.

Право list на secrets фактически раскрывает их содержимое: list возвращает полные объекты со значениями. Если сервису нужен один секрет, выдавайте get на конкретное имя через resourceNames. На list и watch resourceNames тоже действует, но с оговоркой: клиент обязан сам передать field selector по имени, совпадающему с resourceNames, иначе запрос не пройдет авторизацию. Голый kubectl get secrets вернет 403, а kubectl get secrets --field-selector=metadata.name=db-credentials пройдет. Ограничить по имени нельзя только create (имя нового объекта в момент авторизации еще неизвестно) и deletecollection.

roleRef в биндинге неизменяемый. Решили привязать другую роль, придется удалить RoleBinding и создать заново, kubectl apply здесь вернет ошибку.

Классика: ServiceAccount в subjects указан с чужим namespace. RoleBinding при этом создастся без единой ошибки, права просто молча не появятся. У ClusterRoleBinding поведение другое: namespace для ServiceAccount там обязателен, объект без него API-сервер отклонит сразу, с ошибкой subjects.namespace: Required value. Молчаливый вариант с RoleBinding kubectl auth can-i с --as находит за минуту.

И последнее: если под вообще не ходит в Kubernetes API (а большинство приложений не ходит), ставьте automountServiceAccountToken: false в спеке пода. Меньше токенов в файловых системах контейнеров, меньше поверхность атаки.

Что усвоили:

RBAC аддитивен, по умолчанию закрыто все. Role и RoleBinding работают в namespace, ClusterRole и ClusterRoleBinding на весь кластер, при этом ClusterRole через обычный RoleBinding переиспользуется в отдельных namespace. Поды живут под ServiceAccount, права проверяются через kubectl auth can-i, а для типового доступа сначала смотрим встроенные view, edit и admin. Это последняя глава курса, база у вас теперь есть. Дальше по теме безопасности смотрите NetworkPolicy и Pod Security Standards, а навыки отладки из главы 11 пригодятся и тут: заметная часть "не работает" в проде оказывается банальным 403.
👍3 ❤️2 🔥1 😄 🤔
✔ Лучший ответ сформирован автоматически — gwinger
дополню про create token: дефолтный срок там час, а слишком большой --duration апи-сервер может молча урезать до своего максимума, kubectl при этом только warning пишет. у нас в managed кластере так и вышло, токен для интеграции протух раньше времени. для долгоживущих штук лучше отдельный секрет типа kubernetes.io/service-account-token руками создавать, но это уже осознанный риск
Перейти к ответу →
Аватара пользователя
terraform1337
Сообщения: 1
Зарегистрирован: 28 май 2026, 04:24

Re: Базовая безопасность: RBAC и доступы

Сообщение terraform1337 »

anton_k8s писал(а):Право list на secrets фактически раскрывает их содержимое
вот это для меня открытие. всегда был уверен, что list отдает только имена, а значения уже через get. получается, всякие дашборды, которым выдали list на secrets ради списка, видят все пароли неймспейса? пошел проверять наши биндинги
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
gwinger
Сообщения: 1
Зарегистрирован: 14 май 2026, 22:53

Re: Базовая безопасность: RBAC и доступы

Сообщение gwinger »

✔ Лучший ответ — сформирован автоматически
дополню про create token: дефолтный срок там час, а слишком большой --duration апи-сервер может молча урезать до своего максимума, kubectl при этом только warning пишет. у нас в managed кластере так и вышло, токен для интеграции протух раньше времени. для долгоживущих штук лучше отдельный секрет типа kubernetes.io/service-account-token руками создавать, но это уже осознанный риск
👍1 ❤️1 🔥 😄 🤔
Аватара пользователя
kotlinsre
Сообщения: 1
Зарегистрирован: 03 июн 2026, 08:19

Re: Базовая безопасность: RBAC и доступы

Сообщение kotlinsre »

спасибо за can-i --list, не знал про этот флаг. неделю назад полдня дебажил, почему gitlab-runner не может сделать rollout restart, оказалось в роли не было verb patch на deployments. с can-i нашел бы минут за пять
👍2 ❤️ 🔥 😄 🤔
Аватара пользователя
lena11
Сообщения: 2
Зарегистрирован: 09 июн 2026, 16:07

Re: Базовая безопасность: RBAC и доступы

Сообщение lena11 »

а если одни и те же права нужны в трех неймспейсах сразу? копировать Role в каждый как-то тоскливо. правильно понимаю, что можно завести одну ClusterRole и сделать к ней RoleBinding в каждом ns, и права при этом останутся в рамках конкретного неймспейса, а не на весь кластер?
👍 ❤️ 🔥2 😄 🤔2
Ответить
← Предыдущая глава
Helm: пакетный менеджер для Kubernetes
Следующая глава →
Job и CronJob: разовые и периодические задачи

Все главы курса «Kubernetes на практике»

Поделиться темой: ✈ Telegram VK

Вернуться в «Kubernetes на практике»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость