1、概述
Kubernetes 中的 TokenReview 是用于验证令牌(Token)有效性的一种 API 资源,属于 authentication.k8s.io/v1 API 组。
它允许客户端通过创建 TokenReview 对象向 API Server 发起一个请求以验证一个令牌是否合法,并获取与该令牌关联的用户信息(如用户名、组、附加属性等)。大致验证流程如下:
- +----------------+ (1) 创建 TokenReview 请求 +----------------+
- | 客户端 | ------------------------------------> | API Server |
- | (外部服务等) | | (服务端) |
- +----------------+ <------------------------------------ +----------------+
- (2) 返回验证结果(status 字段)
-
当客户端(如第三方服务、自定义控制器或 CLI 工具)需要验证一个令牌时,它通过创建 TokenReview 对象向 API Server 发起一个请求。
-
真正执行验证逻辑的是 API Server(服务端),服务端帮助客户端验证令牌。
-
API Server 根据配置的认证机制(如 ServiceAccount、Webhook 等)验证令牌,并返回结果(status.authenticated、status.user 等)。
2、TokenReview 的用途
-
令牌验证:验证一个令牌(如 ServiceAccount Token)是否有效。
-
身份信息获取:返回与该令牌关联的身份信息(如用户、组、扩展属性等)。
-
集成认证:用于自定义身份验证流程(例如与外部认证服务集成)。
3、TokenReview 的定义
TokenReview是一个 Kubernetes API 对象,其结构如下:
- apiVersion: authentication.k8s.io/v1
- kind: TokenReview
- spec:
- token: "<Bearer Token>" # 要验证的令牌(必需)
- audiences: ["aud1", "aud2"] # 可选:指定令牌的目标受众(audience),如果令牌的受众不匹配,验证会失败,通过kube-apiserver验证话受众为https://kubernetes.default.svc.cluster.local
4、使用示例
4.1 为用户创建Token
(1)创建用户:
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: zmc-serviceaccount

注意:在 Kubernetes v1.24 之前,每当创建一个 ServiceAccount 时,Kubernetes 会自动为其创建一个包含令牌(token)的 Secret 对象,并且将这个 Secret 挂载到使用该 ServiceAccount 的 Pod 中,以便 Pod 可以使用这个令牌与 Kubernetes API 服务器进行通信。在Kubernetes v1.24 版本开始,创建 ServiceAccount 时默认不再自动创建对应的 Secret 对象。
(2)通过TokenRequest 为给定的服务账号请求一个令牌
可以使用 TokenRequest API 动态请求令牌。示例如下,使用 kubectl 为 ServiceAccount 请求令牌:
- kubectl create token <serviceaccount-name>
也可以通过编写代码向 Kubernetes API 服务器发送 TokenRequest 请求,例如使用 curl 在 Pod 内请求令牌:
- TOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest", "spec": {"audience": "https://kubernetes.default.svc"}}' https://kubernetes.default.svc/api/v1/namespaces/<namespace>/serviceaccounts/<serviceaccount-name>/token --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)")
- echo $TOKEN
本来通过kubectl命令为ServiceAccount zmc-serviceaccount颁发令牌:
- kubectl create token zmc-serviceaccount
- eyJhbGciOiJSUzI1NiIsImtpZCI6ImpyaFRNMDRFR0h5a2JpSUY2Vk5jM2lZYnRYY2Fwcl9yTmhDV04tTkdzdnMifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQxMjY4NDEzLCJpYXQiOjE3NDEyNjQ4MTMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InptYy1zZXJ2aWNlYWNjb3VudCIsInVpZCI6ImJhZDE1ODExLWMyMzktNGEzYy1hMTkzLWI3ZWViYWRmY2YxZSJ9fSwibmJmIjoxNzQxMjY0ODEzLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp6bWMtc2VydmljZWFjY291bnQifQ.u53WwYrQILWQEIkKo06J6eIBB1Tw5oqEdCAMuRsx7XBjPZZM79WcVi-cGcRmzIAX6Hqdqqg6IMVf9xWzLYx1yfO7sad183Wbq_puJJJDH5o2C6mdUEcfthAD7EKmhgF35JFCYSnM0d7d0-8xRVyelNALR-Ex7yr91EL1e5OUuu9hx7fbhL91xeIxwTzB-5dNPt16km8Z9pdt4HzG3EC_zWeBdHIwEK5DRc1fvPenwDAbRFNQGMNAXQrLjPNJjGQboBC6M70fXwOxDa8l-9oNDIfWlx5bBNqCzUYaT3gx4G5tsRd99UmCcVN8EVlw_7h119GiYJlIPgjx1nqT2q28vg
验证token:

