限制访问 Kubernetes 命名空间列表。

10

我有一组用户(dev-team),他们只需要访问devqa命名空间。我创建了一个服务帐户,集群角色和集群角色绑定,如下所示。

服务帐户

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dev-team

集群角色

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: dev-team-users
rules:
  - apiGroups: ["rbac.authorization.k8s.io",""]
    resources: ["namespaces"]
    resourceNames: ["dev","qa"]
    verbs: ["get","list","create"]

群集角色绑定

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: dev-team-user-bindings
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: dev-team-users
subjects:
- kind: User
  name: dev-team
  namespace: kube-system
  apiGroup: rbac.authorization.k8s.io

当我尝试验证访问权限时,运行以下命令kubectl get namespaces --as=dev-team,会出现以下错误信息。
Error from server (Forbidden): namespaces is forbidden: User "dev-team" cannot list resource "namespaces" in API group "" at the cluster scope

我期望只显示 devqa 命名空间,这里我漏掉了什么吗?

1个回答

21

list操作失败是因为您在ClusterRole中使用resourceNames字段来限制命名空间对象以授予访问权限,但list会返回所有命名空间对象。

但我想你真正想要的是限制对命名空间中的资源的访问,而不是命名空间对象本身(其中包含的信息不多,只有命名空间的名称)。

为了实现这一点,您必须在那些您希望向用户授予访问权限的命名空间中创建角色(或ClusterRole)和RoleBindings。

下面是如何为dev-team用户在devqa命名空间中授予所有资源的访问权限,但拒绝访问任何其他命名空间中的资源。

创建一个ClusterRole(您也可以在devqa命名空间中创建一个角色,但使用ClusterRole允许您仅定义权限一次,然后从多个RoleBindings引用它):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: dev-team-users
rules:
- apiGroups:
    - '*'
  resources:
  - '*'
  verbs:
  - '*'
devqa命名空间中创建一个RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: dev-team-user-bindings
  namespace: dev
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: dev-team-users
subjects:
- kind: User
  name: dev-team
  apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: dev-team-user-bindings
  namespace: qa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: dev-team-users
subjects:
- kind: User
  name: dev-team
  apiGroup: rbac.authorization.k8s.io

测试访问:

kubectl get pods -n qa --as=dev-team           # Succeeds
kubectl get pods -n dev --as=dev-team          # Succeeds
kubectl get pods -n default --as=dev-team      # Fails
kubectl get pods -n kube-system --as=dev-team  # Fails

请参考Kubernetes RBAC文档

编辑

1. 识别用户创建的命名空间

不能使用RBAC来完成此操作。您需要某种形式的审计

2. 识别用户可以访问的命名空间

也不能使用RBAC轻松完成此操作。但是您可以遍历所有命名空间并测试给定用户是否具有访问权限:

for n in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
  echo -n "$n: "
  kubectl auth can-i get pods -n "$n" --as=dev-team
done
你可以根据需要更改动词/资源部分(例如获取pods)。

感谢您的详细解释。我有一个需求,需要识别用户创建或访问的所有命名空间。是否有一种基于RBAC规则列出它们的方法? - Niranjan
1
有没有办法让“kubectl get ns”仅列出用户可以访问的命名空间?本地或通过扩展Kubernetes功能实现? - Sascha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接