【问题标题】:Getting error "An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied" after setting up EKS cluster设置 EKS 集群后出现错误“调用 AssumeRole 操作时发生错误 (AccessDenied):访问被拒绝”
【发布时间】:2019-07-03 05:37:55
【问题描述】:

我使用 AWS 控制台创建了 EKS 集群,在创建集群时我使用了我预先创建的 VPC 和子网,我创建了一个角色 eks-role,其中附加了 AmazonEKSClusterPolicyAmazonEKSServicePolicy

我添加了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

【问题讨论】:

  • 你解决了吗?
  • 我使用 eksctl 创建了 EKS 集群
  • 我也是。就我而言,问题是我创建集群时使用的帐户是共享帐户,而在本地我使用的是由该帐户创建的用户凭据。

标签: amazon-web-services amazon-eks


【解决方案1】:

我确信问题已经解决,但我会在此处提供更多信息,因此如果其他人仍然面临问题,那么他们可能不会像我一样浪费时间并使用这些步骤。

当我们通过 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 用户/角色。

要验证 EKS 集群的角色/用户,我们可以在 cloudtrail 上搜索 CreateCluster" Api 调用,它会在字段 arn (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/view-cloudtrail-events.html) 的 sessionIssuer 部分中告诉我们集群的创建者)。

当我们使用 IAM 角色或 IAM 用户创建集群时,当我们使用与用户相比的角色创建集群时,设置 EKS 集群的访问权限将变得有点棘手。

在设置对 EKS 集群的访问权限时,我将针对每种不同的方法列出我们可以遵循的步骤。

场景 1:使用 IAM 用户创建集群(例如“eks-user”)


通过运行aws sts get-caller-identity 命令确认已在创建集群的 AWS cli 上正确设置了 IAM 用户凭证

$ 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 调用,因为这将由 kube 配置文件中设置的 aws/aws-iam-authenticator 自动完成。

假设现在我们正在尝试为用户 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 sts get-caller-identity 确认已在创建集群的 AWS cli 上正确设置了 IAM 用户凭证。重要的是要记住它应该向我们展示 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

4.通过aws sts assume-role 命令手动代入 IAM 角色。

通过运行 cli 命令手动承担角色 eks-role

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

之后,通过运行命令 aws sts get-caller-identity 验证我们是否承担了 IAM 角色。

$ aws sts get-caller-identity { “帐户”:“xxxxxxxxxx”, "UserId": "xxxxxxxxx: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 用户/角色的访问权限,您也可以对这些用户使用相同的命令集。

【讨论】:

  • 我已经使用 eks_user 创建了 eks 集群,并使用 eks_role 的角色创建了 kubectl cli 服务器。但得到以下错误 ----- kubectl get svc error: You must be logged in to the server (Unauthorized) --- 请您帮忙解决它
  • 如果您使用用户创建了集群,则必须按照场景 1 中的步骤操作,不确定通过角色创建 kubectl cli 是什么意思,但无论如何如果集群是通过用户创建的,您将无法访问它第一次通过角色
  • kubectl cli via role > 意味着我已经创建了一个 CLI 服务器并将 ROLE 附加到服务器。从 AWS 前端创建的集群,附加到集群的角色
  • 附加到服务器的角色是否与创建 EKS 集群的角色相同?
  • 承担角色部分帮助我解决了问题!涵盖不同场景的超级答案!
猜你喜欢
  • 2021-04-13
  • 2018-07-12
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-08
  • 2021-09-23
相关资源
最近更新 更多