4.2 客户端通过创建TokenReview对象向API Server发起一个请求以验证一个令牌是否合法,并获取与该令牌关联的用户信息
同4.1,向API Server发送认证请求同样可以通过Kubectl或者通过 Kubernetes API 调用2种方式,这里通过Kubernetes API调用演示:
- # export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- # TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
- # curl -X POST https://192.168.137.159:6443/apis/authentication.k8s.io/v1/tokenreviews --header "Authorization: Bearer $TOKEN" --header "Content-Type: application/json" --data '{
- "apiVersion": "authentication.k8s.io/v1",
- "kind": "Tok> enReview",
- "spec": {
- "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImpyaFRNMDRFR0h5a2JpSUY2Vk5jM2lZYnRYY2Fwcl9yTmhDV04tTkdzdnM> ifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQxMjY4NDEzLCJpYXQiOjE3NDE> yNjQ4MTMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pb> yI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmF> tZSI6InptYy1zZXJ2aWNlYWNjb3VudCIsInVpZCI6ImJhZDE1ODExL> WMyMzktNGEzYy1hMTkzLWI3ZWViYWRmY2YxZSJ9fSwibmJmIjoxNzQx> MjY0ODEzLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp6bWMtc2VydmljZWFjY291bnQifQ.u53WwYrQILWQEIkKo06J6eIBB1Tw5oqEdCAMuRsx7XBjPZZM79WcVi-cGcRmzIAX6Hqdqqg6IMVf9xWzLYx1yfO7sad183Wbq_puJJJDH5o2C6mdUEcfthAD7EKmhgF35JFCYSnM0d7d0-8xRVyelNALR-Ex7yr91EL1e5OUuu9hx7fbhL91xeIxwTzB-5dNPt16km8Z9pdt4HzG3EC_zWeBdHIwEK5DRc1fvPenwDAbRFNQGMNAXQrLjPNJjGQboBC6M70fXwOxDa8l-9oNDIfWlx5bBNqCzUYaT3gx4G5tsRd99UmCcVN8EVlw_7h119GiYJlIPgjx1nqT2q28vg"
- }
- }'
- > > {
- "kind": "TokenReview",
- "apiVersion": "authentication.k8s.io/v1",
- "metadata": {
- "creationTimestamp": null,
- "managedFields": [
- {
- "manager": "curl",
- "operation": "Update",
- "apiVersion": "authentication.k8s.io/v1",
- "time": "2025-03-06T13:06:59Z",
- "fieldsType": "FieldsV1",
- "fieldsV1": {
- "f:spec": {
- "f:token": {}
- }
- }
- }
- ]
- },
- "spec": {
- "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImpyaFRNMDRFR0h5a2JpSUY2Vk5jM2lZYnRYY2Fwcl9yTmhDV04tTkdzdnMifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzQxMjY4NDEzLCJpYXQiOjE3NDEyNjQ4MTMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6InptYy1zZXJ2aWNlYWNjb3VudCIsInVpZCI6ImJhZDE1ODExLWMyMzktNGEzYy1hMTkzLWI3ZWViYWRmY2YxZSJ9fSwibmJmIjoxNzQxMjY0ODEzLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp6bWMtc2VydmljZWFjY291bnQifQ.u53WwYrQILWQEIkKo06J6eIBB1Tw5oqEdCAMuRsx7XBjPZZM79WcVi-cGcRmzIAX6Hqdqqg6IMVf9xWzLYx1yfO7sad183Wbq_puJJJDH5o2C6mdUEcfthAD7EKmhgF35JFCYSnM0d7d0-8xRVyelNALR-Ex7yr91EL1e5OUuu9hx7fbhL91xeIxwTzB-5dNPt16km8Z9pdt4HzG3EC_zWeBdHIwEK5DRc1fvPenwDAbRFNQGMNAXQrLjPNJjGQboBC6M70fXwOxDa8l-9oNDIfWlx5bBNqCzUYaT3gx4G5tsRd99UmCcVN8EVlw_7h119GiYJlIPgjx1nqT2q28vg"
- },
- "status": { //验证结果通过
status
字段返回 - "authenticated": true, #令牌是否有效
- "user": {
- "username": "system:serviceaccount:default:zmc-serviceaccount", #关联的用户名
- "uid": "bad15811-c239-4a3c-a193-b7eebadfcf1e", #用户唯一标识
- "groups": [
- "system:serviceaccounts",
- "system:serviceaccounts:default",
- "system:authenticated"
- ]
- },
- "audiences": [ #令牌的受众
- "https://kubernetes.default.svc.cluster.local"
- ]
- }
- }
关键响应字段:
- status.authenticated:true 表示令牌有效,false 表示无效。
- status.user:令牌关联的用户信息(遵循 Kubernetes 用户模型)。
- status.audiences:令牌实际生效的受众列表。
- status.error:如果验证失败,返回错误原因(如 Token expired)。
注意 1:确保调用Kube-APIServer服务的客户端拥有创建TokenReview资源对象的权限。
- apiVersion: rbac.authorization.k8s.io/v1
- kind: ClusterRole
- metadata:
- name: tokenreview-creator
- rules:
- - apiGroups: ["authentication.k8s.io"]
- resources: ["tokenreviews"]
- verbs: ["create"]
注意 2: 客户端获创建 TokenReview 权限,便能调用 Kube-APIServer,对令牌合法性进行验证,可以帮助鉴定Token合法性。
5、 应用场景
-
ServiceAccount Token 验证:当 Pod 使用 ServiceAccount 访问 API Server 时,API Server 会自动验证其 Token 的有效性。
-
外部身份提供者集成:与 OpenID Connect (OIDC)、Webhook Token Authentication 等外部认证系统集成时,可通过TokenReview验证外部令牌。
-
自定义身份验证逻辑:开发自定义控制器或服务时,可能需要验证客户端提供的令牌是否合法。
6、总结
通过TokenReview,Kubernetes 提供了一种标准化的方式验证令牌并获取身份信息,是实现安全认证的关键机制之一。
参考文档:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/
参考文档:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-review-v1/