LabHub
学习 学习路径 课程

CKA — Kubernetes 管理员

用 RBAC 把权限切开

在 LabHub 中继续学习

目标

为 ServiceAccount 授予最小权限,确认权限不会越过 namespace 边界,并进一步配置集群作用域权限和 Aggregated ClusterRole。

为什么这很重要

RBAC 题目在考试中是稳定得分项,但比创建正确答案更重要的是确认答案是否正确kubectl auth can-i --as= 只会创建 SubjectAccessReview 向 apiserver 查询,并不会发送实际请求,因此可以在无副作用的情况下反复确认。

本实验特别加入了确认 no 的步骤。RBAC 权限只会累加,没有拒绝规则,因此如果误用了 ClusterRoleBinding,开放范围会远超预期。我们经常确认权限是否已开放,却很少确认它是否没有被开放。没有“确认不能做什么”的习惯,就无法真正遵守最小权限原则。

步骤

  1. 创建 namespace cka-rbaccka-rbac-other。在 cka-rbac 中创建 ServiceAccount deploy-bot,并在 cka-rbac-other 中创建一个用于边界确认的 ConfigMap boundary-probe
  2. cka-rbac 中创建 Role pod-reader。apiGroups 为 core(空字符串),resources 仅包含 podspods/log,verbs 仅包含 getlistwatch
  3. cka-rbac 中创建 RoleBinding pod-reader-bind,将 Role pod-reader 绑定到 ServiceAccount cka-rbac/deploy-bot
  4. 将模拟 deploy-bot 身份的权限检查结果保存到 /root/cka-rbac/can-i.txt。在 cka-rbac 中,get Pod 应为 yes,delete 应为 no。
  5. 使用同一账户检查能否读取 cka-rbac-other 中的 Pod,并将结果保存到 /root/cka-rbac/boundary.txt。结果应为 no。
  6. 创建 ClusterRole node-viewer(apiGroups 为 core,resources 为 nodes,verbs 为 get/list/watch)和 ClusterRoleBinding node-viewer-bind,并绑定到 cka-rbac/deploy-bot。list 节点应变为 yes。
  7. 创建 ClusterRole cka-monitoring-endpoints。添加标签 rbac.labhub.io/aggregate-to-monitoring=true,规则允许对 core 组中的 servicesendpoints 执行 getlist。然后创建 ClusterRole cka-monitoring,使 aggregationRule 通过选择器选中该标签。
  8. cka-rbac 中创建 ServiceAccount no-token,并设置 automountServiceAccountToken: false。创建 Pod locked-down(镜像 nginx:1.27),将 serviceAccountName 设为 no-token,并在 Pod spec 中也明确设置 automountServiceAccountToken: false。不要为该账户绑定任何权限。

参考

ServiceAccount 与实验 namespace

创建 namespace cka-rbaccka-rbac-other。在 cka-rbac 中创建 ServiceAccount deploy-bot,并在 cka-rbac-other 中创建一个用于边界确认的 ConfigMap boundary-probe

ServiceAccount 是 namespace 作用域资源。为了确认边界,在不应允许访问的一侧也必须存在一个资源。

创建只读 Role

cka-rbac 中创建 Role pod-reader。apiGroups 为 core(空字符串),resources 仅包含 podspods/log,verbs 仅包含 getlistwatch

core 组使用空字符串。日志被视为与 Pod 不同的子资源,因此需要单独填写。不要加入写操作动词。

通过 RoleBinding 建立连接

cka-rbac 中创建 RoleBinding pod-reader-bind,将 Role pod-reader 绑定到 ServiceAccount cka-rbac/deploy-bot

subjects 的 kind 为 ServiceAccount;除了名称,还必须填写该账户所在的 namespace。

确认权限已生效

将模拟 deploy-bot 身份的权限检查结果保存到 /root/cka-rbac/can-i.txt。在 cka-rbac 中,get Pod 应为 yes,delete 应为 no。

auth can-i 不会发送实际请求,只会发起查询。--as 所用的 ServiceAccount 名称有固定格式。

确认无法越过 namespace 边界

使用同一账户检查能否读取 cka-rbac-other 中的 Pod,并将结果保存到 /root/cka-rbac/boundary.txt。结果应为 no。

如果这里得到 yes,说明选择了错误的绑定类型。请重新检查 RoleBinding 与 ClusterRoleBinding 的差异。

开放集群作用域资源访问权限

创建 ClusterRole node-viewer(apiGroups 为 core,resources 为 nodes,verbs 为 get/list/watch)和 ClusterRoleBinding node-viewer-bind,并绑定到 cka-rbac/deploy-bot。list 节点应变为 yes。

节点不属于任何 namespace。无法通过 namespace 作用域的绑定授予访问权限。

配置 Aggregated ClusterRole

创建 ClusterRole cka-monitoring-endpoints。添加标签 rbac.labhub.io/aggregate-to-monitoring=true,规则允许对 core 组中的 servicesendpoints 执行 getlist。然后创建 ClusterRole cka-monitoring,使 aggregationRule 通过选择器选中该标签。

不要在使用 aggregationRule 的角色中直接编写 rules。规则应写在带标签的其他角色中。

综合:创建不挂载令牌的 Pod

cka-rbac 中创建 ServiceAccount no-token,并设置 automountServiceAccountToken: false。创建 Pod locked-down(镜像 nginx:1.27),将 serviceAccountName 设为 no-token,并在 Pod spec 中也明确设置 automountServiceAccountToken: false。不要为该账户绑定任何权限。

可以在 ServiceAccount 和 Pod 两侧关闭令牌挂载,Pod 侧设置优先。同时在两处明确配置,意图会更清楚。