RBAC — 四个对象和一个陷阱
一句话总结
RBAC是将“可以做什么”(Role)和“谁可以在哪里做”(Binding)分开的模型,确定范围的一方总是Binding。
为什么需要这个?
如果把所有权限都写在一张文件上,两个权限就会立刻崩溃。每当人数增加时,就必须复制相同的权限组合,而且没有人能追踪哪些权限在哪里发挥作用。RBAC将这两种权限分开。权限的内容由Role和ClusterRole定义,谁以及在哪些范围内分配该内容由RoleBinding和ClusterRoleBinding决定。
| 对象 | 范围 | 做的事情 |
|---|---|---|
| Role | 命名空间 | 关于那个命名空间资源的规则 |
| ClusterRole | 集群 | 集群范围资源或可重复使用的共同权限 |
| RoleBinding | 命名空间 | 将角色赋予主体,仅在这个命名空间中 |
| ClusterRoleBinding | 集群 | 将角色赋予主体,在整个集群中 |
怎么行动
规则有三个。apiGroups,resources,verbs.
rules:
- apiGroups: [""] # 코어 그룹은 빈 문자열
resources: ["pods"]
verbs: ["get", "list", "watch"]
apiGroups: [""]遗漏导致无法看到Padd的咨询现在每周都在出现。Core API组的名称是空字符串,Deployment之类的apps在团体里。
这里出现了一个最重要的陷阱。**如果将ClusterRole绑定为RoleBinding,该权限仅在相应命名空间有效。**也就是说,角色的种类不是决定范围,而是绑定的种类决定。这种组合在实际工作中非常有用。只要在一次性定义一个“只读”等通用权限组合为ClusterRole,然后每个团队在各自的命名空间中将其绑定为RoleBinding即可使用。如果将相同的ClusterRole绑定为ClusterRoleBinding,那么那一刻就成为整个群集的全部权限。两个配置文件的区别只有一句话。
第二经常忽略的是子资源。pods/log哇pods/exec是pods哇,这是单独的资源名称。没有读取pad的权限,所以无法读取日志,也没有权限在shell上附加读取日志。给日志收集机器人pods/log的get这是可以提供无限设计的理由,相反pods/exec如果把它留给任何人,也意味着可以在集装箱里做任何事情。
第三个是确认方法。权限不是创造的,而是被判定的,所以不要用眼睛看,要问。
kubectl auth can-i list pods -n rbac-lab \
--as=system:serviceaccount:rbac-lab:app-reader
# yes
--as是impersonation。服务账户的正式名称格式是system:serviceaccount:<네임스페이스>:<이름>只要知道这个,就可以模仿任何主体提问。要一起确认可以做和不能做的事情才有意义。如果只确认yes的话,即使权限比需要的大得多,也无法知道。
在现场相遇的样子
第一,野生卡一旦进入就不能掉出来。verbs: ["*"]虽然是这样,但以后如果出现新的资源,在任何人都不知道的情况下,权限会自动扩大。最低权限不是取向,而是为了让即使时间过去也不会扩大范围的装置。
**第二,get secrets实际上是资格证明阅览权限。**为了开发者的方便,给予的编辑权限与生产数据库密码阅览权限相同的情况很常见。这个故事将继续到下一个模块。
第三,定期审计。 cluster-admin 挂在 ClusterRoleBinding 列表上的角色、使用通配符的角色、可以读取 secrets 的角色——这三个问题应该每个群集定期提出。kubectl get clusterrolebindings -o json | jq只要写几行就会得到答案,这种习惯大大降低了权力债务的积累速度。
知道为什么没有权限的方法
RBAC问题可以不猜测地提问。kubectl auth can-i到API服务器
直接询问判断。
kubectl auth can-i create pods -n prod
kubectl auth can-i list secrets -n prod --as=system:serviceaccount:prod:app
kubectl auth can-i --list --as=system:serviceaccount:prod:app -n prod
最后一行特别有用。显示主体拥有的全部权限。
**必须准确填写对象。**服务账户的名字是
system:serviceaccount:<네임스페이스>:<이름>是。人的账号是认证书的CN吗?
来自OIDC的请求。--as要模仿的话,就需要拥有 impersonate 权限。
要求。
规则只会增加。RBAC没有拒绝。如果权限太宽泛的话,在某个地方 因为是添加的,所以需要找到绑定。
kubectl get rolebinding,clusterrolebinding -A -o json | jq -r '
.items[] | select(.subjects[]? .name=="app")
| "\(.kind) \(.metadata.namespace // "-")/\(.metadata.name) -> \(.roleRef.name)"'
经常让人困惑的四个。
ClusterRole乙RoleBinding用连接符连接的话,只有在那个命名空间内才有效。 是将相同的角色重复使用在多个命名空间中的正常方法。- 像节点、PV、命名空间一样没有命名空间的资源是
ClusterRoleBinding需要这个。 - 下级资源单独写。
pods/log,pods/exec,deployments/scale银pods,deployments不包括在内。 create仅凭权限无法阻止特定名称。resourceNames需要知道名字 仅在动词(get·update·delete)中才有效。
**不要忘记默认附加的东西。所有认证的使用者
system:discovery可以通过等查看API列表,在平板电脑上安装的服务账户
即使代币没有任何权限,也可以访问API服务器。**如果没有必要的话
automountServiceAccountToken: false用绳子绑起来。
下次实习要做的事情
创建只读Role,并将其绑定到服务账户。auth can-i确认边界。创建用于节点等群集范围资源的ClusterRole,将相同的ClusterRole作为RoleBinding挂起来,亲自看看范围是如何缩小的。创建只打开子资源的角色,最后将群集的危险权限扫描的审计报告转换为JSON。