Kubernetes resourceNames 限权后,get 单个节点成功但 list 报 Forbidden
同一账户能 get 授权节点,节点列表却 Forbidden。核对 list、watch 的 metadata.name 条件及客户端请求,保留既定名称授权范围。
同一个账户可以读取 worker-node-1,打开管理界面的节点列表却报 cannot list resource "nodes" at the cluster scope。如果授权规则用了 resourceNames,需要检查客户端是否发出了没有名称选择条件的集合请求。已经允许 list,也不等于允许列出所有节点。
节点是集群范围的资源。读取指定节点与列出节点集合,是不同的 API 请求;按名称限制的授权要求集合请求也带上匹配的名称条件。
用同一身份比较两种请求
先确认当前集群、应用实际凭据和错误中的完整身份。下面只读取节点,worker-node-1 应替换成被授权的真实名称;命令必须在与失败应用相同的身份下执行:
kubectl get node worker-node-1
kubectl get nodes --field-selector=metadata.name=worker-node-1
第一条是读取命名资源,通常对应 get;第二条是带名称条件的集合请求,对应 list。如果用管理员 kubeconfig 测试,成功只能证明管理员获准,不能替代应用账户的结果。
具备 impersonation 权限的管理员也可以用 --as 检查同一账户,但没有这项权限时,应使用获准的应用凭据验证,不要临时给应用增加模拟身份权限。
记录原来失败请求的动作、资源、API 组和范围。如果命名 GET 本身也失败,就不能只归因于列表条件;还需要核对绑定主体、资源名和动词,ServiceAccount 主体写错时可看 RoleBinding 的账户身份检查。
resourceNames 不会替客户端过滤列表
由管理员检查实际 ClusterRole 和 ClusterRoleBinding,包括被绑定的身份。以下只是现有 ClusterRole 规则的核对片段,不包含创建或扩大授权的操作:
rules:
- apiGroups: [""]
resources: ["nodes"]
resourceNames: ["worker-node-1"]
verbs: ["get", "list", "watch"]
在这样的按名限制下,list 和 watch 请求需要包含匹配的 metadata.name field selector。API 服务器不会先列出全部节点,再替客户端自动删掉无权查看的部分。客户端发送没有条件的节点集合请求,仍可被拒绝。
节点不属于某个命名空间,所以调整命名空间选择器或给某个空间增加 RoleBinding,不会将节点列表变成空间内资源。标签选择器也不能代替这里要求的名称条件。
允许多个名称时,应按各名称发送符合条件的请求,再由客户端处理结果;不要把多个相等条件拼到同一个 field selector,期待它表示“名称 A 或名称 B”。这类选择条件组合不是名称列表的 OR 查询。
命令行成功,界面仍可能继续失败
如果带条件的命令成功,而界面仍发出不受限的 list nodes,问题就落在客户端请求方式上。通过浏览器请求记录或应用日志确认真实查询参数,同时保留服务端拒绝信息;日志应隐藏令牌和其他认证数据。
检查应用是否支持按已知名称 GET,或为列表、后续 watch 都附上名称条件。只修正第一次列表请求,后续建立无条件 watch 时仍可能遇到拒绝。应用还需正确处理已授权节点不存在、请求失败和多个单名结果,而不能把任何 403 都解释成空列表。
没有相应支持时,可以先用受限的命名读取方式处理必要工作,并将界面功能限制作为客户端兼容问题处理。不能仅凭存在一个补丁提议,就宣称升级某个未确认的客户端版本即可修好。
验收保留原来的授权边界
保留授权配置与客户端设置,通过原配置来源调整已经确认的请求方式。最终应看到同一账户读取获准节点成功、界面相应请求不再被拒绝,同时未获准的名称和无条件集合请求仍受既定限制。
不要为了让节点页面打开就移除 resourceNames 或绑定 cluster-admin。若业务确实需要查看整个集群,应单独确认所需范围,而不是把扩大授权当作这个请求条件问题的默认处理。
需要回退客户端设置时,恢复本次修改并重查请求参数。RBAC 权限来自多个绑定的叠加;只恢复一份规则,也不能证明其他授权没有扩大,应按实际账户验证最终边界。


