Перейти к содержанию

Namespace и права наблюдателя через RBAC

До этого читатель управлял лабораторией через учётные данные kind. Для совместной работы такие полномочия не всегда нужны. Разработчику, который разбирает недоступный каталог, часто достаточно прочитать Pod, Deployment, события и журналы. Создадим отдельную роль наблюдателя. Результат урока — выразить нужные действия, объекты и область доступа, сохранив различие между именованием и реальной изоляцией.

Полный файл 08-reader-rbac.yaml находится в примере «Площадка». Он создаёт ServiceAccount observer, Role и RoleBinding в namespace ploshchadka. Автор не создавал учётную запись и не выполнял проверку прав. Примеры ниже описывают будущую локальную работу с административной учётной записью лаборатории.

Что namespace ограничивает, а что нет

Namespace даёт область имён для многих объектов: Deployment api в ploshchadka отличается от Deployment api в другом namespace. Команда с -n ploshchadka выбирает нужную область. Благодаря этому можно разделить учебные приложения или окружения и использовать одинаковые короткие названия без конфликта.

Однако namespace не делает все объекты namespaced. Node и некоторые другие ресурсы относятся к кластеру целиком. Нельзя рассматривать namespace как отдельный виртуальный Kubernetes со своей полной инфраструктурой. При планировании доступа важно знать область конкретного ресурса, чтобы не выдать кластерные права вместо нужной локальной роли.

Namespace сам по себе также не является сетевым запретом. Если приложение знает адрес Service другой области и политика сети позволяет соединение, оно может обратиться туда. Для ограничения сетевых переходов нужны отдельные механизмы и поддерживающий их CNI. В этой лаборатории такие политики не устанавливаются; RBAC отвечает за действия в Kubernetes API.

Разделение окружений требует и раздельной конфигурации. Нельзя создать namespace staging и автоматически получить другое значение API_BASE, независимую базу или иной секрет. Объекты нужно создать с осознанными ссылками. Иначе логическое имя окружения существует, а приложения всё ещё используют общий внешний ресурс.

ServiceAccount, Role и RoleBinding

ServiceAccount представляет идентичность, которой могут пользоваться процессы и обращения к API. Мы создаём observer, но не монтируем его токен в API или web. Приложения каталога вообще не должны получать права наблюдателя для выдачи JSON. Учебная роль нужна для объяснения модели доступа, а не для расширения полномочий веб-процесса.

Ключевая часть Role:

rules:
  - apiGroups: [""]
    resources: ["pods", "services", "events"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]

Пустая API group относится к основным ресурсам v1, а apps содержит Deployment и ReplicaSet. Названия в rules — имена ресурсов API во множественном числе, не произвольные заголовки YAML. Это важно при чтении отказа доступа: право на deployments не означает автоматически право на pods/log.

Журналы представлены отдельным subresource pods/log. Наблюдатель может видеть Pod, но без этой строки не обязательно сможет прочитать его лог. Сходным образом существует pods/exec, позволяющий выполнять команды внутри контейнера; его в нашей роли нет. Для диагностики каталога выполнение команд изнутри процесса не требуется.

RoleBinding связывает Role с субъектом observer. Сама Role не выдаёт полномочия всем пользователям namespace. Такой раздельный подход позволяет переиспользовать описание действий и явно перечислять получателей доступа. Формат субъектов и область применения описаны в официальной документации RBAC.

Почему в роли отсутствуют Secrets

Наблюдателю не нужно читать Secret api-demo-secret. Он может определить отсутствие объекта по состоянию контейнера и событиям, не узнавая значение токена. Разделение помогает дать диагностическую возможность без доступа к чувствительным данным. В реальной системе события и журналы тоже могут раскрывать информацию, поэтому их состав нужно контролировать отдельно.

Некоторые права имеют косвенные последствия. Право создавать Pod с произвольной спецификацией может дать доступ к смонтированным данным или учётным записям, даже если прямое чтение Secrets запрещено. Поэтому нельзя оценивать набор полномочий только по одному отсутствующему слову. Наша роль вообще не содержит create, patch, update или delete.

Поле automountServiceAccountToken: false у API и web уменьшает ненужную доступность токена внутри контейнера. Оно не превращает пользователя, применяющего манифест, в observer и не меняет его kubeconfig. Учётные данные команды и идентичность Pod относятся к разным участникам. Это различие часто скрывается за общим словом «доступ».

В настоящей команде человеческий вход обычно организуется отдельным способом, например через внешнюю систему идентификации. Сервисная учётная запись не обязана становиться постоянным паролем разработчика. В курсе observer используется как понятный субъект для правил, а выдача долговременных токенов людям не описывается.

Чтение решения авторизации

RoleBinding действует в выбранном namespace. Для прав на кластерные ресурсы существуют другие формы связывания, но они не нужны наблюдателю каталога. Разница помогает не расширять область полномочий только потому, что удобно иметь одну роль для всей лаборатории.

Будущая административная проверка в локальной лаборатории:

kubectl --context kind-ploshchadka apply -f manifests/08-reader-rbac.yaml
kubectl --context kind-ploshchadka -n ploshchadka auth can-i get pods --as system:serviceaccount:ploshchadka:observer
kubectl --context kind-ploshchadka -n ploshchadka auth can-i get pods/log --as system:serviceaccount:ploshchadka:observer
kubectl --context kind-ploshchadka -n ploshchadka auth can-i get secrets --as system:serviceaccount:ploshchadka:observer

Для первых двух действий ожидается yes, для Secrets — no. Параметр --as просит выполнить запрос с impersonation указанного субъекта. Вызывающая учётная запись должна иметь право на такую подстановку; обычный observer не получает его автоматически. Поэтому отказ самой проверки impersonation не означает ошибку Role.

Дополнительно можно сопоставить list и get. Чтение одного известного объекта и получение списка — разные действия. Если интерфейс диагностики показывает весь набор Pod, ему нужен list; если следит за изменениями, понадобится watch. Правило должно отражать реальные операции интерфейса, а не случайный набор глаголов из другого проекта.

Не добавляйте wildcard * только ради устранения непонятного отказа. Сначала выясните запрошенные resource, subresource, verb и namespace. Затем оцените, входит ли операция в задачу наблюдателя. При таком подходе отказ доступа становится проверяемым свойством роли, а не препятствием, которое нужно безусловно убрать.

В финальной передаче важно сохранить правила и объяснение получателей доступа. Команда должна понимать, кто способен читать журналы, кто менять Deployment и кто получать секреты. Сегодня результатом является ограниченная роль для локального наблюдения; далее рассмотрим границу постоянного хранения и PVC, где полномочия удаления особенно связаны с последствиями для данных.

Оглавление серии