bigywater.tech
Kubernetes · 90

聚合 ClusterRole:标签怎么把规则合并

为什么给 CRD 发一个 ClusterRole,内置的 view / edit / admin 就多了新资源的权限?手动改 view 为什么改不动?聚合是怎么合并 rules 的?这篇用一个 CRD 和一个用户 alice 把聚合 ClusterRole 的每个环节验证一遍。

13 / 28 / 30
内置 view / edit / admin 由聚合得到的 rule 条数
<0.1 秒
带标签的 ClusterRole 创建后,view 的 rules 里出现新资源所用的时间
view → edit → admin
给 view 加的权限会沿标签链流进 edit 和 admin

内置三件套

实测 · 本机执行输出
  ClusterRole view:aggregationRule 选择 [{'rbac.authorization.k8s.io/aggregate-to-view': 'true'}];当前汇总出 13 条 rule
  ClusterRole edit:aggregationRule 选择 [{'rbac.authorization.k8s.io/aggregate-to-edit': 'true'}];当前汇总出 28 条 rule
  ClusterRole admin:aggregationRule 选择 [{'rbac.authorization.k8s.io/aggregate-to-admin': 'true'}];当前汇总出 30 条 rule
  带标签 rbac.authorization.k8s.io/aggregate-to-view=true 的 ClusterRole 有 2 个:['system:aggregate-to-view', 'system:aggregated-metrics-reader']
  view 里的一条汇总进来的 rule 例子:{'apiGroups': [''], 'resources': ['configmaps', 'endpoints', 'persistentvolumeclaims', 'persistentvolumeclaims/status', 'pods', 'replicationcontrollers', 'replicationcontrollers/scale', 'serviceaccounts', 'services', 'services/status'], 'verbs': ['get', 'list', 'watch']}
  edit 的标签链:admin 还聚合 edit 吗?admin 的 selector:[{'rbac.authorization.k8s.io/aggregate-to-admin': 'true'}]

view 的 aggregationRule 选择 rbac.authorization.k8s.io/aggregate-to-view=true 的 ClusterRole,现在汇总出 13 条 rule;edit 选 aggregate-to-edit,28 条;admin 选 aggregate-to-admin,30 条。带 aggregate-to-view 标签的 ClusterRole 有两个(system:aggregate-to-view、system:aggregated-metrics-reader)。它们的 rules 字段是控制器填的,不是人写的。

CRD 作者的用法

实测 · 本机执行输出
  创建 CRD widgets.k84.example.com 并把 alice 绑定到 view:alice list widgets → no;list pods → yes
  view 的 rules 里已有 widgets:False
  创建带 aggregate-to-view 标签的 ClusterRole k84-widgets-view 之后 0.0 秒,view 的 rules 里出现 widgets;alice list widgets → yes;alice delete widgets → no(view 只有读权限)
  edit 里有 widgets 吗:True;admin 里呢:True——因为 view 这个 ClusterRole 自己带着标签 ['rbac.authorization.k8s.io/aggregate-to-edit'],它的(聚合后的)rules 又会被 edit、admin 聚合进去:view → edit → admin 形成一条链
  删除这个 ClusterRole 后 0.0 秒,widgets 从 view 里消失;alice list widgets → no

创建 CRD widgets.k84.example.com,把 alice 绑定到 view:alice list widgets 是 no(view 里还没有这个资源),list pods 是 yes。创建带 aggregate-to-view=true 标签的 ClusterRole k84-widgets-view(widgets 的 get / list / watch)后不到 0.1 秒,view 的 rules 里就出现了 widgets,alice list widgets 变成 yes、delete 仍是 no。edit 和 admin 里也有 widgets:view 自己带着 aggregate-to-edit 标签,它的(聚合后的)rules 会被 edit 聚合,edit 再被 admin 聚合——view → edit → admin 形成一条链。删掉这个 ClusterRole,widgets 又立刻从 view 里消失。

手改会被覆盖

实测 · 本机执行输出
  给 view 手动追加一条 secrets get:退出码 0;patch 返回的对象有 14 条 rule(原来 13 条)
    之后连续读 view 的 rule 数:[13]…最终 13;控制器把额外那条还原了;alice get secrets → no

手动给聚合出来的 view 追加一条 secrets get:patch 成功,返回的对象有 14 条 rule(原来 13 条),但随后读 view 已经是 13 条——控制器把多出的那条立刻还原;alice get secrets 仍是 no。想加权限就写一个带标签的 ClusterRole 去聚合。

自己的聚合角色

实测 · 本机执行输出
  k84-monitoring 本身 rules 写的是空,0.0 秒后汇总出 3 条:[(['nodes', 'nodes/metrics'], ['get', 'list']), (['pods'], ['get', 'list', 'watch']), (['nodes'], ['get', 'list'])]
  两个来源里都有 nodes get/list:汇总时没有去重(重复保留)
  删掉 k84-src-pods 后:[(['nodes', 'nodes/metrics'], ['get', 'list'])]

自建 k84-monitoring:rules 写空,aggregationRule 选 k84/aggregate-to-monitoring=true。两个来源(k84-src-nodes、k84-src-pods)很快汇总成 3 条 rule,其中 nodes 的 get / list 来自两个来源,重复保留、没有去重;删掉 k84-src-pods 后只剩 1 条。

分步演示

聚合 ClusterRole
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0);alice 是一个不存在的用户名,只通过 kubectl auth can-i --as=alice 查询(见下面的 auth can-i 一篇);“<0.1 秒”是带 0.05 秒轮询的结果,控制器通常在 kubectl 返回之前就已经汇总完;每种情形各一次
    • 没有验证:aggregationRule 中使用 matchExpressions 的行为;聚合角色被其他聚合角色选中时的循环保护;ClusterRoleBinding 到聚合角色后 rules 变化对已缓存授权的影响;edit 与 admin 对 CRD 的默认权限差别;kube-controller-manager 的 clusterrole-aggregation 控制器的日志
    京ICP备2026067502号-1京公网安备11010502063487号