想象你刚入职一家有二十层楼的大公司。HR 发给你一张门禁卡,这张卡可不能让你想去哪儿就去哪儿——财务室的锁只认财务部员工的卡,机房值班员才能刷开服务器机房,普通员工最多进工位区和自己部门的会议室。谁进哪扇门,不靠保安认脸,而靠一套“岗位说明书 + 门禁卡”的组合拳:行政部先定义每个岗位能去哪些楼层(角色),再把具体某个员工和岗位绑在一起(绑定),门禁系统看到你的卡就自动查岗位、查权限,放行或拒绝(判定)。Kubernetes 集群就是这栋大楼:里面跑着成千上万个容器“员工”和 API 资源“房间”。而 RBAC(基于角色的访问控制)就是这套门禁系统,负责回答三个问题:你是谁(身份)、你能做什么(动作)、你能碰什么(资源)。本文就用这栋大楼的视角,带你彻底读懂 Role 与 ClusterRole 的区别、Binding 的玩法、最小权限的落地,以及 ServiceAccount 和 Token 安全的门道。

岗位关联

对运维和平台工程师而言,RBAC 是 K8s 安全的第一道闸门。掌握它,你才能守住集群边界、做好多租户隔离、轻松应对安全合规审计——这是云原生岗位上最硬的“保命技能”。

目录
  1. 可视化演示
  2. RBAC核心概念
  3. Role与ClusterRole
  4. Binding绑定机制
  5. 最小权限原则
  6. ServiceAccount管理
  7. Token与安全实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

RBAC核心概念

大楼的门禁系统运作前,得先搞清楚几个基本角色:你是谁、你要去哪儿、你要干什么。在 Kubernetes 里,“你是谁”由主体(Subject)回答——可以是一个真实的人类用户(User),也可以是一群人的组合(Group),还可以是跑在 Pod 里的程序身份(ServiceAccount)。“你要去哪儿”由资源(Resource)回答,比如 Pods、Deployments、Services 这些 API 对象,就像大楼里的房间。“你要干什么”则由动词(Verb)回答——get、list、watch、create、delete、patch,对应刷卡、开门、搬东西、拆墙这些动作。

把这几个要素组合起来,就是一次完整的门禁判定。Kubernetes 的 APIServer 每收到一个请求,都要先走过这条流水线:确认请求者身份(认证),再查这个身份被绑定了哪些角色(授权),最后检查该角色对所请求资源是否声明了对应动词。这里有一个极其重要的安全哲学——默认拒绝(default deny)。就像新员工的卡默认哪儿都刷不开,只有明确写入规则的房间才能进。

回到大楼的比喻:这套流程就像保安拿着你的卡,先刷卡确认身份,再查 HR 的岗位登记表,最后看岗位清单里有没有“可进入房间 X”这一条。任何一环查不到,你就得打道回府。

