如何解决 Amazon EKS 中 AWS SDK 工作负载的常见问题?

2 分钟阅读
0

我使用 AWS SDK 为 Amazon Elastic Kubernetes Service(Amazon EKS)开发了容器应用程序。尝试调用 AWS 服务时,出现错误。

解决方法

将使用 AWS SDK 的容器应用程序部署到 Amazon EKS 集群时,您可能会收到以下错误之一:

  • NoCredentialsError: 找不到凭证
  • EndpointConnectionError
  • ClientError: 出现错误(AccessDenied)
  • ClientError: 出现错误(UnauthorizedOperation)

具体的错误消息取决于您的应用程序使用的 AWS SDK 编程语言。请参阅以下故障排除步骤,解决遇到的错误。

找不到凭证

如果 Amazon EKS 找不到容器组的凭证,将显示类似于以下消息的错误:

“文件‘/usr/local/lib/python2.7/site-packages/botocore/auth.py’,第 315 行,在 add_auth 中
引发 NoCredentialsError
botocore.exceptions.NoCredentialsError: 找不到凭证”

没有配置容器组的凭证、没有正确配置凭证或者 AWS SDK 版本不受支持时,就会出现此错误。

要解决此错误,请使用 AWS Identity and Access Management(AWS IAM)角色。通常,在应用程序中或使用 Amazon EC2 实例的角色为 SDK 客户端创建和分发 AWS 凭证,而将容器组配置为使用服务账户的 IAM 角色。将 IAM 角色与 Kubernetes 服务账户相关联,然后将容器组配置为使用该服务账户。

**重要事项:**容器组的容器必须使用支持通过 OpenID Connect Web 身份令牌文件代入 IAM 角色的 AWS SDK 版本

无法连接到端点 URL

如果容器组无法与 AWS 服务端点通信,则会显示类似于以下消息的错误:

“文件‘/usr/local/lib/python2.7/site-packages/botocore/retryhandler.py’,第 359 行, _check_caught_exception 中
引发 caught_exception
botocore.exceptions.EndpointConnectionError: 无法连接到端点 URL:‘https://ec2.eu-west-1.amazonaws.com/’
botocore.exceptions.EndpointConnectionError: 无法连接到端点 URL:‘https://sts.eu-west-1.amazonaws.com/’”

要解决此错误,请排查 DNS 问题并确认以下几点:

检查 CoreDNS 容器组是否在集群中运行

运行以下命令:

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o wide

您会看到类似于以下示例的输出结果:

NAME                       READY   STATUS    RESTARTS   AGE   IP                NODE                                            NOMINATED NODE   READINESS GATES  
coredns-7f85bf9964-kz8lp   1/1     Running   0          15d   192.168.100.36    ip-192-168-101-156.eu-west-1.compute.internal   <none>           <none>  
coredns-7f85bf9964-wjxvb   1/1     Running   0          15d   192.168.135.215   ip-192-168-143-137.eu-west-1.compute.internal   <none>           <none>

确保 Amazon EKS 集群中运行的 Worker 节点具有足够的容量,以便成功运行 CoreDNS 容器组。

测试端点解析

验证 CoreDNS 容器组和应用程序容器组是否可以解析希望容器组调用的 AWS 服务端点。运行以下命令:

nslookup SERVICE_ENDPOINT  

nslookup ec2.eu-west-1.amazonaws.com  

nslookup ec2.amazonaws.com

**注意:**将 SERVICE_ENDPOINT 替换为错误消息中输出的端点。

调用 AssumeRoleWithWebIdentity 操作时出错(AccessDenied)

如果容器组无法请求临时安全凭证,则会显示类似于以下消息的错误:

“文件‘/usr/local/lib/python3.11/site-packages/botocore/client.py’,第 960 行, _make_api_call 中
引发 error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: 调用 AssumeRoleWithWebIdentity 操作时出错(AccessDenied): 无权执行 sts:AssumeRoleWithWebIdentity”

