Об ролевой модели в Kubernetes написано достаточно материала, поэтому в данной статье мы не будем уделять слишком много внимания теории, а посмотрим, как можно выполнить настройку ролей на практике.
Немного об RBAC
Управление доступом на основе ролей (RBAC) — это метод контроля доступа к вычислительным ресурсам на основе ролей отдельных пользователей в организации. В Kubernetes для авторизации RBAC используется группа API rbac.authorization.k8s.io. Данная группа применяется для принятия решений об авторизации, позволяя вам динамически настраивать политики с помощью Kubernetes API.
Для того, чтобы включить RBAC, запустите API-сервер с флагом --authorization-mode, установленным для списка, разделенного запятыми, который включает RBAC; например:
kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
Роли и их привязки
В RBAC у нас есть четыре вида объекта: Role, ClusterRole, RoleBinding и ClusterRoleBinding. Для начала разберемся с первыми двумя типами объектов.
Объекты Role и ClusterRole это по сути наборы правил, представляющие набор разрешений для организации доступа. При этом, Role — используется для предоставления доступа к ресурсам внутри одного пространства имен (namespace). А ClusterRole — используется для предоставления доступа к ресурсам, доступным в пределах всего кластера.
Для того, чтобы данные объекты, можно воспользоваться следующим манифестом:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
В этом примере ClusterRole у нас будет использоваться для предоставления доступа на чтение к секретам во всех пространствах имен.
Однако, создать роль мало, для того, чтобы она начала действовать, ее необходимо применить, а для этого у нас есть еще два объекта это RoleBinding и ClusterRoleBinding. Здесь принцип действия аналогичен: для Role мы используем RoleBinding внутри одного пространства имен, а для ClusterRole мы используем ClusterRoleBinding в рамках всего кластера K8s.
Для нашего примера ClusterRole с секретами рассмотрим следующий манифест:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # имя группы
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Здесь мы предоставляем всем пользователям из группы manager права на чтение секретов по всему кластеру.
И для того, чтобы подытожить представленное выше описание четырех объектов, рассмотрим рисунок:
Здесь Role и RoleBinding у нас действуют внутри одного пространства имен, в то время как ClusterRole и ClusterRoleBinding могут применяться по всему кластеру.
Полагаю, с теорией все понятно и теперь можно приступать к практике. Мы выполним все действия, необходимые для того, чтобы настроить для пользователя user1 роль с правами на выполнение с подами следующих действий "get", "watch", "list".
В моем примере используется minikube и указаны соответствующие пути к файлам. В случае, если у вас используется другая реализация K8s, нужно будет поправить соответствующие пути.
Для начала давайте сгенерируем ключ для user1:
openssl genrsa -out user1.key 2048
openssl req -new \
-key user1.key \
-out user1.csr \
-subj "/CN=user1/O=test"
openssl x509 -req \
-in user1.csr \
-CA ~/.minikube/ca.crt \
-CAkey ~/.minikube/ca.key \
-CAcreateserial \
-out user1.crt \
-days 500
Убедимся в том, что файлы ca.crt и ca.key успешно созданы:
ls –la ~/.minikube/
Установим учетные данные для user1 в Kubernetes:
kubectl config set-credentials user1 \
--client-certificate=user1.crt \
--client-key=user1.key
Сконфигурируем контекст, который будет включать в себя имя кластера, пространство имен (в данном примере default) и имя пользователя.
kubectl config set-context user1-context \
--cluster=minikube \
--namespace=default \
--user=user1
Посмотрим, что у нас получилось:
kubectl config view
Переключимся в созданный контекст:
kubectl config use-context user1-context
Попробуем создать пространство имен и посмотреть поды:
kubectl create namespace ns-test
kubectl get pods
Как видим обе операции завершились неудачно, так как у нас нет необходимых прав. Теперь давайте создадим нужную роль и привяжем ее к пользователю user1.
Для роли нам потребуется создать YAML файл со следующим манифестом (role.yaml):
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
А для RoleBinding создадим следующий файл (role-binding.yaml):
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Теперь нам необходимо переключиться в контекст minikube для того, чтобы иметь возможность создать наши объекты, так как в текущем контексте мы это сделать не сможем из-за отсутствия прав.
kubectl config use-context minikube
Применим наши YAML файлы.
kubectl apply -f role.yaml
kubectl apply -f role-binding.yaml
Посмотрим роли и привязки
kubectl get roles
kubectl get rolebindings
И теперь давайте проверим, что же у нас получилось. Для этого нам надо снова переключиться в контекст user1-context.
kubectl config use-context user1-context
Попробуем посмотреть состояние подов:
kubectl get pods
Как видим у нас есть все нужные права. А для того, чтобы убедиться, что не выдали случайно ничего лишнего попробуем создать пространство имен:
kubectl create namespace ns-test
Как видно, на это прав у нас нет.
Заключение
Настройка прав доступа в Kubernetes лишь на первый взгляд кажется сложным процессом. С помощью несложных операций мы можем настроить права для доступа к объектам Kubernetes без особых проблем.
Приглашаю вас на бесплатный вебинар, который посвящён внутреннему устройству Kubernetes. Зарегистрироваться можно по этой ссылке, а на странице курса вы сможете посмотреть записи предыдущих вебинаров.
SignFinder
Несмотря на простоту, в свое время почему-то именно Kubernetes RBAC была самой бесячей вещью в ванильном k8s для понимания, да еще с отсутствием как класс привычной авторизации логин\пароль.