Вопрос или проблема
У меня есть кластер с несколькими пространствами имен. Назовем их: ns1
и ns2
. У меня также есть несколько учетных записей сервиса, назовем их sa1
и sa2
, все в одном пространстве имен – sa-ns
.
Оба пользователя имеют доступ ко всем ресурсам в обоих пространствах имен, однако они не могут перечислить пространства имен, частью которых они являются. kubectl get ns --as=sa1
возвращает:
Error from server (Forbidden): namespaces is forbidden: User "sa1" cannot list resource "namespaces" in API group "" at the cluster scope
Это работает только в том случае, если я вручную указываю, какие пространства имен я хочу перечислить:
kubectl get ns ns1 --as=sa1
NAME STATUS AGE
ns1 Active 6d6h
Мне нужно, чтобы оба пользователя sa1
и sa2
могли перечислить все пространства имен в кластере, к которым у них есть доступ. В данном случае ns1
и ns2
.
Это поведение также, вероятно, не позволит мне перечислить пространства имен и их ресурсы на панели управления Lens. В списке пространств имен я могу перечислить только пространство имен sa-ns
, частью которого являются пользователи sa1
и sa2
. Однако панели закладки пусты, как видно на изображении ниже.
Я пытался добавить пространство имен, к которому пользователь фактически имеет доступ через функцию ACCESSIBLE NAMESPACES
в Lens, но это тоже не работает.
Я все еще ничего не вижу, только пустые панели закладки.
ServiceAccount:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa1
namespace: sa-ns
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa2
namespace: sa-ns
Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: admin-role
namespace: ns1
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: admin-role
namespace: ns2
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "*"
RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: admin-role-binding
namespace: ns1
roleRef:
kind: Role
name: admin-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: sa1
namespace: sa-ns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: admin-role-binding
namespace: ns2
roleRef:
kind: Role
name: admin-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: sa2
namespace: sa-ns
Я пытался использовать ClusterRole
вместо Role
, но ничего не изменилось.
Итак, проблема в том, что у вас нет доступа к ресурсам Namespace, которые относятся к области кластера и поэтому не включены в комбинацию Role/Rolebinding, которую вы использовали. Довольно неочевидно, но комбинирование ClusterRole с Rolebinding также предоставляет права только для одного пространства имен, поэтому это не работает.
Вероятно, лучший способ решить эту проблему – создать ClusterRole, предоставляющую права GET и LIST для ресурсов Namespace, а затем создать ClusterRoleBinding для каждой учетной записи сервиса, чтобы связать их с этим ClusterRole.
Ответ или решение
Чтобы предоставить ServiceAccount возможность перечислить все пространства имён, к которым у него есть доступ в кластере Kubernetes, необходимо использовать механизм управления доступом, предоставленный Kubernetes – роль и привязки ролей (RBAC).
Теория
RBAC в Kubernetes позволяет определять, какие пользователи и сервисные аккаунты (ServiceAccount) могут выполнять те или иные действия над ресурсами в кластере. Ресурсы в Kubernetes могут быть двух типов: namespace-scoped (ограниченные пространством имён) и cluster-scoped (кластерные). Пространства имён (Namespaces) относятся к cluster-scoped ресурсам, что означает, что для управления ими требуется назначение прав на уровне всего кластера.
Из вашего описания задачи видно, что у вас есть два пространства имён (ns1
и ns2
) и два сервисных аккаунта (sa1
и sa2
) в пространстве имён sa-ns
. Поскольку использование Role и RoleBinding ограничено только пространствами имён, оно не позволит управлять кластерными ресурсами, такими как Namespaces. Для этого потребуется ClusterRole и ClusterRoleBinding.
Пример
Для того чтобы предоставить сервисным аккаунтам sa1
и sa2
возможность перечислить все пространства имён в кластере, необходимо создать ClusterRole с правами на просмотр (GET, LIST) ресурсов Namespace и ClusterRoleBinding для каждого из аккаунтов.
- Создание ClusterRole:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-viewer
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
- Создание ClusterRoleBinding для каждого ServiceAccount:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sa1-namespace-viewer
roleRef:
kind: ClusterRole
name: namespace-viewer
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: sa1
namespace: sa-ns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sa2-namespace-viewer
roleRef:
kind: ClusterRole
name: namespace-viewer
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: sa2
namespace: sa-ns
Применение
После создания ClusterRole и ClusterRoleBinding оба сервисных аккаунта sa1
и sa2
получат возможность перечислять все доступные пространства имён в кластере. Это можно проверить с помощью команды:
kubectl get namespaces --as=system:serviceaccount:sa-ns:sa1
Служебный аккаунт теперь сможет видеть все пространства имён, к которым у него есть доступ.
Заключение
Использование ClusterRole и ClusterRoleBinding для управления правами доступа к кластерным ресурсам является мощным инструментом в Kubernetes. Это позволяет настроить гибкую систему управления доступом, обеспечивая безопасное взаимодействие с кластерными ресурсами. Таким образом, предоставление прав сервисным аккаунтам на перечисление пространств имён не только удовлетворяет текущие потребности, но и закладывает основу для возможного расширения функционала управления доступом в будущем.
Поскольку доступ к кластерным ресурсам требует особого внимания с точки зрения безопасности, рекомендуется регулярно пересматривать и оптимизировать политику доступа, соблюдая принцип минимальных прав (least privilege). Это гарантирует, что у каждого пользователя или сервисного аккаунта есть только те права, которые необходимы для выполнения его задач, минимизируя риск несанкционированного доступа к кластеру и его ресурсам.