要解决此错误,请完成以下步骤:

确认代入的 IAM 角色

确认容器组代入与集群中存在的 Kubernetes 服务账户关联的 IAM 角色。否则,容器组代入 Amazon EKS 节点 IAM 角色。要获取服务账户的 IAM 角色 ARN,请运行以下命令:

kubectl get serviceaccount -A  

kubectl describe serviceaccount serviceaccount_name -n namespace_name | grep -i arn

**注意:**将 serviceaccount_namenamespace_name 替换为您自己的值。

您会看到类似于以下示例的输出结果:

Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::11112222333:role/AccessEC2role

查看 CloudTrail 事件

验证哪个 IAM 身份被拒绝访问,无法执行 AssumeRoleWithWebIdentity actionView。要执行此操作,请在 CloudTrail 控制台中查看 AWS CloudTrail 事件。

  1. 登录 CloudTrail 控制台
  2. 在导航窗格中,选择事件历史记录
  3. 查找属性下拉菜单中,将选择从只读更改为事件名称
  4. 输入事件名称搜索栏中,输入 AssumeRoleWithWebIdentity。检查内容窗格中显示的事件列表。请参阅被拒绝事件的以下示例:
{  
    "eventVersion": "1.08",  
    "userIdentity": {  
        "type": "WebIdentityUser",  
        "userName": "system:serviceaccount:serverless:aws-sdk"  
    },  
    "eventName": "AssumeRoleWithWebIdentity",  
    "errorCode": "AccessDenied",  
    "errorMessage": "An unknown error occurred",  
    "requestParameters": {  
        "roleArn": "arn:aws:iam::11112222333:role/AccessEC2role",  
        "roleSessionName": "botocore-session-1675698641"  
    }  
}

在此输出中,roleArn 必须与您为容器组的服务账户配置的 IAM 角色相同。
userNamesystem:serviceaccount:serverless:aws-sdk)必须与服务账户名称及其命名空间相匹配。此名称的格式为 system:serviceaccount:namespace:serviceaccount_name

配置容器组的服务账户 IAM 角色

IAM 控制台中,使用正确的 IAM 信任策略语句配置容器组的服务账户 IAM 角色:

     {  
            "Effect": "Allow",  
            "Principal": {  
                "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD"  
            },  
            "Action": "sts:AssumeRoleWithWebIdentity",  
            "Condition": {  
                "StringEquals": {  
                    "oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD:sub": "system:serviceaccount:namespace_name:serviceaccount_name",  
                    "oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD:aud": "sts.amazonaws.com"  
                }  
            }  
    }     

**注意:**将 region_codeACCOUNT_IDEXAMPLE11111122222333334444ABCDserviceaccount_namenamespace_name 替换为您自己的值。

出现错误(UnauthorizedOperation)

为容器组的服务账户配置的 IAM 角色可能无权调用其他 AWS 服务。在这种情况下,会显示类似于以下消息的错误:

文件“/usr/local/lib/python3.11/site-packages/botocore/client.py”,第 960 行, _make_api_call 中
引发 error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: 调用 DescribeInstances 操作时出错(UnauthorizedOperation): 您无权执行此操作。

要解决此错误,请完成以下步骤:

  1. 确认容器组代入与 Kubernetes 服务账户关联的 IAM 角色。要执行此操作,请参阅上一部分确认代入的 IAM 角色。记下此步骤返回的角色 ARN。
  2. 打开 IAM 控制台。在导航窗格中,选择角色。然后,搜索并选择步骤 1 中的角色 ARN。
  3. 权限选项卡下,将必要的 IAM policy 权限附加到 IAM 角色。

有关示例容器组,请参阅 GitHub 上的运行 AWS Python SDK 并将 Web 联合身份提供者作为凭证提供者的示例容器组

AWS 官方
AWS 官方已更新 1 年前