Access(u,v,r)={allow,∃ (u,g)∈Bindings,  v∈Verbs(g,r)deny,otherwise\displaystyle \mathrm{Access}(u, v, r) = \begin{cases} \mathrm{allow}, & \exists\, (u, g) \in \mathrm{Bindings},\; v \in \mathrm{Verbs}(g, r) \\ \mathrm{deny}, & \text{otherwise} \end{cases}
这个公式说明:只有存在一条绑定,把用户 u 和某个角色 g 连起来,并且 g 的规则里明确包含对资源 r 执行动作 v 的许可,请求才被放行;否则一律拒绝。
  1. 三元组判定Access(u, v, r) 表示对一次请求的最终裁决——u 是谁、v 要做什么、r 对什么资源做。
    u∈Users,v∈Verbs,r∈Resources\displaystyle u \in \text{Users}, \quad v \in \text{Verbs}, \quad r \in \text{Resources}
  2. 找到用户的所有绑定在全部 Binding 集合中寻找包含该用户的记录,g 是这条绑定指向的角色(也可能是组)。
    (u,g)∈Bindings\displaystyle (u, g) \in \mathrm{Bindings}
  3. 动词必须落在角色规则里v 必须属于角色 g 对资源 r 声明的动词集合,get、list、watch、create、delete 等。
    v∈Verbs(g,r)\displaystyle v \in \mathrm{Verbs}(g, r)
  4. 默认拒绝兜底只要上一步没命中,结论就是 deny——没有明确说“行”,就是“不行”。
    deny,otherwise\displaystyle \mathrm{deny}, \quad \text{otherwise}

Role与ClusterRole

公司里有两类岗位说明书:一类是部门内部的,比如“开发部测试专员”,只在开发部范围内有效;另一类是公司级的,比如“消防巡检员”,全公司每个楼层都得听他的。Kubernetes 也把角色分成两类——Role 和 ClusterRole。

Role 在创建时必须指定命名空间(namespace),它的权限范围被牢牢锁在那个命名空间里,就像部门岗位只对部门员工生效。ClusterRole 则不绑定任何命名空间,天生具备集群级视野,可以管理节点(Node)、持久卷(PV)、集群角色本身这些集群级资源,就像消防巡检员可以去任何楼层检查灭火器。那什么场景该用哪个?如果你的角色只管某一个业务命名空间里的 Pods 和 Deployments,用 Role 就够;如果要管理集群组件、跨命名空间查看资源,或者想做一个全集群通用的“模板角色”,就用 ClusterRole。

所以,当你需要给全公司所有楼层的监控探头都配一个“可查看”权限时,别在每个部门重复写十份一模一样的部门岗位——直接定义一份 ClusterRole 全局岗位,再按需在各部门绑定下发,省心又一致。

Scope(Role)={ns},Scope(ClusterRole)={Cluster,经 ClusterRoleBinding 绑定{ns},经 RoleBinding 绑定\displaystyle \mathrm{Scope}(\mathrm{Role}) = \{ns\}, \qquad \mathrm{Scope}(\mathrm{ClusterRole}) = \begin{cases} \mathrm{Cluster}, & \text{经 ClusterRoleBinding 绑定} \\ \{ns\}, & \text{经 RoleBinding 绑定} \end{cases}
这个公式揭示了 ClusterRole 的一个灵活特性:它本身是全局的,但实际生效范围由后面的 Binding 决定——你可以把全局模板“收窄”到某个命名空间使用。
  1. Role 天生只属于一个命名空间Role 定义时就指定了 namespace,描述的是“这个部门内部的岗位”。
    Scope(Role)={ns}\displaystyle \mathrm{Scope}(\mathrm{Role}) = \{ns\}
  2. ClusterRole 是全局岗位说明书不绑定任何命名空间,天然具备集群级视野,能够覆盖 Nodes、PV 等集群级资源。
    Scope(ClusterRole)=Cluster\displaystyle \mathrm{Scope}(\mathrm{ClusterRole}) = \mathrm{Cluster}
  3. 授权范围反过来由 Binding 决定ClusterRole 一旦被 RoleBinding 绑定,作用域就收窄到该命名空间,形成“全局模板 + 局部授权”的经典用法。
    Scope(ClusterRole)→RoleBinding{ns}\displaystyle \mathrm{Scope}(\mathrm{ClusterRole}) \xrightarrow{\mathrm{RoleBinding}} \{ns\}

Binding绑定机制

岗位说明书写得再详细,不发给具体员工也是废纸一张。Binding(绑定)就是“发卡”环节,它把角色和主体连接起来。RoleBinding 在某个命名空间内把角色授予用户、组或 ServiceAccount;ClusterRoleBinding 则在整个集群范围内完成授权。换句话说,RoleBinding 是“部门内发卡”,ClusterRoleBinding 是“全公司开通权限”。

这里有新手最容易忽略的玩法:RoleBinding 不仅能绑定 Role,还能绑定 ClusterRole。当你用 RoleBinding 绑定一个 ClusterRole 时,该 ClusterRole 的权限会被“压缩”到这个命名空间内。这就好比公司发布了一份全公司通用的“实验室安全员”岗位说明,开发部用自己部门的发卡机给张三发了一张只在本部门生效的安全员卡——定义是全局的,发放是局部的。同时要注意,一个用户可以拥有多张“卡”,他的最终权限是所有绑定取并集,而不是取交集。

Binding 是最容易埋雷的环节。许多安全事故不是角色定义错了,而是“卡发多了”——把 ClusterRoleBinding 当万能授权扔给所有开发,等于给整栋大楼的每个房间都配了钥匙。记住:发卡要克制,绑定要可追溯。

Perm(u)=⋃b∈Bindings(u)Perm(b)=Perm(b1)∪Perm(b2)∪⋯\displaystyle \mathrm{Perm}(u) = \bigcup_{b \in \mathrm{Bindings}(u)} \mathrm{Perm}(b) = \mathrm{Perm}(b_1) \cup \mathrm{Perm}(b_2) \cup \cdots
这个公式说明:用户的有效权限等于所有绑定带来的权限之和,绑定的角色越多,权限越大,并不会互相抵消。
  1. 用户在多个岗位任职一个用户可以被多个 RoleBinding 或 ClusterRoleBinding 绑定,同时担任“观察员”“发布者”等多种角色。
    b1,b2,…∈Bindings(u)\displaystyle b_1, b_2, \ldots \in \mathrm{Bindings}(u)
  2. 权限取并集最终权限是每个绑定所赋予权限的并集,而不是交集,也不是更小的那个。
    Perm(u)=⋃bPerm(b)\displaystyle \mathrm{Perm}(u) = \bigcup_{b} \mathrm{Perm}(b)
  3. 权限随绑定数量膨胀这提醒我们,角色绑得越多,权限就越大,必须定期清理,避免员工不知不觉攒了一堆“卡”。
    ∣Perm(u)∣≤∑b∣Perm(b)∣\displaystyle |\mathrm{Perm}(u)| \le \sum_{b} |\mathrm{Perm}(b)|

最小权限原则

门禁系统最怕的不是门太少,而是钥匙太多。最小权限原则(Least Privilege) 的理念很朴素:只授予完成工作所必需的最少权限,不多给一分。给一个只需要看日志的实习生 cluster-admin 权限,就像给前台配了金库钥匙——他不会主动干坏事,但他的账号一旦被钓鱼,整栋楼就失守了。

落地时可以从三个方向入手。一是权限收敛:先把角色规则里的 verbs 和 resources 精确到“够用就行”,比如只读角色就只给 get/list/watch,千万别给 *。二是逐级授权:把权限分成只读(viewer)、运维(operator)、管理(admin)几个梯度,按职责对号入座。三是审计复盘:定期用脚本扫描所有绑定,找出三个月未使用的角色、绑定给离职员工的账号、以及权限过大的“幽灵卡”。数学上,最小权限可以写成这样:

回到大楼:给员工发卡之前,先问一句“他每天的工作到底需要进哪几个房间”。回答得越具体,卡就越小,楼就越安全。K8s 里的 kubectl auth can-i 就是帮你回答“这卡能不能刷开那扇门”的利器。

∀p∈Permmin⁡(u):∃ t∈Tasks(u),  p∈Required(t)\displaystyle \forall p \in \mathrm{Perm}_{\min}(u): \exists\, t \in \mathrm{Tasks}(u),\; p \in \mathrm{Required}(t)
这个公式告诉我们:最终授予用户的每一个权限,都必须能找到一项工作任务作为“出处”;找不到任务支撑的权限,就不该存在。
  1. 对授予的每个权限做审查取用户被授予的任意一个权限 p,都要接受追问——哪项任务需要它?
    ∀p∈Permmin⁡(u)\displaystyle \forall p \in \mathrm{Perm}_{\min}(u)
  2. 权限必须对应某个任务p 必须属于用户某任务 t 的必要权限集合,即“没有它任务就干不成”。
    ∃ t∈Tasks(u),  p∈Required(t)\displaystyle \exists\, t \in \mathrm{Tasks}(u),\; p \in \mathrm{Required}(t)
  3. 找不到出处的权限不允许存在任何不在所有任务必要权限并集里的权限,都是多余的,应当被回收。
    ∄ p:p∈Perm(u)∖⋃t∈Tasks(u)Required(t)\displaystyle \nexists\, p : p \in \mathrm{Perm}(u) \setminus \bigcup_{t \in \mathrm{Tasks}(u)} \mathrm{Required}(t)

ServiceAccount管理

大楼里除了人类员工,还有一堆机器人——自动售货机、扫地机器人、系统巡检小车。它们也要身份,否则保安没法判断“是不是自己人”。Kubernetes 里跑在 Pod 中的程序,它们的身份凭证就是 ServiceAccount(服务账号)。你可以把它理解成“机器人员工的工作证”。

ServiceAccount 是命名空间级别的对象。当你创建一个 Pod 时,如果不显式指定,Kubernetes 会默认给它挂一个名为 default 的 ServiceAccount,并自动把一个长期有效的 Token(本质是 JWT)挂载到容器里,路径是 /var/run/secrets/kubernetes.io/serviceaccount/token。这个“自动发卡”机制很贴心,但也埋下隐患:很多容器根本不访问 APIServer,却白白揣着一张长期有效的卡,一旦容器被攻破,攻击者就把卡偷走了。Kubernetes 的 APIServer 在验证这张卡时,要走一条完整的校验链:

实践上的建议是:为不同业务 Pod 创建专用 ServiceAccount,比如监控 Pod 用 monitor-sa,只绑只读角色;外部访问需求少的 Pod,在 spec 里设置 automountServiceAccountToken: false 或把 SA 的该字段关掉,别让机器人揣着用不上的万能卡到处跑。

Verify(Token)→签名校验Subject→Bindings 查询Roles→RBAC 判定Access\displaystyle \mathrm{Verify}(\mathrm{Token}) \xrightarrow{\text{签名校验}} \mathrm{Subject} \xrightarrow{\text{Bindings 查询}} \mathrm{Roles} \xrightarrow{\text{RBAC 判定}} \mathrm{Access}
这个流程链说明:Token 不是“刷一下就行”,它先要被验签确认是集群签发而非伪造,再取出身份、查出角色、最终裁决权限。
  1. 验签APIServer 用集群公钥验证 Token 签名,确认门禁卡确实是公司签发的,而不是伪造的。
    Verify(Token)→{true,false}\displaystyle \mathrm{Verify}(\mathrm{Token}) \to \{\mathrm{true}, \mathrm{false}\}
  2. 提取身份验证通过后,从 Token 的 claims 中取出 subject,也就是 ServiceAccount 的名字。
    claims.sub=ServiceAccount 名称\displaystyle \mathrm{claims.sub} = \mathrm{ServiceAccount}\text{ 名称}
  3. 身份映射到授权用这个 SA 名字去查所有 Binding,得到它被授予的角色集合。
    ServiceAccount→BindingsRoles\displaystyle \mathrm{ServiceAccount} \xrightarrow{\mathrm{Bindings}} \mathrm{Roles}
  4. 最终判定最后走 RBAC 判定流程,裁决请求是 ALLOW 还是 DENY。
    Roles→Access(u,v,r)\displaystyle \mathrm{Roles} \to \mathrm{Access}(u, v, r)

Token与安全实践

门禁卡最怕什么?怕丢,怕被复制,怕丢了以后还能用十年。Kubernetes 的 Token 安全也围绕这三件事展开。新版 Kubernetes 默认用 TokenRequest API 签发短期 Token,它有过期时间,还支持绑定受众(audience),就算被偷,攻击者能利用的时间窗口也很有限。而旧式的长期 Token 存在 Secret 里,一存就是好几年,等于一张永不失效的万能钥匙。

Kubernetes 社区的安全基线一般建议:优先使用短期 Token 并配置自动轮换;为每个工作负载创建最小权限的专用 ServiceAccount;非必要场景关闭自动挂载;不要图省事把 Token 写进镜像或公共仓库。再加上多租户隔离的“三件套”——每个租户一个命名空间、RBAC 限制越权访问、ResourceQuota 限制资源配额——以及 APIServer 审计日志的开启,就能构筑层层防线。风险的量化模型很简单:

门禁管理员最需要的不是一面更厚的墙,而是三件不起眼的小事:勤换锁芯(轮换)、少发钥匙(最小权限)、随手关门(关闭自动挂载)。把这三点做扎实,你的 K8s 集群就能在安全审计面前从容不迫。

Risk=Exposure×Privilege×Time\displaystyle \mathrm{Risk} = \mathrm{Exposure} \times \mathrm{Privilege} \times \mathrm{Time}
这个公式揭示了降低风险的三种手段:减少暴露(不把 Token 乱丢)、降低权限(最小权限)、缩短时间(短期 Token 勤轮换)。三个因子任何一个降为 0,风险就归零。
  1. 暴露面Token 被泄露到镜像、日志、第三方仓库的概率,暴露面越大风险越高。
    Exposure=P(凭证泄露)\displaystyle \mathrm{Exposure} = P(\text{凭证泄露})
  2. 权限面该凭证绑定的权限越大,一旦泄露,攻击者能造成的破坏越严重。
    Privilege=∣Perm(subject)∣\displaystyle \mathrm{Privilege} = |\mathrm{Perm}(\text{subject})|
  3. 时间窗口Token 有效期越长,攻击者可以利用它反复横跳的时间越充裕。
    Time=TTL(Token)\displaystyle \mathrm{Time} = \mathrm{TTL}(\mathrm{Token})
  4. 三因子相乘这是“安全没有银弹,但有杠杆”的数学表达——把任何一个因子压到最小,整体风险就急速坍缩。
    Risk=E×P×T\displaystyle \mathrm{Risk} = E \times P \times T

AI 应用场景

多租户 AI 平台的租户隔离

阶段:云原生基础设施层(多租户接入)

解决的问题:传统做法让所有租户共用一套账号权限,越权访问风险极高,审计时说不清“谁动了谁的数据”。AI 平台用“命名空间 + RBAC”为每个租户划出独立楼层:租户管理员只能管理自己命名空间内的模型服务,平台方用 ClusterRole 统一管理集群级只读监控权限。

具体案例:一家提供模型训练平台的 AI 公司,为每个客户创建独立命名空间,并为每个训练任务绑定专用 ServiceAccount——任务只能读取自己的数据集和模型仓库,无法碰其他租户的任何资源。

CI/CD 流水线的机器身份管理

阶段:模型交付与发布(CI/CD)

解决的问题:流水线若用同一个管理员 Token 部署集群,权限过大且泄露面广。改为每个流水线项目创建专用 ServiceAccount,部署角色只含 deployments 的 get/list/patch 等必要动词,配合短期 Token 做到“用完即弃”。

具体案例:某算法团队的 GitLab CI 在构建阶段用只读 SA 查询 Pod 状态,只有在发布阶段才切换到受限的 deployer 身份,且每次发布自动换取新 Token,有效避免了“一人泄露全集群沦陷”。

等保与 SOC2 合规审计

阶段:安全审计与合规

解决的问题:合规审计要求证明“谁在何时对什么资源做了什么操作”,人工翻日志既不现实也易遗漏。开启 APIServer 审计日志后,定期用脚本扫描所有 RoleBinding,生成权限矩阵报告,并自动标记权限过大的高风险账号。

具体案例:某金融 AI 部门每季度执行一次权限巡检,用 kubectl auth can-i 批量核验关键账号的实际权限,自动回收三个月未使用的角色绑定,并输出合规报告供审计使用。

Python 演示

python69 行
class RBACSystem:    # 极简RBAC模型, 模拟Kubernetes的角色/绑定/鉴权判定    def __init__(self):        self.roles = {}        # 角色名 -> 规则列表        self.binds = []        # (主体, 角色, 命名空间) 列表        self._check_count = 0  # 鉴权次数统计     def create_role(self, name, rules):        self.roles[name] = rules     def create_binding(self, subject, role, namespace):        self.binds.append((subject, role, namespace))     def can(self, user, verb, resource, namespace):        self._check_count += 1        for subject, role, ns in self.binds:            if subject not in (user, "*"):                continue            if ns is not None and ns != namespace:                continue            for rule in self.roles.get(role, []):                verb_ok = rule["verbs"] == "*" or verb in rule["verbs"]                res_ok = rule["resources"] == "*" or resource in rule["resources"]                if verb_ok and res_ok:                    return True        return False  # 默认拒绝: 任何规则未命中即拒绝     def audit_wide_rules(self):        wide = []        for name, rules in self.roles.items():            for rule in rules:                if rule["verbs"] == "*" or rule["resources"] == "*":                    wide.append((name, rule["resources"], rule["verbs"]))        return wide     @property    def check_count(self):        return self._check_count  def main():    rbac = RBACSystem()    rbac.create_role("viewer", [        {"verbs": ["get", "list", "watch"], "resources": ["pods", "services"]}    ])    rbac.create_role("deployer", [        {"verbs": ["get", "list", "create", "patch"], "resources": ["deployments"]}    ])    rbac.create_binding("ops-user", "deployer", "prod")    rbac.create_binding("dev-user", "viewer", "dev")    rbac.create_binding("ci-robot", "deployer", "prod")     tests = [        ("ops-user", "patch", "deployments", "prod"),        ("dev-user", "list", "pods", "dev"),        ("dev-user", "delete", "pods", "dev"),        ("ci-robot", "get", "deployments", "prod"),        ("dev-user", "get", "secrets", "dev"),    ]    for user, verb, res, ns in tests:        result = "ALLOW" if rbac.can(user, verb, res, ns) else "DENY"        print("%s %s %s in %s => %s" % (user, verb, res, ns, result))     print("total checks:", rbac.check_count)    print("wide rules:", rbac.audit_wide_rules())  if __name__ == "__main__":    main()
目的:用 60 行代码实现了 K8s RBAC 的核心判定逻辑——角色定义、绑定、默认拒绝、最小权限审计,可直接运行观察不同身份对资源的访问结果。
  1. self.binds = []用列表保存所有“发卡记录”,每条记录包含主体、角色和生效命名空间,对应 K8s 的 RoleBinding 列表。
  2. self._check_count = 0计数器统计鉴权次数,属性加下划线前缀避免与方法名冲突。
  3. def can(self, user, verb, resource, namespace)鉴权的核心入口,依次匹配主体、命名空间和角色规则,对应 RBAC 判定流程。
  4. if subject not in (user, "*"):支持通配符主体,模拟 K8s 中绑定 system:authenticated 组对所有登录用户生效的用法。
  5. return False默认拒绝的安全兜底,任何规则未命中就直接拒绝,对应“没有明确说行就是不行”。
  6. def audit_wide_rules(self)审计函数,扫描所有含 * 通配符的过宽规则,对应最小权限原则中的权限收敛检查。
  7. rbac.create_binding("dev-user", "viewer", "dev")把 viewer 角色绑定给 dev 用户且只在 dev 命名空间生效,演示 RoleBinding 的局部授权。

常见误区

误区我以为写好 Role 的 YAML apply 到集群,用户就有权限了。结果用户一直报 403,调了半天才发现根本没建 Binding,可文档里明明说“创建角色即可授权”。

正解Role 只是“岗位说明书”,不 Binding 就等于没发卡。RBAC 的权限链路是:身份 → 角色 → 绑定 → 资源,四者缺一不可。把 Role 定义好却不绑定任何主体,就像把岗位职责贴在墙上但没人持有对应门禁卡,门禁系统当然不放行。

为何常见:Role 和 ClusterRole 是看得见的 YAML 文件,而 Binding 是容易被忽略的“胶水”环节。新手往往混淆“定义权限”和“授予权限”这两个动作。

误区给所有开发和流水线账号直接绑定 cluster-admin,省得每次排障都要申请权限。反正集群是内部用的,有问题可以随时再收紧。

正解cluster-admin 是全集群的“万能钥匙”,任何持有者的账号被攻破,整个集群都会沦陷,包括所有业务数据和其他租户。正确做法是遵循最小权限:普通开发给 viewer,发布给 deployer,只有平台管理员才用 admin,且要配合审计日志定期验证。

为何常见:排障时缺权限确实恼火,而“给满权限”是最短路径;加上团队缺乏权限分级意识,就养成了图省事的坏习惯。

误区我始终认为 RoleBinding 只能绑 Role,ClusterRoleBinding 只能绑 ClusterRole,名字必须配对,否则 Kubernetes 应该会报错。

正解RoleBinding 完全可以绑定 ClusterRole,只是绑定后 ClusterRole 的权限会被收窄到该命名空间。这是官方推荐的“全局模板 + 局部授权”模式:定义一份全局通用的 ClusterRole,再用多个 RoleBinding 把它分别下放到不同命名空间,避免重复编写十份相似角色。

为何常见:Role 配 RoleBinding、ClusterRole 配 ClusterRoleBinding 的命名直觉太强了,让人以为必须一一对应,而忽略了 K8s 文档中“RoleBinding 引用 ClusterRole”的灵活设计。

误区只要把两个团队的资源放在不同的命名空间里,他们就天然隔离了,谁也看不到谁的数据,安全得很。

正解namespace 只提供资源命名的逻辑隔离,不提供安全隔离。没有 RBAC 限制,任何有权限的用户照样可以跨命名空间访问;没有 NetworkPolicy,Pod 之间可以互相打通网络。真正的安全隔离需要 RBAC 控制 API 访问 + NetworkPolicy 控制网络 + ResourceQuota 控制资源配额三者配合。

为何常见:“隔离”这个词让人联想到虚拟机的硬隔离,而实际上 namespace 只是把文件放进不同文件夹,文件夹本身不上锁。

面试题

Q1. Role 与 ClusterRole 的核心区别是什么?

单选题 · easy

  • A.Role只能作用于单个命名空间内← 正确答案
  • B.ClusterRole只能作用于默认空间
  • C.Role与ClusterRole作用域完全相同
  • D.ClusterRole权限比Role权限更小

答案:A。Role 创建时必须指定命名空间,权限被限制在该命名空间内,就像部门内部岗位;ClusterRole 不绑定命名空间,可以管理节点、PV 等集群级资源。选项 B 错误,ClusterRole 不是“默认空间专用”;C、D 与事实相反。

Q2. 用户未绑定任何角色时,在启用 RBAC 的集群中默认拥有什么权限?

单选题 · easy

  • A.默认拥有集群全部管理员权限
  • B.默认拥有只读权限可以查看资源
  • C.默认被拒绝所有资源操作请求← 正确答案
  • D.默认权限取决于创建的命名空间

答案:C。RBAC 遵循默认拒绝原则,没有显式授权就一律拒绝。就像新员工的门禁卡默认刷不开任何门。选项 A、B 都违背了默认拒绝;D 是干扰项,命名空间不自动产生权限。

Q3. 用 RoleBinding 绑定一个 ClusterRole,会发生什么?

单选题 · mid

  • A.语法报错无法完成绑定操作
  • B.权限会被收窄到该命名空间内← 正确答案
  • C.会立刻获得集群级超级管理员
  • D.绑定的ClusterRole将自动失效

答案:B。RoleBinding 可以绑定 ClusterRole,且绑定后 ClusterRole 的权限被限定在 RoleBinding 所在的命名空间内,即“全局模板 + 局部授权”。A 错误,语法完全合法;C 混淆了 ClusterRoleBinding 的作用;D 无中生有。

Q4. 下列哪些属于 Kubernetes RBAC 中的主体(Subject)?

多选题 · mid

  • A.User用户账号← 正确答案
  • B.Group用户组← 正确答案
  • C.ServiceAccount服务账号← 正确答案
  • D.Namespace命名空间对象

答案:ABC。RBAC 的主体是“谁发起请求”的三类对象:User(人)、Group(用户组)、ServiceAccount(程序身份)。Namespace 是资源所属的“楼层”,它是资源的作用范围而不是请求主体,所以 D 不选。

Q5. 最小权限原则的核心思想是什么?

单选题 · mid

  • A.授予完成工作所需的最少权限← 正确答案
  • B.给所有用户授予管理员全部权限
  • C.权限越多越方便运维排障工作
  • D.定期删除所有角色和绑定策略

答案:A。最小权限要求每个被授予的权限都有任务作为“出处”,只给够用的钥匙,不给金库钥匙。B、C 与原则背道而驰;D 把“清理冗余”误解为“全部删除”,删除所有角色会让集群无法正常运作。

Q6. 关于 ServiceAccount 自动挂载 Token 的安全实践,正确的是?

单选题 · mid

  • A.无外部访问时建议关闭自动挂载← 正确答案
  • B.自动挂载Token越多权限越大越好
  • C.所有Pod都必须挂载长期Token
  • D.Token只能由ServiceAccount绑定使用

答案:A。很多 Pod 根本不访问 APIServer,默认挂载的长期 Token 反而扩大了暴露面,建议设置 automountServiceAccountToken: false。B 完全错误,权限并非越大越好;C 说法绝对化;D 是正确陈述但答非所问,不是“安全实践”。

Q7. 下列哪些措施能有效降低 Token 泄露带来的安全风险?

多选题 · hard

  • A.使用短期Token并定期轮换← 正确答案
  • B.关闭非必要Pod的自动挂载← 正确答案
  • C.把Token写入公开镜像仓库
  • D.为Pod绑定最小权限专用SA← 正确答案

答案:ABD。风险 = 暴露面 × 权限 × 时间。短期 Token 压缩时间因子,关闭自动挂载降低暴露面,最小权限 SA 缩减权限因子,三者都有效。C 直接把 Token 放进公开仓库等于把钥匙贴在门口,是典型反面操作。

Q8. ClusterRoleBinding 的作用范围是什么?

单选题 · easy

  • A.只对默认命名空间生效
  • B.作用范围覆盖集群所有空间← 正确答案
  • C.只能绑定普通用户不能绑定组
  • D.与RoleBinding权限完全相同

答案:B。ClusterRoleBinding 在整个集群范围内生效,可以授权用户、组和 ServiceAccount 访问所有命名空间的资源,相当于“全公司开通权限”。A、D 混淆了它和 RoleBinding;C 错误,它可以绑定 Group 和 ServiceAccount。

Q9. 多云多租户场景下,K8s 推荐哪些隔离措施组合?

多选题 · hard

  • A.每个租户使用独立命名空间← 正确答案
  • B.绑定最小权限角色进行约束← 正确答案
  • C.所有租户共用一个集群管理员
  • D.配置ResourceQuota资源限额← 正确答案

答案:ABD。租户隔离三件套:命名空间做逻辑划分、RBAC 最小权限防越权、ResourceQuota 防资源争抢,再配合 NetworkPolicy 做网络隔离。C 是反面做法,所有租户共用一个管理员会让隔离形同虚设。

Q10. kubectl auth can-i 命令的主要作用是什么?

单选题 · easy

  • A.查询当前用户能否执行某操作← 正确答案
  • B.创建新的角色和绑定关系
  • C.删除集群中无效的节点对象
  • D.修改Pod副本数的动态调整

答案:A。kubectl auth can-i get pods -n dev 可以快速自测当前用户对某资源是否有某动词权限,相当于在门禁前先试刷一下卡。B、C、D 分别对应 kubectl create、kubectl delete、kubectl scale,与鉴权自测无关。