如何通过Kubernetes RBAC限制Entra ID用户组仅访问Azure AKS特定命名空间
看起来你遇到的核心问题是AKS默认给所有通过Entra ID认证的用户(包括你的users组)绑定了集群级的基础权限,导致即使你加了自定义权限,用户还是能看到不少集群范围的资源。我来一步步帮你解决这个问题:
一、先理清问题根源
AKS默认会把system:authenticated这个内置组(所有认证用户都会自动加入这个组)绑定到system:basic-user、system:discovery、system:public-info-viewer这三个ClusterRole上,给了用户一些集群级的基础查看权限(比如查看命名空间列表、节点信息等)。而且K8s RBAC的权限是累加的——你给users组加的新权限会和这些默认权限叠加,而不是替换。
另外,你之前创建ClusterRole和ClusterRoleBinding的做法是集群级的,这会让users组在整个集群范围内都有对应权限,这显然不是你想要的。正确的做法应该是用命名空间级的Role和RoleBinding来限制权限范围。
二、具体解决方案步骤
1. 移除你之前创建的集群级配置
先把你之前给users组创建的ClusterRole和ClusterRoleBinding删掉,避免它们继续给用户叠加不必要的集群级权限:
kubectl delete clusterrole <你的ClusterRole名称> kubectl delete clusterrolebinding <你的ClusterRoleBinding名称>
2. 创建目标命名空间的权限规则(Role)
在你想要开放的命名空间下,创建一个Role,明确定义用户在这个命名空间内可以执行的操作。比如,如果你只想让users组能查看这个命名空间里的Pod、Deployment和Service,就可以这么写:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: namespace-limited-access namespace: <你的目标命名空间名称> rules: # 针对核心API组的资源(Pod、Service等) - apiGroups: [""] resources: ["pods", "pods/status", "services", "services/status"] verbs: ["get", "list", "watch"] # 针对apps API组的资源(Deployment等) - apiGroups: ["apps"] resources: ["deployments", "deployments/status", "replicasets", "replicasets/status"] verbs: ["get", "list", "watch"] # 如果你需要开放更多操作(比如创建、更新),可以在verbs里添加对应的动作,比如"create", "update"
3. 绑定Role到Entra ID的users组(RoleBinding)
接下来创建RoleBinding,把上面定义的Role和你的Entra ID users组关联起来,作用域仅限目标命名空间:
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: bind-users-to-target-namespace namespace: <你的目标命名空间名称> subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: <你的Entra ID users组的对象ID> # 注意这里填的是组的Object ID,不是组名 roleRef: kind: Role name: namespace-limited-access apiGroup: rbac.authorization.k8s.io
4. 处理默认的集群级权限(可选)
如果你觉得默认的集群级权限(比如查看命名空间列表、节点信息)还是太多,想要完全限制users组只能访问目标命名空间,这里有个小技巧:
因为我们不能直接删除AKS自带的ClusterRoleBindings(会影响管理员组的正常使用),可以用OPA Gatekeeper这类准入控制器来添加更严格的访问规则,但这需要额外部署组件。如果你的需求没这么极端,其实默认的集群级公共信息权限(比如看命名空间列表)不会让用户访问到其他命名空间内的具体资源,只是能看到集群的基本结构,这种情况可以不用额外处理。
三、验证配置是否生效
你可以用属于users组的Entra ID用户登录AKS,然后测试:
# 尝试查看目标命名空间的Pod,应该能成功 kubectl get pods -n <你的目标命名空间名称> # 尝试查看其他命名空间的Pod,应该会被拒绝 kubectl get pods -n kube-system # 尝试查看集群节点,会显示(如果没做额外限制),但无法执行节点的详细操作 kubectl get nodes
这样配置后,users组就只能在你指定的命名空间内执行你允许的操作,其他范围的访问都会被RBAC拒绝。
备注:内容来源于stack exchange,提问作者sm0ke21

