2.2 kubectl apply 的安检流水线:认证、授权与准入


2.2 kubectl apply 的安检流水线:认证、授权与准入

每一次 kubectl apply 都要依次通过三道关卡:认证(Authentication,验证你是谁)、授权(Authorization,判定你能否对这个资源执行这个动作)、准入(Admission,对提交内容做最后的修改或否决)。本节逐关拆解,并给出生产可用的 RBAC 最小权限配置。

声明抵达 API Server 后并不会直接入账,2.1 节的窗口只是前台,窗口后面还有三道安检。这一节是集群安全的入口章:读懂三道关卡,403 报错、权限设计、准入副作用这三类日常问题就都有了坐标系。更深的密钥管理话题留待第7章运行安全时展开。

一、安检的三道关卡

先给三道关卡一张总览表,记住它们各自回答的问题与失败时的报错特征:

关卡 回答的问题 典型机制 失败时的表现
认证 你是谁 客户端证书、令牌、kubeconfig 401,匿名身份被拒
授权 你能做什么 RBAC 的 Role 与 RoleBinding 403,指出缺哪个动词
准入 这次提交要不要改 变异准入与校验准入插件 422 或声明被静默修订

顺序不可颠倒:先有身份才谈权限,先有权限才轮到内容审查。三道全过,声明才获得入账资格。

图 2-2:一次 apply 请求的三道安检关卡

图 2-2:一次 apply 请求的三道安检关卡

二、认证与授权:身份与权限的分离

kubectl 的身份来自 kubeconfig 文件里的凭证——通常是一张客户端证书。证书里的 CN 字段就是你的用户名,O 字段是组名:

# 查看当前生效的身份与上下文 kubectl config get-contexts # CURRENT NAME CLUSTER AUTHINFO NAMESPACE # * prod-ctx prod alice production # 模拟查看自己的身份(权限模拟,需要管理员预先授权) kubectl auth whoami # Attribute: Username # Value: alice

身份只是入场券,权限由 RBAC 决定。RBAC 的核心是两份 YAML 的组合:Role 说"在这个空间里,哪些动词可以作用于哪些资源";RoleBinding 说"把这些能力授予谁"。给平台组配一个生产空间的只读角色:

apiVersion: rbac.authorization.k8s.io/v1 kind: Role # 命名空间级的权限范围 metadata: name: orders-reader namespace: production rules: - apiGroups: ["", "apps"] # 空串代表核心组,apps 是应用组 resources: ["pods", "pods/log", "deployments"] verbs: ["get", "list", "watch"] # 只读三件套,不含 create/update/delete --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding # 把角色与用户缝合 metadata: name: read-orders namespace: production subjects: - kind: User name: alice # 授权对象:用户 alice roleRef: kind: Role name: orders-reader apiGroup: rbac.authorization.k8s.io

申请了只读权限的人试图改副本数,会被关卡二拦下,报错信息相当体贴:

kubectl scale deployment orders-api --replicas=5 -n production # Error from server (Forbidden): deployments.apps "orders-api" is forbidden: # User "alice" cannot update resource "deployments" in API group "apps" # in the namespace "production"

报错把缺的三要素全说出来了:谁(alice)、缺哪个动词(update)、在哪个空间(production)。读 403 的套路固定:从报错里反查该补哪条规则,而不是盲目给人绑 cluster-admin。

⚠️ 常见坑:为了省事把同事都绑成 cluster-admin(全集群超级权限)。一旦某个人的 kubeconfig 泄露,攻击者等于拿到整个集群。最小权限原则在 Kubernetes 里是可执行的,RoleBinding 精确到 verbs 与 resources。

三、准入:声明入账前的最后一双眼睛

过了授权,声明的内容还要被准入控制器审一遍。准入分两类,先变异、后校验,都通过才落账。常见的守门动作:

  • 默认值注入:ServiceAccount 自动挂载、limitranges 给漏写资源的容器补默认值——你的声明悄悄变厚,但变得更安全;
  • 强制校验:要求必须带某类标签、必须设资源限制、镜像仓库必须来自受信域名——不满足直接打回,返回 422;
  • 资源配额:空间内资源总量超限时拒绝创建。

变异准入的效果可以直接观察。提交一个没写资源限制的 Pod,然后看入账后的它:

# 提交前先问一声:如果通过全部安检,最终入账的对象长什么样 kubectl apply -f bare-pod.yaml --dry-run=server -o yaml | grep -A6 resources: # resources: # limits: # cpu: "1" # memory: 1Gi # 这两行不是我写的,是变异准入补的 # requests: # cpu: 500m # memory: 512Mi

dry-run 配合 -o yaml 是观察准入改写的最佳姿势:你提交的 YAML 与集群记住的 YAML 可能有差异,差异就来自这双看不见的手。第6章讲 ConfigMap 注入、第7章讲安全基线时,都会与准入插件打交道。

四、演练:为新同事走完三道关卡

背景:新同事 bob 要参与订单服务的日常观测,需要能看 Pod、日志与事件,但不能改动任何东西。

操作:三步走——签发身份(由集群管理员配 kubeconfig)、套用 2.2 节的 Role、绑定时把 subjects 换成 bob,随后用模拟命令验证权限边界:

# 不切换身份,直接模拟 bob 能否执行两个动作 kubectl auth can-i get pods -n production --as bob # yes kubectl auth can-i delete pods -n production --as bob # no # 两行输出就是权限设计的验收单

结果:bob 的所有读操作畅通,任何写操作在关卡二被拒,报错格式与前面 alice 的完全一致。

解读:认证解决"进门",授权解决"能碰哪些东西",两者解耦意味着同一个身份在不同空间可以有完全不同的权限画像。can-i 模拟是发布权限变更前的标准自检,比"配完让用户试"体面得多。

变式:CI 流水线需要部署权限时,把 subjects 的 kind 换成 ServiceAccount,授权对象从人变成服务账号,权限边界更清晰;跨空间的权限(如平台组要看所有空间)则用 ClusterRole 配合 RoleBinding,规则复用而范围仍受控。

本节要点回顾

  • 三道关卡顺序固定:认证验身份、授权定边界、准入改内容,任何一步失败都到不了 etcd;
  • RBAC 双件套:Role 定义能力,RoleBinding 把能力缝到身份上,verbs 与 resources 精确到动作级;
  • 403 是自查清单:报错自带用户名、动词、资源、空间四要素,缺什么补什么;
  • 准入有变异与校验两类:dry-run 加 -o yaml 能看到集群最终记住的版本;
  • can-i 模拟是验收工具:发布权限前先模拟目标用户的动作,免得用户当测试员。

声明过了三关、即将落账。下一节看它落入的这本账——etcd 为什么是唯一真相源,以及 Watch 广播如何让调度器和控制器在秒级知晓新声明的到来。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U