--- title: 管理服务账号 content_type: concept weight: 50 --- **ServiceAccount** 为 Pod 中运行的进程提供了一个身份。 Pod 内的进程可以使用其关联服务账号的身份,向集群的 API 服务器进行身份认证。 有关服务账号的介绍, 请参阅[配置服务账号](/zh-cn/docs/tasks/configure-pod-container/configure-service-account/)。 本任务指南阐述有关 ServiceAccount 的几个概念。 本指南还讲解如何获取或撤销代表 ServiceAccount 的令牌, 以及如何将 ServiceAccount 的有效期与某个 API 对象的生命期绑定(可选)。 ## {{% heading "prerequisites" %}} {{< include "task-tutorial-prereqs.md" >}} 为了能够准确地跟随这些步骤,确保你有一个名为 `examplens` 的名字空间。 如果你没有,运行以下命令创建一个名字空间: ```shell kubectl create namespace examplens ``` ## 用户账号与服务账号 {#user-accounts-versus-service-accounts} Kubernetes 区分用户账号和服务账号的概念,主要基于以下原因: - 用户账号是针对人而言的。而服务账号是针对运行在 Pod 中的应用进程而言的, 在 Kubernetes 中这些进程运行在容器中,而容器是 Pod 的一部分。 - 用户账号是全局性的。其名称在某集群中的所有名字空间中必须是唯一的。 无论你查看哪个名字空间,代表用户的特定用户名都代表着同一个用户。 在 Kubernetes 中,服务账号是名字空间作用域的。 两个不同的名字空间可以包含具有相同名称的 ServiceAccount。 - 通常情况下,集群的用户账号可能会从企业数据库进行同步, 创建新用户需要特殊权限,并且涉及到复杂的业务流程。 服务账号创建有意做得更轻量,允许集群用户为了具体的任务按需创建服务账号。 将 ServiceAccount 的创建与新用户注册的步骤分离开来, 使工作负载更易于遵从权限最小化原则。 - 对人员和服务账号审计所考虑的因素可能不同;这种分离更容易区分不同之处。 - 针对复杂系统的配置包可能包含系统组件相关的各种服务账号的定义。 因为服务账号的创建约束不多并且有名字空间域的名称,所以这种配置通常是轻量的。 ## 绑定的服务账号令牌 {#bound-service-account-tokens} ServiceAccount 令牌可以被绑定到 kube-apiserver 中存在的 API 对象。 这可用于将令牌的有效性与另一个 API 对象的存在与否关联起来。 支持的对象类型如下: * Pod(用于投射卷的挂载,见下文) * Secret(可用于允许通过删除 Secret 来撤销令牌) * 节点(可以在其节点被删除时自动撤销令牌;创建新的与节点绑定的令牌在 v1.33+ 中是 GA 状态) 当将令牌绑定到某对象时,该对象的 `metadata.name` 和 `metadata.uid` 将作为额外的“私有声明”存储在所发布的 JWT 中。 当将被绑定的令牌提供给 kube-apiserver 时,服务帐户身份认证组件将提取并验证这些声明。 如果所引用的对象或 ServiceAccount 正处于删除中(例如,由于 finalizer 的原因), 那么在 `.metadata.deletionTimestamp` 时间戳之后的 60 秒(或更长时间)后的某一时刻, 使用该令牌进行身份认证将会失败。 如果所引用的对象不再存在(或其 `metadata.uid` 不匹配),则请求将无法通过认证。 ### Pod 绑定令牌中的附加元数据 {#additional-metadata-in-pod-bound-tokens} {{< feature-state feature_gate_name="ServiceAccountTokenPodNodeInfo" >}} 当服务帐户令牌被绑定到某 Pod 对象时,一些额外的元数据也会被嵌入到令牌中, 包括所绑定 Pod 的 `spec.nodeName` 字段的值以及该节点的 uid(如果可用)。 当使用令牌进行身份认证时,kube-apiserver **不会**检查此节点信息的合法性。 由于节点信息被包含在令牌内,所以集成商在检查 JWT 时不必获取 Pod 或 Node API 对象来检查所关联的 Node 名称和 uid。 ### 查验和检视私有声明 {#verifying-and-inspecting-private-claims} TokenReview API 可用于校验并从令牌中提取私有声明: 1. 首先,假设你有一个名为 `test-pod` 的 Pod 和一个名为 `my-sa` 的服务帐户。 2. 创建绑定到此 Pod 的令牌: ```shell kubectl create token my-sa --bound-object-kind="Pod" --bound-object-name="test-pod" ``` 3. 将此令牌复制到名为 `tokenreview.yaml` 的新文件中: ```yaml apiVersion: authentication.k8s.io/v1 kind: TokenReview spec: token: <第 2 步获取的令牌> ``` 4. 将此资源提交给 API 服务器进行审核: ```shell # 使用 '-o yaml' 检视命令输出 kubectl create -o yaml -f tokenreview.yaml ``` 你应该看到如下所示的输出: ```yaml apiVersion: authentication.k8s.io/v1 kind: TokenReview metadata: creationTimestamp: null spec: token: status: audiences: - https://kubernetes.default.svc.cluster.local authenticated: true user: extra: authentication.kubernetes.io/credential-id: - JTI=7ee52be0-9045-4653-aa5e-0da57b8dccdc authentication.kubernetes.io/node-name: - kind-control-plane authentication.kubernetes.io/node-uid: - 497e9d9a-47aa-4930-b0f6-9f2fb574c8c6 authentication.kubernetes.io/pod-name: - test-pod authentication.kubernetes.io/pod-uid: - e87dbbd6-3d7e-45db-aafb-72b24627dff5 groups: - system:serviceaccounts - system:serviceaccounts:default - system:authenticated uid: f8b4161b-2e2b-11e9-86b7-2afc33b31a7e username: system:serviceaccount:default:my-sa ``` {{< note >}} 尽管你使用了 `kubectl create -f` 来创建此资源,并与 Kubernetes 中的其他资源类型类似的方式定义它,但 TokenReview 是一种特殊类别, kube-apiserver 实际上并不将 TokenReview 对象持久保存到 etcd 中。 因此 `kubectl get tokenreview` 不是一个有效的命令。 {{< /note >}} #### 服务账号私有声明的模式 目前在 JWT 令牌中特定于 Kubernetes 的声明模式尚未文档化,但相关代码段可以在 Kubernetes 代码库的 [serviceaccount 包](https://github.com/kubernetes/kubernetes/blob/d8919343526597e0788a1efe133c70d9a0c07f69/pkg/serviceaccount/claims.go#L56-L68)中找到。 你可以使用标准的 JWT 解码工具检查 JWT。 下面是一个关于 `my-serviceaccount` 服务账号的 JWT 示例, 该服务账号绑定到了一个被调度到 `my-node` 节点、位于 `my-namespace` 命名空间中且名为 `my-pod` 的 Pod 对象: ```json { "aud": [ "https://my-audience.example.com" ], "exp": 1729605240, "iat": 1729601640, "iss": "https://my-cluster.example.com", "jti": "aed34954-b33a-4142-b1ec-389d6bbb4936", "kubernetes.io": { "namespace": "my-namespace", "node": { "name": "my-node", "uid": "646e7c5e-32d6-4d42-9dbd-e504e6cbe6b1" }, "pod": { "name": "my-pod", "uid": "5e0bd49b-f040-43b0-99b7-22765a53f7f3" }, "serviceaccount": { "name": "my-serviceaccount", "uid": "14ee3fa4-a7e2-420f-9f9a-dbc4507c3798" } }, "nbf": 1729601640, "sub": "system:serviceaccount:my-namespace:my-serviceaccount" } ``` {{< note >}} 此 JWT 中的 `aud` 和 `iss` 字段可能因你的配置而在不同的 Kubernetes 集群之间有所差异。 同时存在 `pod` 和 `node` 声明意味着此令牌被绑定到了 **Pod** 对象。 在验证 Pod 绑定的服务账号令牌时,API 服务器**不**验证所引用的 Node 对象是否存在。 {{< /note >}} 在 Kubernetes 外部运行且想要对 JWT 进行离线校验的服务可以使用此模式, 结合以 API 服务器的 OpenID Discovery 信息所配置的合规 JWT 校验器, 可以在不需要使用 TokenReview API 的情况下验证呈现的 JWT。 以这种方式验证 JWT 的服务**不验证**嵌入在 JWT 令牌中的声明是否当前正使用且仍然有效。 这意味着如果令牌被绑定到某个对象,且该对象不再存在,此令牌仍将被视为有效(直到配置的令牌过期)。 需要确保令牌的绑定声明仍然有效的客户端**必须**使用 TokenReview API 将令牌呈现给 `kube-apiserver`, 以便其验证并扩展嵌入的声明,具体步骤类似于上文所述的[验证和检查私有声明](#verifying-and-inspecting-private-claims), 但会使用[支持的客户端库](/zh-cn/docs/reference/using-api/client-libraries/)。 有关 JWT 及其结构的细节,参见 [JSON Web Token RFC](https://datatracker.ietf.org/doc/html/rfc7519)。 ## 绑定的服务账号令牌卷机制 {#bound-service-account-token-volume} {{< feature-state feature_gate_name="BoundServiceAccountTokenVolume" >}} 默认情况下,Kubernetes 控制平面(特别是 [ServiceAccount 准入控制器](#serviceaccount-admission-controller)) 添加一个[投射卷](/zh-cn/docs/concepts/storage/projected-volumes/)到 Pod, 此卷包括了访问 Kubernetes API 的令牌。 以下示例演示如何查找已启动的 Pod: ```yaml ... - name: kube-api-access-<随机后缀> projected: sources: - serviceAccountToken: path: token # 必须与应用所预期的路径匹配 - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace ``` 该清单片段定义了由三个数据源组成的投射卷。在当前场景中,每个数据源也代表该卷内的一条独立路径。这三个数据源是: 1. `serviceAccountToken` 数据源,包含 kubelet 从 kube-apiserver 获取的令牌。 kubelet 使用 TokenRequest API 获取有时间限制的令牌。为 TokenRequest 服务的这个令牌会在 Pod 被删除或定义的生命周期(默认为 1 小时)结束之后过期。该令牌绑定到特定的 Pod, 并将其 audience(受众)设置为与 `kube-apiserver` 的 audience 相匹配。 这种机制取代了之前基于 Secret 添加卷的机制,之前 Secret 代表了针对 Pod 的 ServiceAccount 但不会过期。 1. `configMap` 数据源。ConfigMap 包含一组证书颁发机构数据。 Pod 可以使用这些证书来确保自己连接到集群的 kube-apiserver(而不是连接到中间件或意外配置错误的对等点上)。 1. `downwardAPI` 数据源,用于查找包含 Pod 的名字空间的名称, 并使该名称信息可用于在 Pod 内运行的应用程序代码。 Pod 内挂载这个特定卷的所有容器都可以访问上述信息。 {{< note >}} 没有特定的机制可以使通过 TokenRequest 签发的令牌无效。 如果你不再信任为某个 Pod 绑定的服务账号令牌, 你可以删除该 Pod。删除 Pod 将使其绑定的服务账号令牌过期。 {{< /note >}} ## 手动管理 ServiceAccount 的 Secret {#manual-secret-management-for-serviceaccounts} v1.22 之前的 Kubernetes 版本会自动创建凭据访问 Kubernetes API。 这种更老的机制基于先创建令牌 Secret,然后将其挂载到正运行的 Pod 中。 在包括 Kubernetes v{{< skew currentVersion >}} 在内最近的几个版本中,使用 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) API [直接获得](#bound-service-account-token-volume) API 凭据, 并使用投射卷挂载到 Pod 中。使用这种方法获得的令牌具有绑定的生命周期, 当挂载的 Pod 被删除时这些令牌将自动失效。 你仍然可以[手动创建](/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#manually-create-an-api-token-for-a-serviceaccount) Secret 来保存服务账号令牌;例如在你需要一个永不过期的令牌的时候。 一旦你手动创建一个 Secret 并将其关联到 ServiceAccount, Kubernetes 控制平面就会自动将令牌填充到该 Secret 中。 {{< note >}} 尽管存在手动创建长久 ServiceAccount 令牌的机制,但还是推荐使用 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) 获得短期的 API 访问令牌。 {{< /note >}} ## 清理自动生成的传统 ServiceAccount 令牌 {#auto-generated-legacy-serviceaccount-token-clean-up} 在 1.24 版本之前,Kubernetes 自动为 ServiceAccount 生成基于 Secret 的令牌。 为了区分自动生成的令牌和手动创建的令牌,Kubernetes 会检查 ServiceAccount 的 Secret 字段是否有引用。如果该 Secret 被 `secrets` 字段引用, 它被视为自动生成的传统令牌。否则,它被视为手动创建的传统令牌。例如: ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: build-robot namespace: default secrets: - name: build-robot-secret # 对于手动生成的令牌通常不会存在此字段 ``` 从 1.29 版本开始,如果传统 ServiceAccount 令牌在一定时间段(默认设置为一年)内未被使用,则会被标记为无效。 在定义的时间段(同样默认为一年)持续未被使用的令牌将由控制平面自动清除。 如果用户使用一个无效的自动生成的令牌,令牌验证器将执行以下操作: 1. 为键值对 `authentication.k8s.io/legacy-token-invalidated: /` 添加审计注解, 1. `invalid_legacy_auto_token_uses_total` 指标计数加一, 1. 更新 Secret 标签 `kubernetes.io/legacy-token-last-used` 为新日期, 1. 返回一个提示令牌已经无效的报错。 当收到这个校验报错时,用户可以通过移除 `kubernetes.io/legacy-token-invalid-since` 标签更新 Secret,以临时允许使用此令牌。 以下是一个自动生成的传统令牌示例,它被标记了 `kubernetes.io/legacy-token-last-used` 和 `kubernetes.io/legacy-token-invalid-since` 标签: ```yaml apiVersion: v1 kind: Secret metadata: name: build-robot-secret namespace: default labels: kubernetes.io/legacy-token-last-used: 2022-10-24 kubernetes.io/legacy-token-invalid-since: 2023-10-25 annotations: kubernetes.io/service-account.name: build-robot type: kubernetes.io/service-account-token ``` ## 控制平面细节 {#control-plane-details} ### ServiceAccount 控制器 {#serviceaccount-controller} ServiceAccount 控制器管理名字空间内的 ServiceAccount, 并确保每个活跃的名字空间中都存在名为 `default` 的 ServiceAccount。 ### 令牌控制器 {#token-controller} 服务账号令牌控制器作为 `kube-controller-manager` 的一部分运行,以异步的形式工作。 其职责包括: - 监测 ServiceAccount 的删除并删除所有相应的服务账号令牌 Secret。 - 监测服务账号令牌 Secret 的添加,保证相应的 ServiceAccount 存在, 如有需要,向 Secret 中添加令牌。 - 监测服务账号令牌 Secret 的删除,如有需要,从相应的 ServiceAccount 中移除引用。 你必须通过 `--service-account-private-key-file` 标志为 `kube-controller-manager`的令牌控制器传入一个服务账号私钥文件。 该私钥用于为所生成的服务账号令牌签名。同样地,你需要通过 `--service-account-key-file` 标志将对应的公钥通知给 kube-apiserver。公钥用于在身份认证过程中校验令牌。 {{< feature-state feature_gate_name="ExternalServiceAccountTokenSigner" >}} 设置 `--service-account-private-key-file` 和 `--service-account-key-file` 标志的替代方案是配置一个外部 JWT 签名程序, 用于[外部服务账户令牌签名和密钥管理](#external-serviceaccount-token-signing-and-key-management)。 请注意,这些设置是互斥的,不能同时配置。 ### ServiceAccount 准入控制器 {#serviceaccount-admission-controller} 对 Pod 的改动通过一个被称为[准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/)的插件来实现。 它是 API 服务器的一部分。当 Pod 被创建时,该准入控制器会同步地修改 Pod。 如果该插件处于激活状态(在大多数发行版中都是默认激活的),当 Pod 被创建时它会进行以下操作: 1. 如果该 Pod 没有设置 `.spec.serviceAccountName`, 准入控制器为新来的 Pod 将 ServiceAccount 的名称设为 `default`。 2. 准入控制器保证新来的 Pod 所引用的 ServiceAccount 确实存在。 如果没有 ServiceAccount 具有匹配的名称,则准入控制器拒绝新来的 Pod。 这个检查甚至适用于 `default` ServiceAccount。 3. 如果服务账号的 `automountServiceAccountToken` 字段或 Pod 的 `automountServiceAccountToken` 字段都未显式设置为 `false`: - 准入控制器变更新来的 Pod,添加一个包含 API 访问令牌的额外{{< glossary_tooltip text="卷" term_id="volume" >}}。 - 准入控制器将 `volumeMount` 添加到 Pod 中的每个容器, 忽略已为 `/var/run/secrets/kubernetes.io/serviceaccount` 路径定义的卷挂载的所有容器。 对于 Linux 容器,此卷挂载在 `/var/run/secrets/kubernetes.io/serviceaccount`; 在 Windows 节点上,此卷挂载在等价的路径上。 4. 如果新来 Pod 的规约不包含任何 `imagePullSecrets`,则准入控制器添加 `imagePullSecrets`, 并从 `ServiceAccount` 进行复制。 ### 传统 ServiceAccount 令牌追踪控制器 {#legacy-serviceaccount-token-tracking-controller} {{< feature-state feature_gate_name="LegacyServiceAccountTokenTracking" >}} 此控制器在 `kube-system` 命名空间中生成名为 `kube-apiserver-legacy-service-account-token-tracking` 的 ConfigMap。 这个 ConfigMap 记录了系统开始监视传统服务账号令牌的时间戳。 ### 传统 ServiceAccount 令牌清理器 {#legacy-serviceaccount-token-cleaner} {{< feature-state feature_gate_name="LegacyServiceAccountTokenCleanUp" >}} 传统 ServiceAccount 令牌清理器作为 `kube-controller-manager` 的一部分运行, 每 24 小时检查一次,查看是否有任何自动生成的传统 ServiceAccount 令牌在**特定时间段**内未被使用。如果有的话,清理器会将这些令牌标记为无效。 清理器的工作方式是首先检查控制平面创建的 ConfigMap(前提是启用了 `LegacyServiceAccountTokenTracking`)。如果当前时间是 ConfigMap 所包含日期之后的**特定时间段**,清理器会遍历集群中的 Secret 列表, 并评估每个类型为 `kubernetes.io/service-account-token` 的 Secret。 如果一个 Secret 满足以下所有条件,清理器会将其标记为无效: - Secret 是自动生成的,意味着它被 ServiceAccount 双向引用。 - Secret 当前没有被任何 Pod 挂载。 - Secret 自从创建或上次使用以来的**特定时间段**未被使用过。 清理器通过向 Secret 添加名为 `kubernetes.io/legacy-token-invalid-since` 的标签, 并将此值设置为当前日期,来标记 Secret 为无效。 如果一个无效的 Secret 在**特定时间段**内未被使用,清理器将会删除它。 {{< note >}} 上述所有的**特定时间段**都默认为一年。集群管理员可以通过 `kube-controller-manager` 组件的 `--legacy-service-account-token-clean-up-period` 命令行参数来配置此值。 {{< /note >}} ### TokenRequest API {{< feature-state for_k8s_version="v1.22" state="stable" >}} 你使用 ServiceAccount 的 [TokenRequest](/zh-cn/docs/reference/kubernetes-api/authentication-resources/token-request-v1/) 子资源为该 ServiceAccount 获取有时间限制的令牌。 你不需要调用它来获取在容器中使用的 API 令牌, 因为 kubelet 使用**投射卷**对此进行了设置。 如果你想要从 `kubectl` 使用 TokenRequest API, 请参阅[为 ServiceAccount 手动创建 API 令牌](/zh-cn/docs/tasks/configure-pod-container/configure-service-account/#manually-create-an-api-token-for-a-serviceaccount)。 Kubernetes 控制平面(特别是 ServiceAccount 准入控制器)向 Pod 添加了一个投射卷, kubelet 确保该卷包含允许容器作为正确 ServiceAccount 进行身份认证的令牌。 (这种机制取代了之前基于 Secret 添加卷的机制,之前 Secret 代表了 Pod 所用的 ServiceAccount 但不会过期。) 以下示例演示如何查找已启动的 Pod: ```yaml ... - name: kube-api-access- projected: defaultMode: 420 # 这个十进制数等同于八进制 0644 sources: - serviceAccountToken: expirationSeconds: 3607 path: token - configMap: items: - key: ca.crt path: ca.crt name: kube-root-ca.crt - downwardAPI: items: - fieldRef: apiVersion: v1 fieldPath: metadata.namespace path: namespace ``` 该清单片段定义了由三个数据源信息组成的投射卷。 1. `serviceAccountToken` 数据源,包含 kubelet 从 kube-apiserver 获取的令牌。 kubelet 使用 TokenRequest API 获取有时间限制的令牌。为 TokenRequest 服务的这个令牌会在 Pod 被删除或定义的生命周期(默认为 1 小时)结束之后过期。在令牌过期之前,kubelet 还会刷新该令牌。 该令牌绑定到特定的 Pod,并将其 audience(受众)设置为与 `kube-apiserver` 的 audience 相匹配。 1. `configMap` 数据源。ConfigMap 包含一组证书颁发机构数据。 Pod 可以使用这些证书来确保自己连接到集群的 kube-apiserver(而不是连接到中间件或意外配置错误的对等点上)。 1. `downwardAPI` 数据源。这个 `downwardAPI` 卷获得包含 Pod 的名字空间的名称, 并使该名称信息可用于在 Pod 内运行的应用程序代码。 挂载此卷的 Pod 内的所有容器均可以访问上述信息。 ## 创建额外的 API 令牌 {#create-token} {{< caution >}} 只有[令牌请求](#tokenrequest-api)机制不合适,才需要创建长久的 API 令牌。 令牌请求机制提供有时间限制的令牌;因为随着这些令牌过期,它们对信息安全方面的风险也会降低。 {{< /caution >}} 要为 ServiceAccount 创建一个不过期、持久化的 API 令牌, 请创建一个类型为 `kubernetes.io/service-account-token` 的 Secret, 附带引用 ServiceAccount 的注解。控制平面随后生成一个长久的令牌, 并使用生成的令牌数据更新该 Secret。 以下是此类 Secret 的示例清单: {{% code_sample file="secret/serviceaccount/mysecretname.yaml" %}} 若要基于此示例创建 Secret,运行以下命令: ```shell kubectl -n examplens create -f https://k8s.io/examples/secret/serviceaccount/mysecretname.yaml ``` 若要查看该 Secret 的详细信息,运行以下命令: ```shell kubectl -n examplens describe secret mysecretname ``` 输出类似于: ``` Name: mysecretname Namespace: examplens Labels: Annotations: kubernetes.io/service-account.name=myserviceaccount kubernetes.io/service-account.uid=8a85c4c4-8483-11e9-bc42-526af7764f64 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1362 bytes namespace: 9 bytes token: ... ``` 如果你在 `examplens` 名字空间中启动一个新的 Pod,它可以使用你刚刚创建的 `myserviceaccount` service-account-token Secret。 {{< caution >}} 不要在 ServiceAccount 的 `secrets` 字段中引用手动创建的 Secret。 否则,如果这些手动创建的 Secret 长时间未被使用将会被清理掉。 请参考[清理自动生成的传统 ServiceAccount 令牌](#auto-generated-legacy-serviceaccount-token-clean-up)。 {{< /caution >}} ## 删除/废止 ServiceAccount 令牌 {#delete-token} 如果你知道 Secret 的名称且该 Secret 包含要移除的令牌: ```shell kubectl delete secret name-of-secret ``` 否则,先找到 ServiceAccount 所用的 Secret。 ```shell # 此处假设你已有一个名为 'examplens' 的名字空间 kubectl -n examplens get serviceaccount/example-automated-thing -o yaml ``` 输出类似于: ```yaml apiVersion: v1 kind: ServiceAccount metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"example-automated-thing","namespace":"examplens"}} creationTimestamp: "2019-07-21T07:07:07Z" name: example-automated-thing namespace: examplens resourceVersion: "777" selfLink: /api/v1/namespaces/examplens/serviceaccounts/example-automated-thing uid: f23fd170-66f2-4697-b049-e1e266b7f835 secrets: - name: example-automated-thing-token-zyxwv ``` 随后删除你现在知道名称的 Secret: ```shell kubectl -n examplens delete secret/example-automated-thing-token-zyxwv ``` ## 外部 ServiceAccount 令牌签名和密钥管理 {#external-serviceaccount-token-signing-and-key-management} {{< feature-state feature_gate_name="ExternalServiceAccountTokenSigner" >}} kube-apiserver 可以被配置为使用外部签名程序进行令牌签名和令牌验证密钥管理。 此特性允许各种 Kubernetes 发行版集成自己选择的密钥管理解决方案(例如 HSM、云上 KMS)来进行服务账户凭证签名和验证。 要配置 kube-apiserver 使用 external-jwt-signer,将 `--service-account-signing-endpoint` 标志设置为文件系统上 Unix 域套接字 (UDS) 所在的位置,或者以 @ 符号开头并在抽象套接字命名空间中命名 UDS。 在配置的 UDS 上,需要有一个实现 [ExternalJWTSigner](https://github.com/kubernetes/kubernetes/blob/release-1.32/staging/src/k8s.io/externaljwt/apis/v1alpha1/api.proto) 的 RPC 服务器。external-jwt-signer 必须处于健康状态,并准备好为 kube-apiserver 启动提供支持的服务账户密钥。 有关 ExternalJWTSigner 的细节,查阅 [KEP-740](https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/740-service-account-external-signing)。 {{< note >}} kube-apiserver 的 `--service-account-key-file` 和 `--service-account-signing-key-file` 标志将继续被用于从文件中读取,除非设置了 `--service-account-signing-endpoint`; 它们在支持 JWT 签名和身份验证方面是互斥的。 {{< /note >}} ## 清理 {#clean-up} 如果创建了一个 `examplens` 名字空间进行试验,你可以移除它: ```shell kubectl delete namespace examplens ``` ## {{% heading "whatsnext" %}} - 查阅有关[投射卷](/zh-cn/docs/concepts/storage/projected-volumes/)的更多细节。