使用 Kubernetes 服务账户授予 Kubernetes 工作负载访问 AWS 的权限 - Amazon EKS

使用 Kubernetes 服务账户授予 Kubernetes 工作负载访问 AWS 的权限

Kubernetes 服务账户为在 Pod 中运行的进程提供身份。有关更多信息,请参阅 Kubernetes 文档中的管理服务账户。如果您的 Pod 需要访问 AWS 服务,您可以将服务账户映射到 AWS Identity and Access Management 身份来授予该访问权限。有关更多信息,请参阅 服务账户的 IAM 角色

服务账户令牌

Kubernetes 版本中默认启用 BoundServiceAccountTokenVolume 功能。此功能允许在 Kubernetes 上运行工作负载,以请求与受众、时间和密钥绑定的 JSON Web 令牌,从而提高了服务账户令牌的安全性。服务账户令牌有效期为 1 小时。在较早的 Kubernetes 版本中,令牌没有过期时间。这意味着依赖这些令牌的客户端必须在一小时内刷新令牌。以下 Kubernetes 客户端开发工具包会在要求的时间范围内自动刷新令牌:

  • Go 版本 0.15.7 和更高版本

  • Python 版本 12.0.0 和更高版本

  • Java 版本 9.0.0 和更高版本

  • JavaScript 版本 0.10.3 和更高版本

  • Ruby master 分支

  • Haskell 版本 0.3.0.0

  • C# 版本 7.0.5 和更高版本

如果您的工作负载使用的是早期客户端,则必须予以更新。为了使客户顺利迁移到更新的有时限的服务账户令牌,Kubernetes 在默认一小时内向服务账户令牌添加延长的到期期限。对于 Amazon EKS 集群,延长到期期限为 90 天。Amazon EKS 集群的 Kubernetes API 服务器会拒绝令牌超过 90 天的请求。我们建议您检查应用程序及其依赖项,以确保 Kubernetes 客户端开发工具包版本等于或高于之前列出的版本。

当 API 服务器收到令牌超过一小时的请求时,它会使用 annotations.authentication.k8s.io/stale-token 注释 API 审核日志事件。注释的值与以下示例类似:

subject: system:serviceaccount:common:fluent-bit, seconds after warning threshold: 4185802.

如果您的集群启用了控制面板日志记录,则注释在审计日志内。您可以使用以下 CloudWatch Logs Insights 查询,以识别 Amazon EKS 集群中使用过时令牌的所有 Pods:

fields @timestamp | filter @logStream like /kube-apiserver-audit/ | filter @message like /seconds after warning threshold/ | parse @message "subject: *, seconds after warning threshold:*\"" as subject, elapsedtime

subject 指的是 Pod 使用的服务账户。elapsedtime 表示读取最新令牌后的时间(以秒为单位)。对 API 服务器的请求在 elapsedtime 超过 90 天(7,776,000 秒)时被拒绝。您应该主动更新应用程序的 Kubernetes 客户端开发工具包,以使用前面列出的其中一个自动刷新令牌的版本。如果使用的服务账户令牌接近 90 天,并且您没有足够的时间在令牌到期之前更新客户端开发工具包版本,您可以终止现有 Pods 并创建新的。这将导致重新获取服务账户令牌,从而为您提供额外 90 天的时间来更新客户端版本开发工具包。

如果 Pod 是部署的一部分,那么在保持高可用性的同时终止 Pods 的建议方法是使用以下命令执行部署。将 my-deployment 替换为您的部署的名称。

kubectl rollout restart deployment/my-deployment

集群附加组件

已更新以下集群附加组件以使用自动重新获取服务账户令牌的 Kubernetes 客户端开发工具包。我们建议确保已在集群上安装列出的版本或更高版本。

向 Amazon Elastic Kubernetes Service 集群上的工作负载授予 AWS Identity and Access Management 权限

对于向 Amazon EKS 集群中运行的工作负载授予 AWS Identity and Access Management 权限,Amazon EKS 提供了两种方法:服务账户的 IAM 角色EKS 容器组身份

服务账户的 IAM 角色

