使用 Bootstrap Token 进行身份验证

功能状态: 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

引导令牌 Secret 格式

每个有效的令牌都由 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 工具管理正在运行的集群上的令牌。详情请参阅 kubeadm 令牌文档

ConfigMap 签名

除了身份验证外,令牌还可以用于签署 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。

警告

任何持有引导令牌的人都可以为该令牌创建有效的签名。使用 ConfigMap 签名时,不建议与多个客户端共享同一个令牌,因为被攻破的客户端可能会对依赖该签名来引导 TLS 信任的其他客户端实施中间人攻击。

有关更多信息,请查阅 kubeadm 实现细节 部分。


最后修改于 2024年9月11日 上午 11:29 PST:在 bootstrap-tokens.md 中添加 RFC3339 的超链接 (2e7c1d4935)