技术概览 - Amazon EKS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

技术概览

2014 年,AWS Identity and Access Management 使用 OpenID Connect (OIDC) 增加了对联合身份的支持。此功能允许您通过支持的身份提供商对 AWS API 调用进行身份验证,并获得有效的 OIDC Web 令牌 (JWT)。您可以将此令牌传递到 AWS STS AssumeRoleWithWebIdentity API 操作并接收 IAM 临时角色凭证。您可以使用这些凭证与任意 AWS 服务交互,例如 Amazon S3 和 DynamoDB。

Kubernetes 长期以来将服务账户用作其内部身份系统。Pod 可以使用自动装载的令牌(这是非 OIDC JWT,只有 Kubernetes API 服务器可以验证)进行 Kubernetes API 服务器的身份验证。这些旧服务账户令牌不会过期,轮换签名密钥是一个困难的过程。在 Kubernetes 版本 1.12 中,为新 ProjectedServiceAccountToken 功能添加了支持,这是还包含了服务账户身份的 OIDC JSON Web 令牌,并支持可配置的受众。

Amazon EKS 现在针对包含 ProjectedServiceAccountToken JSON Web 令牌的签名密钥的集群,托管公有 OIDC 搜索终端节点,这样 IAM 等外部系统可以验证和接收 Kubernetes 发布的 OIDC 令牌。

IAM 角色配置

在 IAM 中,您创建具有可信关系的 IAM 角色,其范围限定为您集群的 OIDC 提供方、服务账户命名空间以及(可选)服务账户名称,然后附加您要与服务账户关联的 IAM 策略。您可在下方的 StringEqualsStringLike 条件中添加多个条目,以将多个服务账户或命名空间用于角色。

  • 将角色范围限定为特定服务账户:

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/<OIDC_PROVIDER>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "<OIDC_PROVIDER>:sub": "system:serviceaccount:<SERVICE_ACCOUNT_NAMESPACE>:<SERVICE_ACCOUNT_NAME>" } } } ] }
  • 将角色限定为整个命名空间(以使用命名空间为边界):

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/<OIDC_PROVIDER>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringLike": { "<OIDC_PROVIDER>:sub": "system:serviceaccount:<SERVICE_ACCOUNT_NAMESPACE>:*" } } } ] }

服务账户配置

在 Kubernetes 中,您通过添加 eks.amazonaws.com/role-arn 注释到服务账户,定义 IAM 角色与集群中的服务账户关联。

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>

Pod 配置

集群上的 Amazon EKS Pod 身份 Webhook 监视与具有此注释的服务账户关联的 Pod,并对其应用以下环境变量。

AWS_ROLE_ARN=arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME> AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
注意

您的集群无需使用变异的 Webhook 来配置环境变量和令牌文件装载;您可以选择配置 Pod 以手动添加这些环境变量。

重要

如果您的 Amazon EKS 集群运行的是 Kubernetes 版本 1.17 或更早版本,则您需要将以下环境变量添加到为 中国 区域中的服务账户使用 IAM 角色的所有 Pod,无论您是使用更改 Webhook 还是手动配置环境变量。

AWS_DEFAULT_REGION=<region-code>

AWS 开发工具包支持的版本首先在凭证链提供商中查找这些环境变量。角色凭证用于满足这些标准的 Pod。

注意

当 Pod 使用来自与服务账户关联的 IAM 角色的 AWS 凭证时,该 Pod 的容器中的 AWS CLI 或其他 SDKs 将使用该角色提供的凭证。除非您限制对这些凭证的访问,否则 Pod 仍有权访问提供给 Amazon EKS 节点 IAM 角色 的凭证。有关更多信息,请参阅限制对 IMDS 和 Amazon EC2 实例配置文件凭证的访问

默认情况下,只有以 root 身份运行的容器才具有正确的文件系统权限来读取 Web 身份令牌文件。您可以通过使容器以 root 身份运行或通过为清单中的容器提供以下安全上下文,以提供这些权限。fsGroup ID 是任意的,您可以选择任何有效的组 ID。有关为 Pod 设置安全上下文的含义的更多信息,请参阅 Kubernetes 文档中的为 Pod 或容器配置安全上下文

apiVersion: apps/v1 kind: Deployment metadata: name: <my-app> spec: template: metadata: labels: app: <my-app> spec: serviceAccountName: <my-app> containers: - name: <my-app> image: <my-app>:latest securityContext: fsGroup: <1337> ...

代表 Pod 请求并存储令牌。kubelet默认情况下,如果令牌早于其总 TTL 的 80%,或者令牌超过 24 小时,kubelet 将刷新令牌。您可以使用 Pod 规范中的设置修改任何账户(默认服务账户除外)的过期持续时间。有关更多信息,请参阅 Kubernetes 文档中的服务账户令牌卷投影

跨账户 IAM 权限

您可以通过从另一个账户的集群创建身份提供商或使用链接的 IAM 操作来配置跨账户 AssumeRole 权限。在以下示例中,账户 A 拥有一个 Amazon EKS 集群,支持服务账户的 IAM 角色。在该集群上运行的 Pod 需要代入来自账户 B 的 IAM 权限。

例 : 从其他账户的集群创建身份提供商

在此示例中,账户 A 将从其集群向账户 B 提供 OIDC 发布者 URL。账户 B 遵循为集群创建 IAM OIDC 提供商为服务账户创建 IAM 角色和策略中的说明,并使用来自账户 A 集群的 OIDC 发布者 URL。然后,集群管理员注释账户 A 的集群中的服务账户以使用来自账户 B 的角色。

apiVersion: v1 kind: ServiceAccount metadata: annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_B_AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>

例 :使用链接 AssumeRole 操作

在此示例中,账户 B 创建一个 IAM 策略,其中包括授予账户 A 集群中 Pod 的权限。账户 B 将该策略附加到具有可信关系的 IAM 角色,允许对账户 A (111111111111) 的 AssumeRole 权限,如下所示。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:root" }, "Action": "sts:AssumeRole", "Condition": {} } ] }

账户 A 创建具有信任策略的角色,从使用集群的 OIDC 发布者 URL 创建的身份提供商获取凭证,如下所示。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111111111111:oidc-provider/oidc.eks.<region-code>.amazonaws.com/id/EXAMPLEC061A78C479E31025A21AC4CDE191335D05820BE5CE" }, "Action": "sts:AssumeRoleWithWebIdentity" } ] }

账户 A 将策略附加到具有以下权限的角色,以代入账户 B 创建的角色。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::222222222222:role/account-b-role" } ] }

Pod 的应用程序代码代入账户 B 的角色使用两个配置文件:account_b_roleaccount_a_role。 配置文件使用 account_b_role 配置文件作为其源。account_a_role对于 AWS CLI,该 ~/.aws/config 文件类似于下例所示。

[profile account_b_role] source_profile = account_a_role role_arn=arn:aws:iam::222222222222:role/account-b-role [profile account_a_role] web_identity_token_file = /var/run/secrets/eks.amazonaws.com/serviceaccount/token role_arn=arn:aws:iam::111111111111:role/account-a-role

要为其他 AWS SDKs 指定链接的配置文件,请参阅其文档。