LabHub
学习 学习路径 课程

Kubernetes 运维实务

RBAC — 四个对象和一个陷阱

在 LabHub 中继续学习

一句话总结

RBAC是将“可以做什么”(Role)和“谁可以在哪里做”(Binding)分开的模型,确定范围的一方总是Binding。

概念图: 内容 · Core API组的名称是空字符串 · 如果将ClusterRole绑定为RoleBinding,该权限仅在相应命名空间有效。 · 子资源

为什么需要这个?

如果把所有权限都写在一张文件上,两个权限就会立刻崩溃。每当人数增加时,就必须复制相同的权限组合,而且没有人能追踪哪些权限在哪里发挥作用。RBAC将这两种权限分开。权限的内容由Role和ClusterRole定义,谁以及在哪些范围内分配该内容由RoleBinding和ClusterRoleBinding决定。

对象 范围 做的事情
Role 命名空间 关于那个命名空间资源的规则
ClusterRole 集群 集群范围资源或可重复使用的共同权限
RoleBinding 命名空间 将角色赋予主体,仅在这个命名空间中
ClusterRoleBinding 集群 将角色赋予主体,在整个集群中

怎么行动

规则有三个。apiGroupsresourcesverbs.

rules:
  - apiGroups: [""]                     # 코어 그룹은 빈 문자열
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

apiGroups: [""]遗漏导致无法看到Padd的咨询现在每周都在出现。Core API组的名称是空字符串,Deployment之类的apps在团体里。

这里出现了一个最重要的陷阱。**如果将ClusterRole绑定为RoleBinding,该权限仅在相应命名空间有效。**也就是说,角色的种类不是决定范围,而是绑定的种类决定。这种组合在实际工作中非常有用。只要在一次性定义一个“只读”等通用权限组合为ClusterRole,然后每个团队在各自的命名空间中将其绑定为RoleBinding即可使用。如果将相同的ClusterRole绑定为ClusterRoleBinding,那么那一刻就成为整个群集的全部权限。两个配置文件的区别只有一句话。

第二经常忽略的是子资源pods/logpods/execpods哇,这是单独的资源名称。没有读取pad的权限,所以无法读取日志,也没有权限在shell上附加读取日志。给日志收集机器人pods/logget这是可以提供无限设计的理由,相反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-iAPI服务器 直接询问判断。

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)"'

经常让人困惑的四个。

**不要忘记默认附加的东西。所有认证的使用者 system:discovery可以通过等查看API列表,在平板电脑上安装的服务账户 即使代币没有任何权限,也可以访问API服务器。**如果没有必要的话 automountServiceAccountToken: false用绳子绑起来。

下次实习要做的事情

创建只读Role,并将其绑定到服务账户。auth can-i确认边界。创建用于节点等群集范围资源的ClusterRole,将相同的ClusterRole作为RoleBinding挂起来,亲自看看范围是如何缩小的。创建只打开子资源的角色,最后将群集的危险权限扫描的审计报告转换为JSON。