amazon-web-services - 设置 EKS 集群后出现错误“调用 AssumeRole 操作时发生错误 (AccessDenied):访问被拒绝”
问题描述
我已经使用 AWS 控制台创建了 EKS 集群,在创建集群时我使用了预先创建的 VPC 和子网,我创建了一个角色eks-role
,该角色具有AmazonEKSClusterPolicy
并附AmazonEKSServicePolicy
加到它。
我kubeconfig
使用以下方法添加了文件:
aws eks update-kubeconfig --name eks-cluster --role-arn "arn:aws:iam::############:role/eks-role"
当我使用kubectl get svc
命令时,我得到的错误是:
调用 AssumeRole 操作时发生错误 (AccessDenied):访问被拒绝
我不知道这可能有什么问题。
在我的用户中,我添加了一个策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::############:role/eks-role"
}
]
}
在角色中,我添加了信任关系:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::############:user/test"
},
"Action": "sts:AssumeRole"
}
]
}
我的~/.aws/credentials
文件如下所示:
**[default]**
aws_access_key_id = ##############
aws_secret_access_key = #############################
region=us-west-1
**[test]**
aws_access_key_id = ###########
aws_secret_access_key = #############################
region=ap-southeast-1
**[eks]**
role_arn = arn:aws:iam::##########:role/eks-role
source_profile = test
解决方案
我确信问题已经解决,但我会在此处提供更多信息,因此如果其他人仍然面临问题,那么他们可能不会像我一样浪费时间并使用这些步骤。
当我们通过 CloudFormation/CLI/EKSCTL 以任何方法创建 EKS 集群时,创建集群的 IAM 角色/用户将自动绑定到默认的 kubernetes RBAC API 组system:masters
(https://kubernetes.io/docs/reference/access-authn -authz/rbac/#user-facing-roles),这样集群的创建者将获得对集群的管理员访问权限。尽管我们始终可以使用 aws-auth 文件向其他 IAM 用户/角色授予访问权限,但为此我们必须使用创建集群的 IAM 用户/角色。
CreateCluster"
要验证 EKS 集群的角色/用户,我们可以在 cloudtrail 上搜索Api 调用,它会在sessionIssuer
字段部分中告诉我们集群的创建者arn
( https://docs.aws.amazon.com/awscloudtrail/latest /userguide/view-cloudtrail-events.html)。
当我们使用 IAM 角色或 IAM 用户创建集群时,当我们使用与用户相比的角色创建集群时,设置 EKS 集群的访问权限将变得有点棘手。
在设置对 EKS 集群的访问权限时,我将针对每种不同的方法列出我们可以遵循的步骤。
场景 1:使用 IAM 用户创建集群(例如“eks-user”)
通过运行命令确认已在创建集群的 AWS cli 上正确设置了 IAM 用户凭证aws sts get-caller-identity
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxxx",
"UserId": "xxxxxxxxxxxxxxxxxxxxx",
"Arn": "arn:aws:iam::xxxxxxxxxxx:user/eks-user"
}
之后使用以下命令更新 kubeconfig 文件
aws eks --region region-code update-kubeconfig --name cluster_name
通过上述命令附加配置文件后的外观。除非必要,否则请不要直接编辑此文件。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: CERT
server: https://xxxxxxx.sk1.us-east-1.eks.amazonaws.com
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
contexts:
- context:
cluster: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
current-context: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- --region
- us-east-1
- eks
- get-token
- --cluster-name
- eks-cluster
command: aws
完成上述设置后,您应该能够运行 kubectl 命令。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xxx.xx.x.x <none> 443/TCP 12d
场景 2:使用 IAM 角色创建集群(例如“eks-role”)
当通过 IAM 角色创建集群时,主要有四种不同的方式可以通过 cli 设置访问。
1.直接在kubeconfig文件中设置角色。
在这种情况下,我们不必在运行 kubectl 命令之前通过 cli 手动进行任何假设角色 api 调用,因为这将通过aws/aws-iam-authenticator
kube 配置文件中的设置自动完成。
假设现在我们正在尝试为用户设置访问权限,eks-user
首先确保用户确实有权担任该角色eks-role
将承担角色权限添加到eks-user
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::xxxxxxxxxxx:role/eks-role"
}
]
}
编辑角色上的信任关系,使其允许代eks-user
入该角色。
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxx:user/eks-user"
},
"Action": "sts:AssumeRole"
}
]
}
通过运行命令确认已在创建集群的 AWS cli 上正确设置了 IAM 用户凭证aws sts get-caller-identity
。重要的是要记住它应该向我们展示 IAM 用户 ARN,而不是 IAM 假定的 ROLE ARN。
$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxxx",
"UserId": "xxxxxxxxxxxxxxxxxxxxx",
"Arn": "arn:aws:iam::xxxxxxxxxxx:user/eks-user"
}
之后使用以下命令更新 kubeconfig 文件
aws eks --region region-code update-kubeconfig --name cluster_name --role-arn arn:aws:iam::xxxxxxxxxxx:user/eks-role
通过上述命令附加配置文件后的外观。除非必要,否则请不要直接编辑此文件。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: CERT
server: https://xxxxxxx.sk1.us-east-1.eks.amazonaws.com
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
contexts:
- context:
cluster: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
current-context: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- --region
- us-east-1
- eks
- get-token
- --cluster-name
- eks-cluster
- --role
- arn:aws:iam::xxxxxxx:role/eks-role
command: aws
完成上述设置后,您应该能够运行 kubectl 命令。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xxx.xx.x.x <none> 443/TCP 12d
2. 如果您在 CLI 上设置了 AWS 配置文件 ( https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html ),并且您想将其与 kube 配置一起使用。
确认配置文件设置正确,以便它可以使用凭据eks-user
$ cat ~/.aws/config
[default]
output = json
region = us-east-1
[eks]
output = json
region = us-east-1
[profile adminrole]
role_arn = arn:aws:iam::############:role/eks-role
source_profile = eks
$ cat ~/.aws/credentials
[default]
aws_access_key_id = xxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[eks]
aws_access_key_id = xxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
完成此配置文件配置后,请通过运行命令确认配置文件配置正常aws sts get-caller-identity --profile eks
$ aws sts get-caller-identity --profile eks
{
"Account": "xxxxxxxxxxxx",
"UserId": "xxxxxxxxxxxxxxxxxxxxx",
"Arn": "arn:aws:iam::xxxxxxxxxxx:user/eks-user"
}
之后使用下面的命令和配置文件更新 kubeconfig 文件,请确保我们没有在这里使用角色。
aws eks update-kubeconfig --name devel --profile eks
通过上述命令附加配置文件后的外观。除非必要,否则请不要直接编辑此文件。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: CERT
server: https://xxxxx.sk1.us-east-1.eks.amazonaws.com
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
contexts:
- context:
cluster: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
current-context: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- --region
- us-east-1
- eks
- get-token
- --cluster-name
- eks-cluster
command: aws
env:
- name: AWS_PROFILE
value: eks
完成上述设置后,您应该能够运行 kubectl 命令。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xxx.xx.x.x <none> 443/TCP 12d
3. 以任何其他方式承担角色,例如我们可以直接将IAM角色附加到实例。
如果角色直接附加到实例配置文件,那么我们可以按照我们在场景 1 中为 IAM 用户设置访问权限时所遵循的类似步骤进行操作
验证我们是否已将正确的角色附加到 EC2 实例,并且由于此实例配置文件的优先级最低,因此此步骤还将验证实例上没有任何其他凭据设置。
[ec2-user@ip-xx-xxx-xx-252 ~]$ aws sts get-caller-identity
{
"Account": "xxxxxxxxxxxx",
"UserId": "xxxxxxxxxxxxxxxxxxxxx:i-xxxxxxxxxxx",
"Arn": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/eks-role/i-xxxxxxxxxxx"
}
之后使用以下命令更新 kubeconfig 文件
aws eks --region region-code update-kubeconfig --name cluster_name
通过上述命令附加配置文件后的外观。除非必要,否则请不要直接编辑此文件。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: CERT
server: https://xxxxxxx.sk1.us-east-1.eks.amazonaws.com
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
contexts:
- context:
cluster: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
current-context: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- --region
- us-east-1
- eks
- get-token
- --cluster-name
- eks-cluster
command: aws
完成上述设置后,您应该能够运行 kubectl 命令。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xxx.xx.x.x <none> 443/TCP 12d
aws sts assume-role
4. 通过命令手动代入IAM角色。
eks-role
通过运行 cli 命令手动承担角色。
aws sts assume-role --role-arn arn:aws:iam::xxxxxxxxxxx:role/eks-role --role-session-name test
{
"AssumedRoleUser": {
"AssumedRoleId": "xxxxxxxxxxxxxxxxxxxx:test",
"Arn": "arn:aws:sts::xxxxxxxxxxx:assumed-role/eks-role/test"
},
"Credentials": {
"SecretAccessKey": "xxxxxxxxxx",
"SessionToken": xxxxxxxxxxx",
"Expiration": "xxxxxxxxx",
"AccessKeyId": "xxxxxxxxxx"
}
}
之后,使用上面输出中的值设置所需的环境变量,以便我们可以使用从会话生成的正确凭据。
export AWS_ACCESS_KEY_ID=xxxxxxxxxx
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxx
export AWS_SESSION_TOKEN=xxxxxxxxxx
之后,通过运行命令验证我们是否承担了 IAM 角色aws sts get-caller-identity
。
$ aws sts get-caller-identity { "Account": "xxxxxxxxxx", "UserId": "xxxxxxxxxx:test", "Arn": "arn:aws:sts::xxxxxxxxxx:assumed-role/eks-role/test " }
之后使用以下命令更新 kubeconfig 文件
aws eks --region region-code update-kubeconfig --name cluster_name
通过上述命令附加配置文件后的外观。除非必要,否则请不要直接编辑此文件。
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: CERT
server: https://xxxxxxx.sk1.us-east-1.eks.amazonaws.com
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
contexts:
- context:
cluster: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
current-context: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:xxxxxxx:cluster/eks-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args:
- --region
- us-east-1
- eks
- get-token
- --cluster-name
- eks-cluster
command: aws
完成上述设置后,您应该能够运行 kubectl 命令。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP xxx.xx.x.x <none> 443/TCP 12d
笔记:
我已经尝试在这里介绍主要用例,但可能还有其他用例需要我们设置对集群的访问。
此外,上述测试主要针对 EKS 集群的首次设置,上述方法均未触及 aws-auth configmap。但是,一旦您通过 aws-auth ( https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html ) 文件授予对 EKS 集群的其他 IAM 用户/角色的访问权限,您就可以使用这些用户也有相同的命令集。
推荐阅读
- react-native - 以平滑的方式更改 TextInput 的 fontSize
- ansible - Ansible 来自 /etc/ansible/hosts 的五个随机主机
- pandas - groupby pandas dataframe,取最新日期和最早日期的值之间的差异
- nginx - 404 时重定向到另一个站点
- kentico - 带有自定义查询的 Kentico 中继器
- sql-server - 将删除后触发器替换为代替触发器
- java - “Maven in 5 Minutes”教程中的原型插件错误
- batch-file - 创建一个使用文本文件验证同步两个文件夹的批处理文件
- composer-php - 如果 *condition*,PHP Composer 需要依赖项
- angular - Angular ngIf 无法访问父属性