Управление ролями с помощью RBAC Authorization

RBAC Authorization — один из способов распределения ролей между пользователями в кластере Kubernetes. Подробнее об этом виде авторизации в официальной документации Kubernetes.

Рекомендуем сначала подключить Service Account Token, так как без его использования после любого изменения ролей потребуется заново скачивать kubeconfig.

Затем необходимо подключить Pod Security Policy, чтобы настройки безопасности применялись для кластера.

Пример

Манифест, который создает два пространства имен и двух пользователей, каждый из которых сможет управлять подами только в своем пространстве имен:

apiVersion: v1
kind: Namespace
metadata:
  name: test-one
---
apiVersion: v1
kind: Namespace
metadata:
  name: test-two
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-one
  namespace: test-one
subjects:
- kind: ServiceAccount
  name: test-sa-one
  apiGroup: ""
roleRef:
  kind: Role
  name: pod-reader-one
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-two
  namespace: test-two
subjects:
- kind: ServiceAccount
  name: test-sa-two
  apiGroup: ""
roleRef:
  kind: Role
  name: pod-reader-two
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: test-one
  name: pod-reader-one
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: test-two
  name: pod-reader-two
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: test-one
  name: test-sa-one
---
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: test-two
  name: test-sa-two

После запуска нужно вручную добавить токены пользователям, чтобы можно было авторизоваться без пароля.

Создание токенов:

# kubectl get secret $(kubectl get serviceaccount test-sa-one -o jsonpath='{.secrets[0].name}' --namespace test-one) -o jsonpath='{.data.token}' --namespace test-one | base64 -d
<long and secure token for test-sa-one>


# kubectl get secret $(kubectl get serviceaccount test-sa-two -o jsonpath='{.secrets[0].name}' --namespace test-two) -o jsonpath='{.data.token}' --namespace test-two | base64 -d
<long and secure token for test-sa-two>

Добавление токенов пользователям в файле kubeconfig.yaml:

users:
...
- name: test-sa-one
  user:
    token: <long and secure token test-sa-one>
- name: test-sa-two
  user:
    token: <long and secure token test-sa-two>
...

Проверка работы распределения ролей:

# kubectl config set-context --current --user=test-sa-two
Context "admin@kubernetes" modified.


# kubectl get pods --namespace test-two
No resources found in test-two namespace.


# kubectl get pods --namespace test-one
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:test-two:test-sa-two" cannot list resource "pods" in API group "" in the namespace "test-one"

________

# kubectl config set-context --current --user=test-sa-one
Context "admin@kubernetes" modified.


# kubectl get pods --namespace test-two
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:test-one:test-sa-one" cannot list resource "pods" in API group "" in the namespace "test-two"


# kubectl get pods --namespace test-one
No resources found in test-one namespace.

Теперь пользователь test-sa-two имеет доступ к подам в пространстве имен test-two и не имеет доступа в пространстве имен test-one. Пользователь test-sa-one — наоборот.