我先讲一下业务场景:
- k8s集群内部有几个重要的命名空间(比如: kube-system, kube-public 等),这些命名空间除了管理员有权限,其他用户不可以操作(编辑,删除)这几个命名空间。
- 在k8s集群需要创建一个用户 saas-admin, 有以下权限:
(1). namespace 的 create, update, delete, get, list, watch 权限。
(2). rolebindings 的 create, update, delete, get, list 权限。
(3). serviceaccounts 的 create, update, delete, get, list, watch 权限。 - saas-admin 用户可以在集群下创建用户 sass-user 和 用户独有的命名空间 users-ns, 并且把用户 saas-user 绑定到 ClusterRole。
- 用户 saas-user 具有命名空间 users-ns 下的所有权限(每个用户都有自己的命名空间)。
- 这里重复一下,用户 saas-admin 不可以查看 kube-system 和 kube-public 命名空间下的任务资源, 也不能操作(编辑,删除) kube-system 和 kube-public 命名空间。
这里先抛出一个问题:如果只用 RBAC 如何才能做到上面这种场景?
…
我想了很久, 发现只有RBAC根本做不到(也可能是我才书浅薄, 如果大家有想法,可以在评论区留言)
这个时候就要配合 ValidatingAdmissionPolicy 来使用了,如果不熟悉 ValidatingAdmissionPolicy ,可以去官方文档了接一下,我说一下个人想法:
- 使用 ValidatingAdmissionPolicy 来判断用户是否saas-admin, 如果是则拒绝。
- 使用 ValidatingAdmissionPolicyBinding 来把验证准入策略绑定带有特定标签的命名空间。
- 使用RBAC来分配saas-admin的权限。
第1和第2步的目的是防止saas-admin 误操作 kube-system 等命名空间, 这样目的就达到。
下面展示一下配置,噢,对了,如果不知道k8s怎么开启ValidatingAdmissionPolicy,可以参考这篇文章:k8s 启用 ValidatingAdmissionPolicy 特性
配置 ValidatingAdmissionPolicy
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingAdmissionPolicy
metadata:name: deny-inter
spec:matchConstraints:resourceRules:- apiGroups: ["*"]apiVersions: ["*"]operations: ["*"]resources: ["*"]validations:- expression: "request.userInfo.username != 'system:serviceaccount:saas:saas-admin'" # 拒绝所有请求message: "ServiceAccount 'saas-admin' cannot operate in namespace"failurePolicy: Fail---
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingAdmissionPolicyBinding
metadata:name: deny-inter-binding
spec:policyName: deny-inter # 引用策略名称matchResources:namespaceSelector:matchLabels:test-label: inter # 匹配命名空间的标签, 可以为kube-system和kube-public打上标签validationActions: ["Deny"] # 添加验证动作
配置RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制name: saas-admin-role
rules:- apiGroups: ["*"]resources: ["namespace"]verbs: ["create", "update", "delete", "get", "list", "watch"]- apiGroups: ["rbac.authorization.k8s.io"]resources: ["rolebindings"]verbs: ["create", "update", "delete", "get", "list"]- apiGroups: [""]resources: ["serviceaccounts"]verbs: ["create", "get", "list", "watch", "update", "delete"]
---
apiVersion: v1
kind: ServiceAccount
metadata:name: saas-admin # 替换为实际用户名namespace: saas # 替换为所需的命名空间
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: saas-admin-role-binding
subjects:- kind: ServiceAccountname: sass-adminnamespace: saas
roleRef:kind: ClusterRolename: saas-admin-role # 替换为实际权限角色apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: saas-user-role
rules:- apiGroups: [""]resources: ["pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "persistentvolumes"]verbs: ["get", "list", "create", "update", "delete", "watch"]- apiGroups: ["apps"]resources: ["deployments"]verbs: ["get", "list", "create", "update", "delete", "watch"]