2. K8s API访问控制全景:认证、鉴权、准入控制三层模型详解与交互流程
Kubernetes API Server 是集群所有操作的唯一入口。任何对集群资源的创建、读取、更新、删除(CRUD)请求,都必须经过一个严格的三层安全过滤模型:认证(Authentication)→ 鉴权(Authorization)→ 准入控制(Admission Control)。理解这三层的职责、顺序与交互细节,是设计安全拦截策略的基础。
核心原则:三层模型按顺序执行,前一层通过后才会进入下一层。任何一层拒绝,请求立即终止并返回错误响应(通常为 401、403 或 422)。
2.1 三层模型总览与职责划分
下表清晰定义了每一层的核心职责、处理对象以及典型失败响应码:
| 层级 | 英文名称 | 核心职责 | 处理对象 | 失败响应码 |
|---|---|---|---|---|
| 第一层:认证 | Authentication | 验证请求发起方的身份真实性 | 证书、Token、用户名/密码、JWT | 401 Unauthorized |
| 第二层:鉴权 | Authorization | 判断已认证的用户是否有权限执行请求的操作 | RBAC 规则、ABAC 策略、Node 授权 | 403 Forbidden |
| 第三层:准入控制 | Admission Control | 在对象持久化前,对请求进行校验、修改或策略强制执行 | Mutating Webhook、Validating Webhook、内置插件 | 422 Unprocessable Entity 或 403 |
关键区分:认证回答“你是谁?”,鉴权回答“你能做什么?”,准入控制回答“你做的这件事是否符合集群策略?”。
2.2 三层交互流程详解
一个完整的 API 请求从进入 API Server 到持久化到 etcd,其内部交互流程如下:
- 请求到达 API Server:客户端(kubectl、Pod 内 ServiceAccount、外部应用)通过 HTTPS 发送请求到 API Server 的 6443 端口。
- 认证阶段:API Server 按顺序尝试配置的认证模块(如 X.509 证书、Bearer Token、Webhook TokenReview)。一旦某个模块成功提取并验证了用户身份,认证阶段即通过,请求上下文被注入
user、uid、groups信息。 - 鉴权阶段:API Server 将请求(包含用户、操作、资源、命名空间)发送给鉴权模块链(通常为 RBAC)。鉴权模块检查是否有匹配的 Role/ClusterRole 绑定。如果所有鉴权模块都拒绝,则返回 403。
- 准入控制阶段:鉴权通过后,请求进入准入控制链。该链分为两轮:
- 第一轮:Mutating Admission(变更准入)—— 允许 Webhook 或内置插件修改请求对象(例如注入 Sidecar、设置默认值)。
- 第二轮:Validating Admission(验证准入)—— 验证请求对象的合法性(例如检查镜像仓库白名单、Pod 安全策略)。
- 持久化:所有准入控制通过后,API Server 将对象序列化并写入 etcd,返回成功响应给客户端。
注意:Mutating Webhook 在 Validating Webhook 之前执行,这是为了确保验证逻辑看到的是经过默认值填充和策略注入后的最终对象。如果 Mutating Webhook 修改了对象,Validating Webhook 必须重新验证。
2.3 三层模型交互流程图
下图直观展示了请求从客户端到 etcd 的完整路径,以及三层安全模型的拦截点:
2.4 认证模块链与常见策略
API Server 启动时通过 --authentication-token-webhook-config-file 等参数配置认证模块链。模块按顺序执行,只要有一个模块成功,认证即通过。常见认证策略对比:
| 认证方式 | 适用场景 | 安全等级 | 管理复杂度 |
|---|---|---|---|
| X.509 客户端证书 | kubelet、kube-controller-manager 等组件间通信 | 高 | 中(需管理 CA 和证书轮换) |
| ServiceAccount Token | Pod 内应用访问 API | 中 | 低(自动挂载) |
| OIDC (OpenID Connect) | 企业 SSO、用户身份联邦 | 高 | 高(需外部 IdP) |
| Webhook TokenReview | 自定义认证逻辑、第三方鉴权服务 | 中-高 | 高(需自行实现 Webhook) |
| 静态 Token / 密码文件 | 测试、开发环境 | 低 | 低 |
2.5 鉴权模块链与 RBAC 核心模型
鉴权阶段同样支持多模块链式执行,但逻辑与认证不同:所有鉴权模块都必须拒绝,请求才会被拒绝;只要有一个模块允许,鉴权即通过。生产环境最常用的是 RBAC(基于角色的访问控制),其核心模型包含四个元素:
- Subject(主体):User、Group、ServiceAccount。
- Resource(资源):Pod、Service、Deployment、Node 等。
- Verb(操作):get、list、create、update、delete、watch 等。
- Role / ClusterRole(角色):定义一组权限规则。Role 作用于命名空间,ClusterRole 作用于集群范围。
- RoleBinding / ClusterRoleBinding(角色绑定):将 Subject 与 Role/ClusterRole 关联。
最佳实践:始终遵循最小权限原则。为每个 ServiceAccount 创建独立的 Role 和 RoleBinding,避免使用 cluster-admin 等超级角色。定期审计 RoleBinding 列表,移除不再使用的绑定。
2.6 准入控制链与 Webhook 架构
准入控制是三层模型中最灵活、最强大的扩展点。它分为 内置插件 和 动态 Webhook 两类。动态 Webhook 的架构如下图所示:
2.7 常见场景与三层模型的关系
理解三层模型后,可以快速定位常见安全问题的拦截层:
| 场景 | 拦截层 | 典型配置 |
|---|---|---|
| kubectl 证书过期 | 认证层 | 更新 kubeconfig 中的 client-certificate-data |
| ServiceAccount 尝试删除集群级别的 Node | 鉴权层 | 检查 RoleBinding 是否使用了 ClusterRole |
| 创建 Pod 时未指定资源限制 | 准入控制层 | 部署 Mutating Webhook 自动注入 LimitRange |
| 部署镜像来自非白名单仓库 | 准入控制层 | 部署 Validating Webhook 检查 image 字段 |
| 匿名用户访问集群 | 认证层 | 禁用 --anonymous-auth=false |
学习建议:在生产环境中排查 API 请求失败时,首先查看 API Server 日志中的
HTTP 401/403/422 状态码,快速定位是认证、鉴权还是准入控制层的问题,然后针对性地检查对应层的配置。