服务账户的 IAM 角色(IRSA)可为 AWS 上运行的 Kubernetes 应用程序配置细粒度 IAM 权限,使其能够访问 Amazon S3 存储桶、Amazon DynamoDB 表等各种其他 AWS 资源。您可以在同一 Amazon EKS 集群中同时运行多个应用程序,并确保每个应用程序仅拥有所需的最低权限集。IRSA 旨在支持 AWS 支持的各种 Kubernetes 部署选项,例如 Amazon EKS、Amazon EKS Anywhere、AWS 云端 Red Hat OpenShift 服务,以及 Amazon EC2 实例上的自我管理 Kubernetes 集群。因此,IRSA 是使用基础 AWS 服务(如 IAM)构建的,不直接依赖 Amazon EKS 服务和 EKS API。有关更多信息,请参阅 服务账户的 IAM 角色

EKS 容器组身份

EKS 容器组身份为集群管理员提供了一个简化的工作流,用于对应用程序进行身份验证,以访问各种其他 AWS 资源,例如 Amazon S3 存储桶、Amazon DynamoDB 表等。EKS 容器组身份仅适用于 EKS,因此简化了集群管理员配置 Kubernetes 应用程序以获取 IAM 权限的方式。现在,可以直接通过 AWS Management Console、EKS API 和 AWS CLI,用更少的步骤即可轻松配置这些权限,而且无需对集群内的任何 Kubernetes 对象执行任何操作。集群管理员无需在 EKS 和 IAM 服务之间切换,也无需使用特权 IAM 操作来配置应用程序所需的权限。现在可以跨多个集群使用 IAM 角色,无需在创建新集群时更新角色信任策略。EKS 容器组身份提供的 IAM 凭证包括角色会话标签,以及集群名称、命名空间、服务账户名称等属性。角色会话标签允许管理员根据匹配的标签访问 AWS 资源,从而使管理员能够创建可跨服务账户使用的单一角色。有关更多信息,请参阅 EKS 容器组身份

比较 EKS 容器组身份和 IRSA

总的来说,EKS 容器组身份和 IRSA 都允许您向在 Kubernetes 集群上运行的应用程序授予 IAM 权限。但是,二者在配置方式、支持的限制和启用的功能方面有根本不同。下面,我们将比较这两种解决方案的一些关键方面。

EKS 容器组身份 IRSA

角色可扩展性

您必须对每个角色设置一次,才能与新引入的 Amazon EKS 服务主体 pods.eks.amazonaws.com 建立信任。完成此一次性步骤后,每次在新集群中使用角色时,都无需更新该角色的信任策略。

每次要在新集群中使用 IAM 角色时,都必须使用新的 EKS 集群 OIDC 提供商端点,来更新该角色的信任策略。

集群可扩展性

EKS 容器组身份不需要用户设置 IAM OIDC 提供商,因此这一限制并不适用。

每个 EKS 集群都有一个与其关联的 OpenID Connect(OIDC)发布者 URL。要使用 IRSA,需要在 IAM 中为每个 EKS 集群创建一个唯一的 OpenID Connect 提供商。IAM 对每个 AWS 账户 的默认全局限制为 100 个 OIDC 提供商。如果您计划为每个使用 IRSA 的 AWS 账户 设置超过 100 个 EKS 集群,那么您将达到 IAM OIDC 提供商限制。

角色可扩展性

EKS 容器组身份不要求用户在信任策略中定义 IAM 角色和服务账户之间的信任关系,因此这一限制并不适用。

在 IRSA 中,您可以在角色的信任策略中定义 IAM 角色和服务账户之间的信任关系。默认情况下,信任策略大小的长度为 2048。这意味着您通常可以在单个信任策略中定义 4 个信任关系。虽然您可以增加信任策略长度限制,但单个信任策略中通常最多只能有 8 个信任关系。

角色可重用性

EKS 容器组身份提供的 AWS STS 临时凭证包括角色会话标签,例如集群名称、命名空间、服务账户名称。角色会话标签使管理员能够创建单个 IAM 角色,该角色可用于具有不同有效权限的多个服务账户,方法是允许根据附加到资源的 AWS 标签来访问资源,也称为基于属性的访问权限控制(ABAC)。有关更多信息,请参阅 定义 EKS 容器组身份的权限以根据标签代入角色

不支持 AWS STS 会话标签。您可以在集群之间重用角色,但每个容器组都会获得该角色的所有权限。

支持的环境

EKS 容器组身份仅在 Amazon EKS 上可用。

IRSA 可用于 Amazon EKS、Amazon EKS Anywhere、AWS 云端 Red Hat OpenShift 服务,以及 Amazon EC2 实例上的自我管理 Kubernetes 集群。

支持的 EKS 版本

EKS Kubernetes 版本 1.24 或更高版本。有关特定平台版本,请参阅 EKS 容器组身份集群版本

所有受支持的 EKS 集群版本。