Kubernetes v1.18 [稳定]引导令牌(Bootstrap Tokens)是一种简单的持有者令牌(bearer token),旨在创建新集群或将新节点加入现有集群时使用。它的构建初衷是为了支持 kubeadm,但也可以用于其他希望在不使用 kubeadm 的情况下启动集群的用户场景。它还被设计为通过 RBAC 策略与 kubelet TLS 引导 系统配合使用。
引导令牌定义在 kube-system 命名空间内的一种特定类型(bootstrap.kubernetes.io/token)的 Secret 中。这些 Secret 由 API 服务器中的引导身份验证器(Bootstrap Authenticator)读取。过期的令牌会由控制器管理器(Controller Manager)中的 TokenCleaner 控制器删除。令牌还通过 BootstrapSigner 控制器用于为“发现(discovery)”过程中使用的特定 ConfigMap 创建签名。
引导令牌的格式为 abcdef.0123456789abcdef。更正式地说,它们必须匹配正则表达式 [a-z0-9]{6}\.[a-z0-9]{16}。
令牌的第一部分是“令牌 ID”,被视为公开信息。它在引用令牌时使用,而不会泄露用于身份验证的密钥部分。第二部分是“令牌密钥(Token Secret)”,应仅与受信任方共享。
可以通过在 API 服务器上设置以下标志来启用引导令牌身份验证器:
--enable-bootstrap-token-auth
启用后,引导令牌可用作持有者令牌凭据,以对 API 服务器的请求进行身份验证。
Authorization: Bearer 07401b.f395accd246ae52d
令牌的身份验证用户名为 system:bootstrap:<token id>,并且属于 system:bootstrappers 组。可以在令牌的 Secret 中指定其他组。
通过在控制器管理器上启用 tokencleaner 控制器,可以自动删除过期令牌。
--controllers=*,tokencleaner
每个有效的令牌都由 kube-system 命名空间中的一个 Secret 支持。你可以在此处找到完整的设计文档。
以下是该 Secret 的样子。
apiVersion: v1
kind: Secret
metadata:
# Name MUST be of form "bootstrap-token-<token id>"
name: bootstrap-token-07401b
namespace: kube-system
# Type MUST be 'bootstrap.kubernetes.io/token'
type: bootstrap.kubernetes.io/token
stringData:
# Human readable description. Optional.
description: "The default bootstrap token generated by 'kubeadm init'."
# Token ID and secret. Required.
token-id: 07401b
token-secret: f395accd246ae52d
# Expiration. Optional.
expiration: 2017-03-10T03:22:11Z
# Allowed usages.
usage-bootstrap-authentication: "true"
usage-bootstrap-signing: "true"
# Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
Secret 的类型必须为 bootstrap.kubernetes.io/token,名称必须为 bootstrap-token-<token id>。它还必须存在于 kube-system 命名空间中。
usage-bootstrap-* 成员指示此 Secret 的用途。必须将其值设置为 true 才能启用。
usage-bootstrap-authentication 表示该令牌可用作持有者令牌,用于向 API 服务器进行身份验证。usage-bootstrap-signing 表示该令牌可用于签署 cluster-info ConfigMap,如下所述。expiration 字段控制令牌的过期时间。过期令牌在用于身份验证时会被拒绝,并在 ConfigMap 签名过程中被忽略。过期值使用 RFC3339 编码为绝对 UTC 时间。启用 tokencleaner 控制器可自动删除过期令牌。
你可以使用 kubeadm 工具管理正在运行的集群上的令牌。详情请参阅 kubeadm 令牌文档。
除了身份验证外,令牌还可以用于签署 ConfigMap。这在集群引导过程的早期阶段(客户端尚不信任 API 服务器时)非常有用。签名的 ConfigMap 可以通过共享令牌进行身份验证。
通过在控制器管理器上启用 bootstrapsigner 控制器来启用 ConfigMap 签名。
--controllers=*,bootstrapsigner
被签名的 ConfigMap 是 kube-public 命名空间中的 cluster-info。典型的流程是:客户端在未通过身份验证且忽略 TLS 错误的情况下读取此 ConfigMap。然后,它通过查看嵌入在 ConfigMap 中的签名来验证 ConfigMap 的有效负载。
ConfigMap 可能如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-info
namespace: kube-public
data:
jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
kubeconfig: |
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <really long certificate data>
server: https://10.138.0.2:6443
name: ""
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []
ConfigMap 的 kubeconfig 成员是一个仅填写了集群信息的配置文件。此处传递的关键信息是 certificate-authority-data。这在未来可能会进行扩展。
签名是使用“分离(detached)”模式的 JWS 签名。要验证签名,用户应根据 JWS 规则对 kubeconfig 有效负载进行编码(base64 编码,同时丢弃任何尾随的 =)。然后,该编码的有效负载通过插入到两个点之间来形成完整的 JWS。你可以使用完整的令牌(例如 07401b.f395accd246ae52d)作为共享密钥,通过 HS256 方案(HMAC-SHA256)验证 JWS。用户必须验证是否使用了 HS256。
有关更多信息,请查阅 kubeadm 实现细节 部分。