服务账号
此页面介绍 Kubernetes 中的 ServiceAccount 对象,提供有关服务帐户的工作原理、用例、限制、替代方案以及指向其他指导资源的链接的信息。
什么是服务帐户?
服务帐户是一种非人工帐户,在 Kubernetes 中,它在 Kubernetes 集群中提供一个独特的身份。应用程序 Pod、系统组件以及集群内部和外部的实体可以使用特定的 ServiceAccount 的凭据来识别为该 ServiceAccount。此身份在各种情况下都很有用,包括向 API 服务器进行身份验证或实施基于身份的安全策略。
服务帐户作为 API 服务器中的 ServiceAccount 对象存在。服务帐户具有以下属性
命名空间范围:每个服务帐户都绑定到 Kubernetes 命名空间。每个命名空间在创建时都会获得一个
defaultServiceAccount。轻量级:服务帐户存在于集群中,并在 Kubernetes API 中定义。您可以快速创建服务帐户以启用特定任务。
可移植:复杂容器化工作负载的配置包可能包含系统组件的服务帐户定义。服务帐户的轻量级特性和命名空间身份使配置具有可移植性。
服务帐户与用户帐户不同,用户帐户是在集群中经过身份验证的人工用户。默认情况下,用户帐户不存在于 Kubernetes API 服务器中;相反,API 服务器将用户身份视为不透明数据。您可以使用多种方法进行用户帐户身份验证。某些 Kubernetes 发行版可能会添加自定义扩展 API,以在 API 服务器中表示用户帐户。
| 描述 | ServiceAccount | 用户或组 |
|---|---|---|
| 位置 | Kubernetes API (ServiceAccount 对象) | 外部 |
| 访问控制 | Kubernetes RBAC 或其他 授权机制 | Kubernetes RBAC 或其他身份和访问管理机制 |
| 预期用途 | 工作负载、自动化 | 人员 |
默认服务帐户
创建集群时,Kubernetes 会自动为集群中的每个命名空间创建一个名为 default 的 ServiceAccount 对象。每个命名空间中的 default 服务帐户默认情况下没有权限,除非 Kubernetes 在启用基于角色的访问控制 (RBAC) 时授予所有经过身份验证的主体 默认 API 发现权限。如果您删除命名空间中的 default ServiceAccount 对象,控制平面会用一个新的 ServiceAccount 替换它。
如果您在命名空间中部署 Pod,并且没有 手动将 ServiceAccount 分配给 Pod,Kubernetes 会将该命名空间的 default ServiceAccount 分配给 Pod。
Kubernetes 服务帐户的用例
作为一般指导,您可以使用服务帐户在以下场景中提供身份
- 您的 Pod 需要与 Kubernetes API 服务器通信,例如在以下情况下
- 提供对存储在 Secret 中的敏感信息的只读访问权限。
- 授予 跨命名空间访问权限,例如允许
example命名空间中的 Pod 读取、列出和监视kube-node-lease命名空间中的 Lease 对象。
- 您的 Pod 需要与外部服务通信。例如,工作负载 Pod 需要商业云 API 的身份,并且商业提供商允许配置合适的信任关系。
- 使用
imagePullSecret使用身份验证来私有镜像仓库. - 外部服务需要与 Kubernetes API 服务器通信。例如,作为 CI/CD 管道的一部分进行身份验证。
- 您在集群中使用第三方安全软件,该软件依赖于不同 Pod 的 ServiceAccount 身份将这些 Pod 分组到不同的上下文中。
如何使用服务帐户
要使用 Kubernetes 服务帐户,请执行以下操作
使用 Kubernetes 客户端(如
kubectl)或定义该对象的清单创建 ServiceAccount 对象。使用授权机制(如 RBAC)向 ServiceAccount 对象授予权限。
在 Pod 创建期间将 ServiceAccount 对象分配给 Pod。
如果您正在使用外部服务的身份,检索 ServiceAccount 令牌并从该服务中使用它。
有关说明,请参阅 为 Pod 配置服务帐户。
授予服务帐户权限
您可以使用内置的 Kubernetes 基于角色的访问控制 (RBAC) 机制来授予每个服务帐户所需的最小权限。您创建一个角色,授予访问权限,然后将该角色绑定到您的 ServiceAccount。RBAC 允许您定义最小权限集,以便服务帐户权限遵循最小权限原则。使用该服务帐户的 Pod 不会获得超出正确运行所需的权限。
有关说明,请参阅 服务帐户权限。
使用服务帐户进行跨命名空间访问
您可以使用 RBAC 允许一个命名空间中的服务帐户对集群中另一个命名空间中的资源执行操作。例如,考虑您在 dev 命名空间中有一个服务帐户和 Pod,并且希望您的 Pod 看到在 maintenance 命名空间中运行的 Jobs。您可以创建一个 Role 对象,授予列出 Job 对象的权限。然后,您将在 maintenance 命名空间中创建一个 RoleBinding 对象,将 Role 绑定到 ServiceAccount 对象。现在,dev 命名空间中的 Pod 可以使用该服务帐户列出 maintenance 命名空间中的 Job 对象。
将服务帐户分配给 Pod
要将服务帐户分配给 Pod,您需要在 Pod 规范中设置 spec.serviceAccountName 字段。Kubernetes 随后会自动将该 ServiceAccount 的凭据提供给 Pod。在 v1.22 及更高版本中,Kubernetes 会使用 TokenRequest API 获取一个短时、自动轮换的令牌,并将其作为 投影卷挂载。
默认情况下,Kubernetes 为 Pod 提供分配 ServiceAccount 的凭据,无论该 ServiceAccount 是 default ServiceAccount 还是您指定的自定义 ServiceAccount。
要防止 Kubernetes 自动注入指定 ServiceAccount 或 default ServiceAccount 的凭据,请在 Pod 规范中将 automountServiceAccountToken 字段设置为 false。
在 1.22 之前的版本中,Kubernetes 会将一个长期、静态令牌作为 Secret 提供给 Pod。
手动检索服务帐户凭据
如果您需要在非标准位置挂载服务帐户的凭据,或者对于不是 API 服务器的受众,请使用以下方法之一
- TokenRequest API (推荐): 在您自己的应用程序代码中请求一个短期的服务帐户令牌。该令牌会自动过期并在到期时轮换。如果您有一个不了解 Kubernetes 的遗留应用程序,您可以使用同一个 Pod 中的 sidecar 容器来获取这些令牌并将其提供给应用程序工作负载。
- Token Volume Projection (也推荐): 在 Kubernetes v1.20 及更高版本中,使用 Pod 规范告诉 kubelet 将服务帐户令牌作为 projected volume 添加到 Pod 中。Projected 令牌会自动过期,并且 kubelet 会在令牌到期之前轮换令牌。
- Service Account Token Secrets (不推荐): 您可以将服务帐户令牌作为 Kubernetes Secrets 挂载到 Pod 中。这些令牌不会过期也不会轮换。在 v1.24 之前的版本中,每个服务帐户都会自动创建一个永久令牌。由于与静态、长期存在的凭据相关的风险,不再推荐使用此方法,尤其是在大规模情况下。 LegacyServiceAccountTokenNoAutoGeneration feature gate (从 Kubernetes v1.24 到 v1.26 默认启用) 阻止 Kubernetes 为 ServiceAccount 自动创建这些令牌。该 feature gate 在 v1.27 中被移除,因为它已提升到 GA 状态;您仍然可以手动创建无限期的服务帐户令牌,但应考虑安全影响。
说明
对于在 Kubernetes 集群外部运行的应用程序,您可能正在考虑创建一个存储在 Secret 中的长期 ServiceAccount 令牌。这允许身份验证,但 Kubernetes 项目建议您避免这种方法。一旦泄露,长期 bearer 令牌存在安全风险,因为该令牌可能被滥用。相反,请考虑使用替代方案。例如,您的外部应用程序可以使用受良好保护的私钥 和 证书进行身份验证,或者使用自定义机制,例如您自己实现的 authentication webhook。
您还可以使用 TokenRequest 为您的外部应用程序获取短期令牌。
限制对 Secrets 的访问 (已弃用)
Kubernetes v1.32 [已弃用]说明
kubernetes.io/enforce-mountable-secrets 自 Kubernetes v1.32 起已弃用。使用单独的命名空间来隔离对挂载 Secrets 的访问。Kubernetes 提供了一个名为 kubernetes.io/enforce-mountable-secrets 的注释,您可以将其添加到您的 ServiceAccount 中。应用此注释后,ServiceAccount 的 Secrets 只能挂载到指定类型的资源上,从而增强集群的安全性。
您可以使用 manifest 将注释添加到 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubernetes.io/enforce-mountable-secrets: "true"
name: my-serviceaccount
namespace: my-namespace
当此注释设置为“true”时,Kubernetes 控制平面会确保此 ServiceAccount 的 Secrets 受到某些挂载限制的约束。
- 作为 Pod 中卷挂载的每个 Secret 的名称必须出现在 Pod 的 ServiceAccount 的
secrets字段中。 - 使用
envFrom在 Pod 中引用的每个 Secret 的名称也必须出现在 Pod 的 ServiceAccount 的secrets字段中。 - 使用
imagePullSecrets在 Pod 中引用的每个 Secret 的名称也必须出现在 Pod 的 ServiceAccount 的secrets字段中。
通过了解并强制执行这些限制,集群管理员可以保持更严格的安全配置,并确保只有适当的资源才能访问 Secrets。
验证服务帐户凭据
ServiceAccount 使用签名的 JSON Web Tokens (JWT) 向 Kubernetes API 服务器以及存在信任关系的其他任何系统进行身份验证。根据令牌的颁发方式(使用 TokenRequest 限制时间或使用 Secret 的遗留机制),ServiceAccount 令牌可能还具有过期时间、受众和令牌开始有效的的时间。当充当 ServiceAccount 的客户端尝试与 Kubernetes API 服务器通信时,客户端会在 HTTP 请求中包含 Authorization: Bearer <token> 标头。API 服务器会检查该 bearer 令牌的有效性,如下所示
- 检查令牌签名。
- 检查令牌是否已过期。
- 检查令牌声明中的对象引用是否当前有效。
- 检查令牌是否当前有效。
- 检查受众声明。
TokenRequest API 为 ServiceAccount 生成绑定令牌。此绑定链接到充当该 ServiceAccount 的客户端的生命周期,例如 Pod。有关绑定 Pod 服务帐户令牌的 JWT 模式和负载的示例,请参阅 Token Volume Projection。
对于使用 TokenRequest API 颁发的令牌,API 服务器还会检查使用 ServiceAccount 的特定对象引用是否仍然存在,通过该对象的 unique ID 进行匹配。对于作为 Pod 中的 Secrets 挂载的遗留令牌,API 服务器会将令牌与 Secret 进行检查。
有关身份验证过程的更多信息,请参阅 Authentication。
在您自己的代码中验证服务帐户凭据
如果您有需要验证 Kubernetes 服务帐户凭据的自己的服务,可以使用以下方法
- TokenReview API (推荐)
- OIDC 发现
Kubernetes 项目建议您使用 TokenReview API,因为此方法会使与 API 对象(例如 Secrets、ServiceAccount、Pods 或 Nodes)绑定的令牌在这些对象被删除时失效。例如,如果您删除包含 projected ServiceAccount 令牌的 Pod,集群会立即使该令牌失效,并且 TokenReview 会立即失败。如果您改用 OIDC 验证,您的客户端将继续将令牌视为有效,直到令牌到达其到期时间戳为止。
您的应用程序应始终定义它接受的受众,并应检查令牌的受众是否与应用程序期望的受众匹配。这有助于最大限度地减少令牌的范围,以便它只能在您的应用程序中使用,而不能在其他地方使用。
替代方案
- 使用其他机制颁发您自己的令牌,然后使用 Webhook Token Authentication 使用您自己的验证服务来验证 bearer 令牌。
- 为 Pod 提供您自己的身份。
使用 SPIFFE CSI 驱动程序插件将 SPIFFE SVID 作为 X.509 证书对提供给 Pod.
🛇 此项目链接到不属于 Kubernetes 本身的第三方项目或产品。 更多信息
- 从集群外部向 API 服务器进行身份验证,而不使用服务帐户令牌
- 配置 API 服务器以接受来自您的身份提供商的 OpenID Connect (OIDC) 令牌.
- 使用从云提供商等外部身份和访问管理 (IAM) 服务创建的服务帐户或用户帐户来向您的集群进行身份验证。
- 使用 CertificateSigningRequest API 和客户端证书.
- 配置 kubelet 以从镜像仓库检索凭据.
- 使用 Device Plugin 访问虚拟可信平台模块 (TPM),然后允许使用私钥进行身份验证。
接下来
此页面上的项目引用了提供 Kubernetes 所需功能的第三方产品或项目。Kubernetes 项目作者不对这些第三方产品或项目负责。有关更多详细信息,请参阅 CNCF 网站指南。
在提出添加额外的第三方链接的更改之前,您应该阅读 内容指南。