本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
身份和访问管理
提示
通过亚马逊 EKS 研讨会探索
身份和访问管理 (IAM) 是一项执行两项基本功能的 AWS 服务:身份验证和授权。身份验证涉及身份验证,而授权则管理 AWS 资源可以执行的操作。在 AWS 中,资源可以是其他 AWS 服务,例如 EC2,也可以是 AWS 委托人,例如 I AM 用户或角色。管理允许资源执行的操作的规则以 IAM 策略表示。
控制对 EKS 集群的访问权限
Kubernetes 项目支持各种不同的策略来验证向 kube-apiserver 服务发出的请求,例如持有者代币、证书、OIDC 等。X.509 EKS 目前原生支持 webhook 代币身份验证
webhook 身份验证策略调用一个用于验证持有者令牌的 webhook。在 EKS 上,当您运行命令时,这些不记名令牌由 AWS CLI 或 aws-iam-authenticator 客户端kubectl当你执行命令时,令牌会被传递给 kube-apiserver,由后者将其转发到身份验证 webhook。如果请求的格式正确,则 webhook 会调用嵌入在令牌正文中的预签名 URL。此 URL 会验证请求的签名并返回有关用户的信息,例如用户的账户 Arn 和 UserId kube-apiserver。
要手动生成身份验证令牌,请在终端窗口中键入以下命令:
aws eks get-token --cluster-name <cluster_name> --region <region>
输出应如下所示:
{ "kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": { "expirationTimestamp": "2024-12-20T17:38:48Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20vP0FjdGlvbj1HZ...." } }
您也可以通过编程方式获取代币。以下是用 Go 编写的示例:
package main import ( "fmt" "log" "sigs.k8s.io/aws-iam-authenticator/pkg/token" ) func main() { g, _ := token.NewGenerator(false, false) tk, err := g.Get("<cluster_name>") if err != nil { log.Fatal(err) } fmt.Println(tk) }
输出应如下所示:
{ "kind": "ExecCredential", "apiVersion": "client.authentication.k8s.io/v1alpha1", "spec": {}, "status": { "expirationTimestamp": "2020-02-19T16:08:27Z", "token": "k8s-aws-v1.aHR0cHM6Ly9zdHMuYW1hem9uYXdzLmNvbS8_QWN0aW9uPUdldENhbGxlcklkZW50aXR5JlZlcnNpb249MjAxMS0wNi0xNSZYLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFKTkdSSUxLTlNSQzJXNVFBJTJGMjAyMDAyMTklMkZ1cy1lYXN0LTElMkZzdHMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDIwMDIxOVQxNTU0MjdaJlgtQW16LUV4cGlyZXM9NjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JTNCeC1rOHMtYXdzLWlkJlgtQW16LVNpZ25hdHVyZT0yMjBmOGYzNTg1ZTMyMGRkYjVlNjgzYTVjOWE0MDUzMDFhZDc2NTQ2ZjI0ZjI4MTExZmRhZDA5Y2Y2NDhhMzkz" } }
每个令牌的开头都k8s-aws-v1.是 base64 编码的字符串。该字符串在解码后应类似于以下内容:
https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXJPFRILKNSRC2W5QA%2F20200219%2Fus-xxxx-1%2Fsts%2Faws4_request&X-Amz-Date=20200219T155427Z&X-Amz-Expires=60&X-Amz-SignedHeaders=host%3Bx-k8s-aws-id&X-Amz-Signature=XXXf8f3285e320ddb5e683a5c9a405301ad76546f24f28111fdad09cf648a393
该令牌由包含亚马逊凭证和签名的预签名 URL 组成。有关其他详细信息,请参阅 https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html.
代币的生存时间(TTL)为 15 分钟,之后需要生成新的代币。当你使用客户端时,会自动处理这个问题kubectl,但是,如果你使用的是 Kubernetes 仪表板,则需要生成一个新的令牌,并在每次令牌到期时重新进行身份验证。
在 AWS IAM 服务对用户的身份进行身份验证后,kube-apiserver 会读取kube-system命名空间aws-auth ConfigMap 中的,以确定要与用户关联的 RBAC 组。用于aws-auth ConfigMap 在 IAM 委托人(即 IAM 用户和角色)与 Kubernetes RBAC 群组之间创建静态映射。可以在 Kub RoleBindings ernetes 或. 中引用 RBAC 组。ClusterRoleBindings它们与 IAM 角色类似,因为它们定义了一组可以对一组 Kubernetes 资源(对象)执行的操作(动词)。
CloudWatch 查询以帮助用户识别向全球 STS 端点发送请求的客户端
运行下面的 CloudWatch 查询以获取 sts 端点。如果 stsendpoint 等于 “sts.amazonaws.com”,则它是一个全球 STS 终端节点。如果 stsendpoint 等于 “sts。<region>.amazonaws.com”,那么它是一个区域性 STS 终端节点。
fields @timestamp, @message, @logStream, @log,stsendpoint | filter @logStream like /authenticator/ | filter @message like /stsendpoint/ | sort @timestamp desc | limit 10000
集群访问管理器
集群访问管理器现在是管理 AWS IAM 委托人对亚马逊 EKS 集群访问权限的首选方式,它是 AWS API 的一项功能,也是 EKS v1.23 及更高版本集群(新的或现有的)的选择加入功能。它简化了AWS IAM和Kubernetes RBAC之间的身份映射,无需在AWS和Kubernetes API之间切换或编辑访问管理,从而减少了aws-auth ConfigMap 运营开销,并有助于解决配置错误的问题。该工具还使集群管理员能够撤消或细化自动授予用于创建集群的 AWS IAM 委托人的cluster-admin权限。
此 API 依赖于两个概念:
-
访问条目:直接链接到允许向 Amazon EKS 集群进行身份验证的 AWS IAM 委托人(用户或角色)的集群身份。
-
访问策略:是亚马逊 EKS 特定的策略,为访问入口提供在亚马逊 EKS 集群中执行操作的授权。
在启动时,亚马逊 EKS 仅支持预定义和 AWS 托管策略。访问策略不是 IAM 实体,由亚马逊 EKS 定义和管理。
集群访问管理器允许将上游 RBAC 与支持允许和通过(但不拒绝)有关 API 服务器请求的 Kubernetes AuthZ 决策的访问策略相结合。当上游 RBAC 和 Amazon EKS 授权方都无法确定请求评估的结果时,就会做出拒绝决定。
借助此功能,亚马逊 EKS 支持三种身份验证模式:
-
CONFIG_MAP继续专门使用aws-authConfigMap。 -
API_AND_CONFIG_MAP从 EKS 访问入口 API 和aws-authConfigMap 中获取经过身份验证的 IAM 委托人,优先考虑访问条目。非常适合将现有aws-auth权限迁移到访问条目。 -
API完全依赖 EKS 访问入口 API。这是新的推荐方法。
首先,集群管理员可以创建或更新 Amazon EKS 集群,将首选身份验证设置为API_AND_CONFIG_MAP或API方法,并定义访问条目以授予所需的 AWS IAM 委托人访问权限。
$ aws eks create-cluster \ --name <CLUSTER_NAME> \ --role-arn <CLUSTER_ROLE_ARN> \ --resources-vpc-config subnetIds=<value>,endpointPublicAccess=true,endpointPrivateAccess=true \ --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}' \ --access-config authenticationMode=API_AND_CONFIG_MAP,bootstrapClusterCreatorAdminPermissions=false
以上命令是在没有集群创建者管理员权限的情况下创建 Amazon EKS 集群的示例。
可以使用命令更新 Amazon EKS 集群配置以启用API身份验证模式,要使用该update-cluster-config命令在现有集群上执行此操作,CONFIG_MAP您必须先更新到,API_AND_CONFIG_MAP然后更新到。API这些操作无法恢复,这意味着无法从切换API到API_AND_CONFIG_MAP或CONFIG_MAP,也无法从切换API_AND_CONFIG_MAP到CONFIG_MAP。
$ aws eks update-cluster-config \ --name <CLUSTER_NAME> \ --access-config authenticationMode=API
API 支持添加和撤消对集群的访问权限以及验证指定集群的现有访问策略和访问条目的命令。默认策略是为匹配 Kubernetes RBAC 而创建的,如下所示。
| EKS 访问政策 | Kubernetes RBAC |
|---|---|
|
AmazonEKSClusterAdminPolicy |
集群管理员 |
|
AmazonEKSAdminPolicy |
admin |
|
AmazonEKSEditPolicy |
编辑 |
|
AmazonEKSViewPolicy |
查看 |
$ aws eks list-access-policies { "accessPolicies": [ { "name": "AmazonEKSAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" }, { "name": "AmazonEKSClusterAdminPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" }, { "name": "AmazonEKSEditPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" }, { "name": "AmazonEKSViewPolicy", "arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" } ] } $ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] }
在没有集群创建者管理员权限的情况下创建集群时,没有可用的访问条目,这是默认情况下创建的唯一条目。
aws-auth ConfigMap (已弃用)
实现 Kubernetes 与 AWS 身份验证集成的一种方法是通过位于aws-auth ConfigMap命名空间中的。kube-system它负责将 AWS IAM 身份(用户、群组和角色)身份验证映射到 Kubernetes 基于角色的访问控制 (RBAC) 授权。将在您的亚马逊 EKS 集群的配置阶段自动创建。aws-auth ConfigMap 它最初是为了允许节点加入您的集群而创建的,但如前所述,您也可以使用它 ConfigMap 来向 IAM 委托人添加 RBAC 访问权限。
要检查您的集群 aws-auth ConfigMap,您可以使用以下命令。
kubectl -n kube-system get configmap aws-auth -o yaml
这是的默认配置示例aws-authConfigMap。
apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes - system:node-proxier rolearn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/kube-system-<SELF_GENERATED_UUID> username: system:node:{{SessionName}} kind: ConfigMap metadata: creationTimestamp: "2023-10-22T18:19:30Z" name: aws-auth namespace: kube-system
其主要会话位于区块下方data,该mapRoles区块基本上由3个参数组成。 ConfigMap
-
群组:要将 IAM 角色映射 group/groups 到的 Kubernetes。这可以是默认群组,也可以是或中指定的自定义群组
rolebinding。clusterrolebinding在上面的示例中,我们只声明了系统组。 -
rolearn:使用以下格式将 AWS IAM 角色的 ARN 映射到 Kubernetes group/groups 添加项。
arn:<PARTITION>:iam::<AWS_ACCOUNT_ID>:role/role-name -
用户名:在 Kubernetes 中映射到 AWS IAM 角色的用户名。这可以是任何自定义名称。
也可以为 AWS IAM 用户映射权限,data在下方定义一个新的配置块 mapUsers aws-authConfigMap,替换 userar n 的 role arn 参数,但作为最佳实践,始终建议用户改用。mapRoles
要管理权限,您可以编辑aws-auth ConfigMap 添加或删除对 Amazon EKS 集群的访问权限。尽管可以aws-auth ConfigMap 手动编辑,但建议使用诸如此类的工具,因为这是一种非常敏感的配置eksctl,不准确的配置可能会将您锁定在Amazon EKS集群之外。查看下方的 “使用工具更改 aws-auth” 小节以 ConfigMap了解更多详细信息。
与 ConfigMap-based 访问管理相比的好处
-
降低错误配置的风险:直接 API-based 管理消除了与手动 ConfigMap 编辑相关的常见错误。这有助于防止意外删除或可能将用户锁定在群集之外的语法错误。
-
增强的最小权限原则:消除了集群创建者身份对集群管理员权限的需求,允许进行更精确、更适当的权限分配。您可以选择为 break-glass 用例添加此权限。
-
增强的安全模型:在应用访问条目之前提供内置验证。此外,还提供与 AWS IAM 更紧密的集成以进行身份验证。
-
简化操作:提供一种更直观的方式来通过 AWS-native 工具管理权限。
集群访问建议
将 IAM 身份中心与 CAM API 相结合
-
简化管理:通过将集群访问管理 API 与 IAM 身份中心结合使用,管理员可以管理 EKS 集群访问以及其他 AWS 服务,从而减少在不同接口之间切换或 ConfigMaps 手动编辑的需求。
-
使用访问条目管理集群外的 IAM 主体的 Kubernetes 权限。您可以使用 EKS API、AWS 命令行接口、AWS 开发工具包、AWS 和 AWS 管理控制台添加和管理对集群的访问权限。 CloudFormation这意味着您可以使用与创建集群相同的工具来管理用户。
-
如本示例
所示,利用自动化来部署以 AWS IAM 身份中心作为 IdP、以 CAM API 作为入口点的集群。 -
可以通过访问条目和访问策略将 Kubernetes 用户或群组与与 SSO 身份关联的 IAM 委托人映射,从而应用精细的 Kubernetes 权限。
-
首先,按照更改身份验证模式以使用访问条目,然后按照将现有的 aws-auth 条目迁移到访问 ConfigMap 条目进行操作。
将 EKS 集群终端节点设为私有
默认情况下,当您配置 EKS 集群时,API 集群终端节点设置为公共,即可以从互联网访问该终端节点。尽管可以从互联网访问,但该终端节点仍被认为是安全的,因为它要求所有 API 请求都要通过 IAM 进行身份验证,然后由 Kubernetes RBAC 授权。也就是说,如果您的企业安全政策要求您限制从互联网访问 API 或阻止您将流量路由到集群 VPC 之外,则您可以:
-
将 EKS 集群终端节点配置为私有。有关此主题的更多信息,请参阅修改集群终端节点访问权限。
-
将集群终端节点保持公开状态,并指定哪些 CIDR 块可以与集群终端节点通信。这些区块实际上是一组列入白名单的公有 IP 地址,允许访问集群终端节点。
-
使用一组列入白名单的 CIDR 块配置公共访问权限,并将私有终端节点访问权限设置为启用。这将允许来自特定范围的公有 IP 的公共访问,同时通过配置控制平面时配置到集群 VPC 中的跨账户 ENI 强制执行 kubelets(工作程序)和 Kubernetes API 之间的所有网络流量。
不要使用服务帐号令牌进行身份验证
服务帐号令牌是一种长期的静态凭证。如果该令牌遭到破坏、丢失或被盗,攻击者可能能够执行与该令牌相关的所有操作,直到该服务帐号被删除。有时,您可能需要为必须从集群外部使用 Kubernetes API 的应用程序(例如管道应用程序)授予例外权限。 CI/CD如果此类应用程序在 AWS 基础设施(如 EC2 实例)上运行,请考虑使用实例配置文件并将其映射到 Kubernetes RBAC 角色。
使用最低权限访问 AWS 资源
无需为 IAM 用户分配 AWS 资源的权限即可访问 Kubernetes API。如果您需要授予 IAM 用户访问 EKS 集群的权限,请在中aws-auth ConfigMap 为该用户创建一个映射到特定 Kubernetes RBAC 组的条目。
从集群创建者主体中移除集群管理员权限
默认情况下,Amazon EKS 集群是在绑定到集群创建者主体的永久cluster-admin权限的情况下创建的。使用集群访问管理器 API,在使用API_AND_CONFIG_MAP或API身份验证模式时false,无需此权限--access-config bootstrapClusterCreatorAdminPermissions将设置为,即可创建集群。撤消此访问权限被认为是最佳做法,以避免对群集配置进行任何不必要的更改。撤消此访问权限的过程与撤消对集群的任何其他访问权限的过程相同。
API 使您可以灵活地仅取消IAM委托人与访问策略的关联,在本例中AmazonEKSClusterAdminPolicy为。
$ aws eks list-associated-access-policies \ --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN> $ aws eks disassociate-access-policy --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN. \ --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
或者完全删除与cluster-admin权限相关的访问条目。
$ aws eks list-access-entries --cluster-name <CLUSTER_NAME> { "accessEntries": [] } $ aws eks delete-access-entry --cluster-name <CLUSTER_NAME> \ --principal-arn <IAM_PRINCIPAL_ARN>
在集群无法访问的事故、紧急情况或破碎玻璃场景中,如果需要,可以再次授予此访问权限。
如果群集仍使用CONFIG_MAP身份验证方法进行配置,则应通过授予所有其他用户访问群集的权限 aws-auth ConfigMap,配置完成后 aws-auth ConfigMap ,可以删除分配给创建群集的实体的角色,只有在发生事故、紧急情况或破碎情况时,或者出现损坏而无法访问群集的情况下才能重新创建。aws-auth ConfigMap 这在生产集群中可能特别有用。
当多个用户需要相同的集群访问权限时使用 IAM 角色
与其为每个 IAM 用户创建条目,不如允许这些用户代入 IAM 角色并将该角色映射到 Kubernetes RBAC 群组。这将更易于维护,尤其是在需要访问权限的用户数量增加的情况下。
重要
当访问 IAM 实体映射的 EKS 集群时 aws-auth ConfigMap,描述的用户名会记录在 Kubernetes 审计日志的用户字段中。如果您使用的是 IAM 角色,则不会记录代入该角色的实际用户,也无法对其进行审计。
如果仍使用 aws-auth ConfigMap 作为身份验证方法,则在为 IAM 角色分配 K8s RBAC 权限时,应在用户名中包含\ {{SessionName}}。这样,审核日志将记录会话名称,这样您就可以在 CloudTrail 日志中跟踪实际用户是谁担任了这个角色。
- rolearn: arn:aws:iam::XXXXXXXXXXXX:role/testRole username: testRole:{{SessionName}} groups: - system:masters
创建 RoleBindings 和时使用最低权限访问权限 ClusterRoleBindings
就像前面关于授予AWS资源访问权限的观点一样,RoleBindings 并且 ClusterRoleBindings 应仅包括执行特定功能所需的权限集。除非绝对必要, ClusterRoles 否则请避免["*"]在角色中使用。如果你不确定要分配什么权限,可以考虑使用像 a udit2rbac
使用自动化流程创建集群
如前面的步骤所示,创建 Amazon EKS 集群时,如果不使用使用API_AND_CONFIG_MAP或API身份验证模式,也没有选择退出向集群创建者委派cluster-admin权限,IAM 实体用户或角色,例如创建集群的联合用户,将在集群的 RBAC 配置中自动获得system:masters权限。即使是删除此权限的最佳做法,如这里所述,如果使用CONFIG_MAP身份验证方法,则无法撤消此访问权限。aws-auth ConfigMap因此,最好使用与专用 IAM 角色关联的基础设施自动化管道来创建集群,不允许其他用户或实体承担任何权限,并定期审核该角色的权限、策略以及谁有权触发管道。此外,此角色不应用于在集群上执行例行操作,而应专门用于管道通过更改 SCM 代码等触发的集群级别操作。
使用专用 IAM 角色创建集群
当您创建 Amazon EKS 集群时,IAM 实体用户或角色(例如创建集群的联合用户)将在集群的 RBAC 配置中自动获得system:masters权限。此访问权限无法删除,也无法通过进行管理aws-auth ConfigMap。因此,最好使用专用 IAM 角色创建集群并定期审核谁可以担任该角色。不应使用此角色对群集执行例行操作,而应为此目的通过向其他用户授予对群集aws-auth ConfigMap 的访问权限。配置完成后,应保护该角色,并且仅在临时提升权限模式/break glass 中用于否则无法访问集群的场景。aws-auth ConfigMap 这在未配置用户直接访问权限的集群中特别有用。
定期审核对集群的访问权限
随着时间的推移,谁需要访问权限可能会发生变化。计划定期审计,aws-auth ConfigMap 以查看谁被授予了访问权限以及他们被分配了哪些权限。你还可以使用 kubectl-who-can 或 rbac-lookup 等开源工具
如果依赖 aws-auth,请使用工具进行更改
格式不正确的 aws-auth ConfigMap 可能会导致您无法访问集群。如果您需要对进行更改 ConfigMap,请使用工具。
eksctl eksctl CLI 包含一个用于向 aws-auth 添加身份映射的命令。 ConfigMap
查看 CLI 帮助:
$ eksctl create iamidentitymapping --help ...
检查映射到您的亚马逊 EKS 集群的身份。
$ eksctl get iamidentitymapping --cluster $CLUSTER_NAME --region $AWS_REGION ARN USERNAME GROUPS ACCOUNT arn:aws:iam::788355785855:role/kube-system-<SELF_GENERATED_UUID> system:node:{{SessionName}} system:bootstrappers,system:nodes,system:node-proxier
将 IAM 角色设置为集群管理员:
$ eksctl create iamidentitymapping --cluster <CLUSTER_NAME> --region=<region> --arn arn:aws:iam::123456:role/testing --group system:masters --username admin ...
如需更多信息,请查看eksctl文档
aws-authby keikoproj 包括一个 cli 和一个 go 库。
下载并查看帮助 CLI 帮助:
$ go get github.com/keikoproj/aws-auth ... $ aws-auth help ...
或者,aws-auth使用适用于 kubectl 的 krew 插件管理器
$ kubectl krew install aws-auth ... $ kubectl aws-auth ...
查看上的 aws-auth 文档 GitHub
该aws-iam-authenticator项目包括一个用于更新的 CLI ConfigMap。
在
向 IAM 角色添加集群权限:
$ ./aws-iam-authenticator add role --rolearn arn:aws:iam::185309785115:role/lil-dev-role-cluster --username lil-dev-user --groups system:masters --kubeconfig ~/.kube/config ...
身份验证和访问管理的替代方法
虽然 IAM 是对需要访问 EKS 集群的用户进行身份验证的首选方式,但也可以使用 OIDC 身份提供商,例如GitHub 使用身份验证代理和 Kubernet es 模拟。
重要
EKS 本机支持 OIDC 身份验证,无需使用代理。欲了解更多信息,请阅读发布博客,介绍亚马逊 EKS 的 OIDC 身份提供商身份验证。
你还可以使用 AWS SSO 将 AWS 与外部身份提供商(例如 Azure AD)联合起来。如果您决定使用它,AWS CLI v2.0 包含一个创建命名配置文件的选项,这样可以轻松地将 SSO 会话与当前 CLI 会话关联并代入 IAM 角色。知道在运行之前你必须扮演一个角色,kubectl因为 IAM 角色用于确定用户的 Kubernetes RBAC 组。
EKS pod 的身份和证书
在 Kubernetes 集群中运行的某些应用程序需要权限才能调用 Kubernetes API 才能正常运行。例如,AWS 负载均衡器控制器
Kubernetes 服务账户
服务账号是一种特殊类型的对象,它允许你为 pod 分配 Kubernetes RBAC 角色。系统会自动为集群中的每个命名空间创建默认服务帐号。当你在不引用特定服务账户的情况下将 Pod 部署到命名空间时,该命名空间的默认服务账户将自动分配给 Pod,即该服务账户的服务账户 (JWT) 令牌,将作为卷挂载到容器上。/var/run/secrets/kubernetes.io/serviceaccount解码该目录中的服务帐号令牌将显示以下元数据:
{ "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "default", "kubernetes.io/serviceaccount/secret.name": "default-token-5pv4z", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/service-account.uid": "3b36ddb5-438c-11ea-9438-063a49b60fba", "sub": "system:serviceaccount:default:default" }
默认服务账户拥有以下对 Kubernetes API 的权限。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2020-01-30T18:13:25Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "43" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/system%3Adiscovery uid: 350d2ab8-438c-11ea-9438-063a49b60fba rules: - nonResourceURLs: - /api - /api/* - /apis - /apis/* - /healthz - /openapi - /openapi/* - /version - /version/ verbs: - get
此角色授权未经身份验证和身份验证的用户读取 API 信息,并被认为可以安全地公开访问。
当在 Pod 中运行的应用程序调用 Kubernetes API 时,需要为该 Pod 分配一个服务帐号,明确授予其调用这些 API 的权限。与用户访问准则类似,角色或 ClusterRole 绑定到服务帐号应仅限于应用程序运行所需的 API 资源和方法,仅限于其他任何内容。要使用非默认服务帐号,只需将 Pod 的spec.serviceAccountName字段设置为你想要使用的服务帐号的名称即可。有关创建服务帐号的更多信息,请参阅 https://kubernetes.io/docs/reference/access-authn-authz/rbac/ #service-account-permissions。
注意
在 Kubernetes 1.24 之前,Kubernetes 会自动为每个 a 服务账户创建一个密钥。这个密钥安装在 pod 上的/var/run/secrets/kubernetes。io/serviceaccount 并将被 pod 用来向 Kubernetes API 服务器进行身份验证。在 Kubernetes 1.24 中,服务账户令牌是在容器运行时动态生成的,默认情况下仅在一小时内有效。不会为服务帐号创建密钥。如果你的应用程序在集群之外运行,需要通过 Kubernetes API 进行身份验证,例如 Jenkins,则需要创建一个类型为的机密kubernetes.io/service-account-token以及一个引用服务账户的注解,例如。metadata.annotations.kubernetes.io/service-account.name: <SERVICE_ACCOUNT_NAME>以这种方式创建的密钥不会过期。
服务账户的 IAM 角色(IRSA)
IRSA 是一项允许您为 Kubernetes 服务账户分配 IAM 角色的功能。它通过利用名为服务账户代币量预测的Kubernetes功能来工作。sts:AssumeRoleWithWebIdentity验证代币签名后,IAM 将 Kubernetes 发行的代币交换为临时 AWS 角色证书。
使用 IRSA 时,必须重复使用 AWS 开发工具包会话,以避免对 AWS STS 进行不必要的调用。
解码 IRSA 的 (JWT) 令牌将产生与您在下面看到的示例类似的输出:
{ "aud": [ "sts.amazonaws.com" ], "exp": 1582306514, "iat": 1582220114, "iss": "https://oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "kubernetes.io": { "namespace": "default", "pod": { "name": "alpine-57b5664646-rf966", "uid": "5a20f883-5407-11ea-a85c-0e62b7a4a436" }, "serviceaccount": { "name": "s3-read-only", "uid": "a720ba5c-5406-11ea-9438-063a49b60fba" } }, "nbf": 1582220114, "sub": "system:serviceaccount:default:s3-read-only" }
这个特殊的代币通过担任 IAM 角色向 S3 授予 Pod 仅限查看的权限。当应用程序尝试从 S3 读取数据时,令牌会交换一组临时的 IAM 证书,如下所示:
{ "AssumedRoleUser": { "AssumedRoleId": "AROA36C6WWEJULFUYMPB6:abc", "Arn": "arn:aws:sts::123456789012:assumed-role/eksctl-winterfell-addon-iamserviceaccount-de-Role1-1D61LT75JH3MB/abc" }, "Audience": "sts.amazonaws.com", "Provider": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128", "SubjectFromWebIdentityToken": "system:serviceaccount:default:s3-read-only", "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "FwoGZXIvYXdzEGMaDMLxAZkuLpmSwYXShiL9A1S0X87VBC1mHCrRe/pB2oesl1eXxUYnPJyC9ayOoXMvqXQsomq0xs6OqZ3vaa5Iw1HIyA4Cv1suLaOCoU3hNvOIJ6C94H1vU0siQYk7DIq9Av5RZeuE2FnOctNBvYLd3i0IZo1ajjc00yRK3v24VRq9nQpoPLuqyH2jzlhCEjXuPScPbi5KEVs9fNcOTtgzbVf7IG2gNiwNs5aCpN4Bv/Zv2A6zp5xGz9cWj2f0aD9v66vX4bexOs5t/YYhwuwAvkkJPSIGvxja0xRThnceHyFHKtj0Hbi/PWAtlI8YJcDX69cM30JAHDdQHltm/4scFptW1hlvMaPWReCAaCrsHrATyka7ttw5YlUyvZ8EPogj6fwHlxmrXM9h1BqdikomyJU00gm1FJelfP1zAwcyrxCnbRl3ARFrAt8hIlrT6Vyu8WvWtLxcI8KcLcJQb/LgkWsCTGlYcY8z3zkigJMbYn07ewTL5Ss7LazTJJa758I7PZan/v3xQHd5DEc5WBneiV3iOznDFgup0VAMkIviVjVCkszaPSVEdK2NU7jtrh6Jfm7bU/3P6ZGCkyDLIa8MBn9KPXeJd/yjTk5IifIwO/mDpGNUribg6TPxhzZ8b/XdZO1kS1gVgqjXyVCM+BRBh6C4H21w/eMzjCtDIpoxt5rGKL6Nu/IFMipoC4fgx6LIIHwtGYMG7SWQi7OsMAkiwZRg0n68/RqWgLzBt/4pfjSRYuk=", "Expiration": "2020-02-20T18:49:50Z", "AccessKeyId": "ASIAIOSFODNN7EXAMPLE" } }
作为 EKS 控制平面的一部分运行的变异 webhook 将 AWS 角色 ARN 和网络身份令牌文件路径作为环境变量注入到 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
当预计的代币超过其总有效期的 80% 时,或在 24 小时之后,kubelet 将自动轮换该代币。AWS 开发工具包负责在令牌轮换时重新加载令牌。有关 IRSA 的更多信息,请参阅 https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html.
EKS 容器组身份
EKS Pod Identities 是 re: Invent 2023 上推出的一项功能,允许您为 kubernetes 服务账户分配 IAM 角色,而无需为 AWS 账户中的每个集群配置 Open ID Connect (OIDC) 身份提供商 (IDP)。要使用 EKS Pod 身份,你必须在每个符合条件的工作节点上部署一个作为 DaemonSet pod 运行的代理。此代理作为 EKS 提供给您,是使用 EKS Add-on Pod 身份功能的先决条件。您的应用程序必须使用支持的 AWS 开发工具包版本才能使用此功能。
为 Pod 配置 EKS Pod 身份后,EKS 将在上挂载并刷新 Pod 身份令牌/var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token。AWS 开发工具包将使用此令牌与 EKS Pod 身份代理通信,后者使用容器身份令牌和代理的 IAM 角色通过调用 AssumeRoleForPodIdentity API 为您的容器创建临时证书。传送到您的 pod 身份令牌是由您的 EKS 集群颁发的 JWT 并经过加密签名的,带有相应的 JWT 声明可用于 EKS Pod 身份。
要了解有关 EKS Pod 身份的更多信息,请参阅此博客
您无需对应用程序代码进行任何修改即可使用 EKS Pod 身份。支持的 AWS SDK 版本将使用凭证提供商链自动发现通过 EKS Pod 身份提供的证书。与 IRSA 一样,EKS 容器身份在您的 pod 中设置变量,指导它们如何查找 AWS 证书。
为 EKS Pod 身份使用 IAM 角色
-
为服务帐号配置 EKS Pod 身份的调用者必须拥有该角色的
iam:PassRole权限。 -
每个服务账户只能有一个通过 EKS Pod 身份关联的 IAM 角色,但是您可以将同一 IAM 角色与多个服务账户关联起来。
-
与 EKS Pod 身份一起使用的 IAM 角色必须允许
pods.eks.amazonaws.com服务主体代入这些角色并设置会话标签。以下是允许 EKS Pod 身份使用 IAM 角色的角色信任策略示例:
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ], "Condition": { "StringEquals": { "aws:SourceOrgId": "${aws:ResourceOrgId}" } } } ] }
AWS 建议使用条件密钥aws:SourceOrgId来帮助防范跨服务混乱的代理问题。在上面的角色信任策略示例中,ResourceOrgId是一个变量,等于 AWS 账户所属的 AWS 组织的 AWS 组织组织 ID。EKS 传入的值aws:SourceOrgId等于在 EKS Pod Identities 中扮演角色时的值。
ABAC 和 EKS Pod 身份
当 EKS Pod 身份担任 IAM 角色时,它会设置以下会话标签:
| EKS Pod 身份会话标签 | 值 |
|---|---|
|
kubernetes-命名空间 |
与 EKS Pod 身份关联的 pod 在其中运行的命名空间。 |
|
kubernetes-服务账号 |
与 EKS Pod 身份关联的 kubernetes 服务账户的名称 |
|
eks-cluster-arn |
EKS 集群的 ARN,例如 |
|
eks-cluster-name |
EKS 集群的名称。请注意,您的 AWS 账户中的 EKS 集群名称可以相同,其他 AWS 账户中的 EKS 集群名称可以相同。 |
|
kubernetes-pod 名称 |
EKS 中 pod 的名称。 |
|
kubernetes-pod-uid |
EKS 中 pod 的 UID。 |
这些会话标签允许您使用基于属性的访问控制 (ABAC) 仅向特定的 kubernetes 服务账户授予对您的 AWS 资源的访问权限。这样做时,务必要了解 kubernetes 服务账户仅在命名空间中是唯一的,而 kubernetes 命名空间仅在 EKS 集群中是唯一的。可以使用aws:PrincipalTag/<tag-key>全局条件密钥在 AWS 策略中访问这些会话标签,例如 aws:PrincipalTag/eks-cluster-arn
例如,如果您只想授予特定服务账户的访问权限,以便通过 IAM 或资源策略访问您账户中的 AWS 资源,则需要检查eks-cluster-arn和kubernetes-namespace标记,并确保只有目标集群中的服务账户才能访问该资源,就像其他集群可能拥有的相同kubernetes-service-accounts和一样kubernetes-namespaces。kubernetes-service-account
此示例 S3 存储桶策略仅在eks-cluster-arn所有对象均满足预期值时才授予对其所连接的 S3 存储桶中对象的访问权限,其中 EKS 集群托管在 AWS 账户中111122223333。kubernetes-service-account kubernetes-namespace
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111122223333:root" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::ExampleBucket/*" ], "Condition": { "StringEquals": { "aws:PrincipalTag/kubernetes-service-account": "s3objectservice", "aws:PrincipalTag/eks-cluster-arn": "arn:aws:eks:us-west-2:111122223333:cluster/ProductionCluster", "aws:PrincipalTag/kubernetes-namespace": "s3datanamespace" } } } ] }
EKS Pod 身份与 IRSA 的比较
EKS Pod 身份和 IRSA 都是向 EKS Pod 提供临时 AWS 证书的首选方式。除非你有 IRSA 的具体用例,否则我们建议你在使用 EKS 时使用 EKS Pod 身份。此表有助于比较这两个功能。
| # | EKS 容器组身份 | IRSA |
|---|---|---|
|
需要权限才能在您的 AWS 账户中创建 OIDC IDP? |
否 |
是 |
|
需要为每个集群设置唯一的 IDP |
否 |
是 |
|
设置与 ABAC 一起使用的相关会话标签 |
是 |
否 |
|
需要 iam: PassRole Check? |
是 |
否 |
|
使用您的 AWS 账户中的 AWS STS 配额? |
否 |
是 |
|
可以访问其他 AWS 账户 |
通过角色链间接实现 |
直接使用 sts:AssumeRoleWithWebIdentity |
|
与 AWS 开发工具包兼容 |
支持 |
是 |
|
节点上需要 Pod Identity Agent Daemonset 吗? |
是 |
否 |
EKS pod 的身份和凭证建议
更新 aws-node 守护程序集以使用 IRSA
目前,aws-node 守护程序集配置为使用分配给 EC2 实例的角色为 pod 分配 IP。该角色包括多个 AWS 托管策略,例如 Amazoneks_CNI_PolicyEC2ContainerRegistryReadOnly ,这些策略实际上允许在节点上运行的所有容器访问 attach/detach ENI、 assign/unassign IP 地址或从 ECR 提取镜像。由于这会给您的集群带来风险,因此建议您更新 aws-node 守护程序集以使用 IRSA。可以在本指南的存储库中找到执行此操作
在 v1.15.5 及更高版本中,aws-node 守护程序集支持 EKS Pod 身份。
限制访问分配给工作节点的实例配置文件
当你使用 IRSA 或 EKS Pod 身份时,它会更新容器的凭证链,使其首先使用 IRSA 或 EKS Pod 身份,但是,容器仍然可以继承分配给工作节点的实例配置文件的权限。对于不需要这些权限的 pod,您可以封锁对实例元数据的访问权限,以帮助确保您的应用程序仅具有所需的权限,而不是其节点。
警告
阻止对实例元数据的访问将阻止不使用 IRSA 或 EKS Pod 身份的 Pod 继承分配给工作节点的角色。
您可以通过要求实例仅使用 IMDSv2 并将跳数更新为 1 来阻止对实例元数据的访问,如下例所示。您也可以将这些设置包含在节点组的启动模板中。不要禁用实例元数据,因为这会阻止节点终止处理程序和其他依赖实例元数据的组件正常工作。
$ aws ec2 modify-instance-metadata-options --instance-id <value> --http-tokens required --http-put-response-hop-limit 1 ...
如果您使用 Terraform 创建用于托管节点组的启动模板,请添加元数据块以配置跳数,如以下代码片段所示:
tf hl_lines="7" resource "aws_launch_template" "foo" { name = "foo" … metadata_options { http_endpoint = "enabled" http_tokens = "required" http_put_response_hop_limit = 1 instance_metadata_tags = "enabled" } …
您还可以通过操作节点上的 iptables 来阻止 pod 对 EC2 元数据的访问。有关此方法的更多信息,请参阅限制对实例元数据服务的访问权限。
如果您的应用程序使用不支持 IRSA 或 EKS Pod 身份的旧版 AWS 开发工具包,则应更新软件开发工具包版本。
将 IRSA 角色的 IAM 角色信任策略的范围限定为服务账户名称、命名空间和集群
信任策略可以限定为命名空间或命名空间中的特定服务帐号。使用 IRSA 时,最好通过包括服务帐号名称来尽可能明确地制定角色信任政策。这将有效地防止同一命名空间中的其他 Pod 担任该角色。当您使用 CLI eksctl 创建服务 accounts/IAM 角色时,它会自动执行此操作。有关更多信息,请参阅https://eksctl.io/usage/iamserviceaccounts/。
直接与 IAM 合作时,这是在角色的信任策略中添加条件,该策略使用条件来确保:sub声明是您期望的命名空间和服务账户。举个例子,之前我们有一个IRSA代币,其子声明为 “系统:服务账户:默认:s3-只读”。这是default命名空间,服务帐号是s3-read-only。您将使用如下条件来确保只有集群中给定命名空间中的服务账户才能担任该角色:
"Condition": { "StringEquals": { "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:aud": "sts.amazonaws.com", "oidc.eks.us-west-2.amazonaws.com/id/D43CF17C27A865933144EA99A26FB128:sub": "system:serviceaccount:default:s3-read-only" } }
为每个应用程序使用一个 IAM 角色
对于 IRSA 和 EKS Pod Identity,最佳做法是为每个应用程序提供自己的 IAM 角色。这为您提供了更好的隔离性,因为您可以修改一个应用程序而不影响另一个应用程序,并允许您通过仅向应用程序授予所需的权限来应用最低权限原则。
将 ABAC 与 EKS Pod Identity 结合使用时,您可以在多个服务账户中使用通用的 IAM 角色,并依靠其会话属性进行访问控制。这在大规模运营时尤其有用,因为 ABAC 允许您使用更少的 IAM 角色进行操作。
当您的应用程序需要访问 IMDS 时,使用 IMDSv2 并将 EC2 实例的跳数限制提高到 2
IMDSv2 要求您使用 PUT 请求来获取会话令牌。初始 PUT 请求必须包含会话令牌的 TTL。较新版本的 AWS 开发工具包将自动处理此问题并自动续订所述令牌。还必须注意,为了防止 IP 转发,EC2 实例的默认跳数限制被故意设置为 1。因此,请求在 EC2 实例上运行的会话令牌的 Pod 最终可能会超时并退回到使用 IMDSv1 数据流的状态。EKS 通过启用 v1 和 v2 并将由 eksctl 或官方模板配置的节点上的跳数限制更改为 2 来增加对 IMDSv2 的支持。 CloudFormation
禁用服务帐号令牌的自动挂载
如果您的应用程序不需要调用 Kubernetes API,请将应用程序false中的automountServiceAccountToken属性设置为,或者修补每个命名空间中的默认服务账户,使其不再自动挂载到 pod 上。 PodSpec例如:
kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'
为每个应用程序使用专用服务帐户
每个应用程序都应有自己的专用服务帐户。这适用于 Kubernetes API 的服务账户以及 IRSA 和 EKS Pod Identity。
重要
如果您在使用 IRSA 时采用集群升级 blue/green 方法而不是就地进行集群升级,则需要使用新集群的 OIDC 终端节点更新每个 IRSA IAM 角色的信任策略。 blue/green 集群升级是指在旧集群旁边创建一个运行更新版本的 Kubernetes 的集群,并使用负载均衡器或服务网格将流量从在旧集群上运行的服务无缝转移到新集群。将 blue/green 集群升级与 EKS Pod Identity 结合使用时,您将在新集群中的 IAM 角色和服务账户之间创建 pod 身份关联。如果您有sourceArn条件,请更新 IAM 角色信任政策。
以非 root 用户身份运行应用程序
默认情况下,容器以 root 用户身份运行。虽然这允许他们读取 Web 身份令牌文件,但以 root 身份运行容器不被视为最佳做法。作为替代方案,可以考虑将该spec.securityContext.runAsUser属性添加到 PodSpec。的值runAsUser是任意值。
在以下示例中,Pod 中的所有进程都将在runAsUser字段中指定的用户 ID 下运行。
apiVersion: v1 kind: Pod metadata: name: security-context-demo spec: securityContext: runAsUser: 1000 runAsGroup: 3000 containers: - name: sec-ctx-demo image: busybox command: [ "sh", "-c", "sleep 1h" ]
当您以非 root 用户身份运行容器时,它会阻止容器读取 IRSA 服务帐户令牌,因为默认情况下为该令牌分配了 0600 [root] 权限。如果你更新容器的安全上下文以包含 fsgroup=65534 [Nobody],它将允许容器读取令牌。
spec: securityContext: fsGroup: 65534
在 Kubernetes 1.19 及更高版本中,不再需要进行此更改,应用程序无需将其添加到 Nobody 组即可读取 IRSA 服务账户令牌。
授予对应用程序的最低权限访问权限
Action Hero
考虑为用于 IRSA 和 Pod 身份的 IAM 角色设置权限边界。您可以使用权限边界来确保 IRSA 或 Pod Identities 使用的角色不能超过最大权限级别。有关使用权限边界策略示例入门权限边界的示例指南,请参阅此 github 存储库
查看并撤消对您的 EKS 集群的不必要匿名访问权限
理想情况下,应禁用所有 API 操作的匿名访问。匿名访问权限是通过为 Kubernetes 内置用户ClusterRoleBinding 系统创建 RoleBinding 或来授予的:匿名。您可以使用 rbac-lookup
./rbac-lookup | grep -P 'system:(anonymous)|(unauthenticated)' system:anonymous cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:discovery system:unauthenticated cluster-wide ClusterRole/system:public-info-viewer
任何角色或除 system: public-info-viewer 之外 ClusterRole 的任何角色都不应绑定到系统:匿名用户或 system: unauthenticated 群组。
启用对特定 API 的匿名访问可能有一些正当理由。如果您的集群是这种情况,请确保匿名用户只能访问这些特定的 API,并且在未经身份验证的情况下暴露这些 API 不会使您的集群容易受到攻击。
在 Kubernetes/EKS 版本 1.14 之前,默认情况下,system: unauthenticated 组与 system: discovery 和 system: basic-user 相关联。 ClusterRoles 请注意,即使您已将集群更新到 1.14 或更高版本,这些权限仍可能在您的集群上启用,因为集群更新不会撤消这些权限。要检查除了 system: public-info-viewer 之外哪些ClusterRoles 有 “系统:未验证”,你可以运行以下命令(需要 jq util):
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | .metadata.name'
而且,可以使用以下方法从除 “system: public-info-viewer” 之外的所有角色中删除 “系统:未经身份验证”:
kubectl get ClusterRoleBinding -o json | jq -r '.items[] | select(.subjects[]?.name =="system:unauthenticated") | select(.metadata.name != "system:public-info-viewer") | del(.subjects[] | select(.name =="system:unauthenticated"))' | kubectl apply -f -
或者,你可以通过 kubectl describe 和 kubectl edit 手动检查并删除它。要检查 system: unauthenticated 组在您的集群上是否具有 system: discovery 权限,请运行以下命令
kubectl describe clusterrolebindings system:discovery Name: system:discovery Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:discovery Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated
要检查 system: unauthenticated 群组在您的集群上是否具有 system: basic-user 权限,请运行以下命令:
kubectl describe clusterrolebindings system:basic-user Name: system:basic-user Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true Role: Kind: ClusterRole Name: system:basic-user Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated Group system:unauthenticated
如果 system: unauthenticated 组绑定到集群 ClusterRoles 上的 system: discovery s and/or ystem: basic-user,则应取消这些角色与 system: unauthenticated ClusterRoleBinding 使用以下命令编辑 system: discovery:
kubectl edit clusterrolebindings system:discovery
上面的命令将在编辑器中打开 system: discovery ClusterRoleBinding 的当前定义,如下所示:
# Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2021-06-17T20:50:49Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery resourceVersion: "24502985" selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/system%3Adiscovery uid: b7936268-5043-431a-a0e1-171a423abeb6 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:discovery subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:authenticated - apiGroup: rbac.authorization.k8s.io kind: Group name: system:unauthenticated
从上述编辑器屏幕的 “主题” 部分中删除 system: unauthenticated 群组的条目。
对 system: ClusterRoleBinding basic-user 重复相同的步骤。
与 IRSA 重复使用 AWS 开发工具包会话
当您使用 IRSA 时,使用 AWS 开发工具包编写的应用程序使用传送到您的 pod 的令牌sts:AssumeRoleWithWebIdentity来调用生成临时 AWS 证书。这与其他 AWS 计算服务不同,在其他 AWS 计算服务中,计算服务直接向 AWS 计算资源(例如 lambda 函数)提供临时 AWS 证书。这意味着每次初始化 AWS 开发工具包会话时,都会调用 AWS STS AssumeRoleWithWebIdentity 的。如果您的应用程序快速扩展并初始化了许多 AWS SDK 会话,您可能会受到 AWS STS 的限制,因为您的代码会调用很多次。AssumeRoleWithWebIdentity
为避免这种情况,我们建议在您的应用程序中重复使用 AWS SDK 会话,以AssumeRoleWithWebIdentity免对进行不必要的调用。
在以下示例代码中,使用 boto3 python 开发工具包创建了一个会话,该会话用于创建客户端并与 Amazon S3 和 Amazon SQS 进行交互。AssumeRoleWithWebIdentity仅调用一次,AWS 开发工具包将在证书过期my_session时自动刷新证书。
import boto3 = Create your own session my_session = boto3.session.Session() = Now we can create low-level clients from our session sqs = my_session.client('`sqs`') s3 = my_session.client('`s3`') s3response = s3.list_buckets() sqsresponse = sqs.list_queues() #print the response from the S3 and SQS APIs print("`s3 response:`") print(s3response) print("`—`") print("`sqs response:`") print(sqsresponse)
如果您要将应用程序从其他 AWS 计算服务(例如 EC2)迁移到使用 IRSA 的 EKS,这是一个特别重要的细节。在其他计算服务上,除非您指示,否则初始化 AWS SDK 会话不会调用 AWS STS。
替代方法
虽然 IRSA 和 EKS Pod 身份是向 pod 分配 AWS 身份的首选方式,但它们要求您在应用程序中加入最新版本的 AWS 开发工具包。有关目前支持 IRSA 的软件开发工具包的完整列表,请参阅https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html,对于 EKS Pod 身份,请参阅https://docs.aws.amazon.com/eks/latest/userguide/pod-id-minimum-sdk.html.如果您的应用程序无法使用兼容的软件开发工具包立即更新,则有几种社区构建的解决方案可用于为 Kubernetes 容器分配 IAM 角色,包括 kube2iam 和 kiam。https://github.com/jtblin/kube2iam
如果您需要使用这些非 AWS 提供的解决方案之一,请进行尽职调查,并确保您了解这样做的安全影响。