Kubernetes 鉴权基础:RBAC、ServiceAccount、TokenReview API 原理
在 Kubernetes 集群中,鉴权(Authentication)与授权(Authorization)是两道独立的防线。鉴权确认“你是谁”,授权决定“你能做什么”。本章聚焦于授权层的核心机制——RBAC(基于角色的访问控制),以及与之紧密关联的 ServiceAccount 和 TokenReview API。理解这三者的原理,是设计分布式事务鉴权拦截与故障恢复方案的基石。
3.1 RBAC:基于角色的访问控制
RBAC 是 Kubernetes 默认且最推荐的授权模式。它通过四个核心资源对象实现细粒度的权限管理:Role、ClusterRole、RoleBinding、ClusterRoleBinding。
| 资源对象 | 作用域 | 典型用途 |
|---|---|---|
| Role | 命名空间(Namespace) | 授予某个命名空间内 Pod、Service、Deployment 等资源的操作权限 |
| ClusterRole | 集群全局 | 授予集群级别资源(Node、PV、ClusterRole 自身)或跨命名空间资源的权限 |
| RoleBinding | 命名空间 | 将 Role 绑定到用户、组或 ServiceAccount,限定在特定命名空间内生效 |
| ClusterRoleBinding | 集群全局 | 将 ClusterRole 绑定到用户、组或 ServiceAccount,在整个集群范围内生效 |
关键原则:RBAC 遵循“最小权限”原则。默认情况下,所有请求都被拒绝,只有通过 RoleBinding 或 ClusterRoleBinding 显式授予的权限才会被允许。在分布式事务场景中,跨命名空间的服务调用需要特别注意 ClusterRole 的配置。
以下是一个典型的 RBAC 配置示例,授予 my-sa 在 production 命名空间中对 Pod 的只读权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: production
name: read-pods
subjects:
- kind: ServiceAccount
name: my-sa
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
3.2 ServiceAccount:Pod 的身份凭证
ServiceAccount 是 Kubernetes 中为 Pod 内进程提供的身份标识。与普通用户不同,ServiceAccount 由 Kubernetes API 管理,并自动挂载到 Pod 中。
- 自动挂载:每个命名空间都有一个默认的
defaultServiceAccount。当 Pod 创建时,Kubernetes 会自动将 ServiceAccount 的令牌(Token)以卷挂载的形式注入到 Pod 的/var/run/secrets/kubernetes.io/serviceaccount/目录下。 - 令牌类型:传统上使用静态的 Secret 令牌(已弃用),现在推荐使用 Bound Service Account Token Volume,该令牌具有更短的过期时间、更严格的作用域绑定,并且支持 TokenReview API 进行实时校验。
- 与 RBAC 结合:ServiceAccount 本身没有权限,必须通过 RoleBinding 或 ClusterRoleBinding 绑定到 Role 或 ClusterRole 后才能获得授权。
故障恢复视角:在分布式事务鉴权拦截场景中,ServiceAccount 的令牌泄露或过期是常见故障源。建议启用 Bound Service Account Token,并配置合理的
--service-account-max-token-expiration 参数(默认 1 小时),以降低令牌滥用风险。
3.3 TokenReview API:令牌实时校验
TokenReview API 是 Kubernetes 提供的一个内部 API,用于验证 ServiceAccount 令牌的有效性。它通常由 API Server 内部的鉴权模块调用,但也可以被外部组件(如自定义准入控制器、Sidecar 代理)使用,以实现分布式事务中的鉴权拦截。
3.3.1 工作原理
- 请求发起:客户端(Pod 或外部服务)携带 Bearer Token 向 API Server 发送请求。
- 鉴权拦截:API Server 的鉴权模块(Authentication Webhook 或内置的 TokenReview)拦截请求,提取 Token。
- TokenReview 调用:API Server 构造一个
TokenReview对象,发送给 Kubernetes 内部的 TokenReview API。 - 令牌验证:TokenReview API 检查 Token 的签名、过期时间、颁发者(Issuer)以及是否被绑定到特定的 Pod 和 ServiceAccount。
- 返回结果:返回
authenticated(true/false)以及关联的用户信息(User Info),包括username(ServiceAccount 名称)、uid、groups。 - 授权决策:API Server 将用户信息传递给授权模块(如 RBAC),根据绑定的 Role 决定是否允许操作。
故障恢复关键点:TokenReview API 的可用性直接影响集群的鉴权能力。如果 TokenReview 服务(通常由 kube-apiserver 内置)出现故障,所有依赖令牌验证的请求都将失败。在分布式事务场景中,建议对 TokenReview 调用设置超时和重试机制,并监控其响应延迟。
3.3.2 TokenReview 请求与响应结构
以下是一个 TokenReview 的典型请求和响应示例:
# 请求示例
{
"apiVersion": "authentication.k8s.io/v1",
"kind": "TokenReview",
"spec": {
"token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9..."
}
}
# 响应示例(成功)
{
"apiVersion": "authentication.k8s.io/v1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
"username": "system:serviceaccount:production:my-sa",
"uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"groups": ["system:serviceaccounts", "system:serviceaccounts:production"]
},
"audiences": ["https://kubernetes.default.svc.cluster.local"]
}
}
# 响应示例(失败)
{
"apiVersion": "authentication.k8s.io/v1",
"kind": "TokenReview",
"status": {
"authenticated": false,
"error": "token has expired"
}
}
3.4 三者的协同关系
在分布式事务鉴权拦截场景中,RBAC、ServiceAccount 和 TokenReview API 协同工作,形成完整的鉴权授权链路:
- ServiceAccount 提供身份凭证(Token),是鉴权的起点。
- TokenReview API 负责验证 Token 的真实性和有效性,是鉴权的核心。
- RBAC 基于验证后的身份信息,决定是否允许执行特定操作,是授权的最终裁决者。
故障恢复设计要点:
- 当 TokenReview API 响应超时或失败时,应触发降级策略:例如,对于只读操作可以允许通过(但记录审计日志),对于写操作则必须拒绝。
- ServiceAccount 的 Token 轮换机制(如使用 Bound Token)可以减少因令牌泄露导致的鉴权故障。
- RBAC 配置错误(如遗漏必要的 ClusterRoleBinding)是分布式事务中常见的故障原因,建议使用
kubectl auth can-i命令进行预验证。