如何在K8s Job的Go应用中用SA绑定的IAM角色通过AWS SDK Go v2访问S3?
问题描述
我在K8s Job运行的Go应用中,尝试通过ServiceAccount关联IAM角色调用S3的PutObject接口,已完成以下配置:
- Job YAML中指定了
serviceAccountName字段,对应ServiceAccount已创建且包含正确注解:Name: identity Namespace: identity Labels: app=identity Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<acct-id>:role/identity-s3-role-dev Image pull secrets: <none> Mountable secrets: identity-token-bf2wz Tokens: identity-token-bf2wz Events: <none> - 执行
kubectl describe pod <name>验证Pod已获取正确环境变量与挂载:AWS_REGION: us-east-1 AWS_ROLE_ARN: arn:aws:iam::<id>:role/identity-s3-role-dev AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token Mounts: /var/run/secrets/eks.amazonaws.com/serviceaccount from aws-iam-token (ro) /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7rx85 (ro) - 已确认identity-s3-role-dev角色具备目标S3存储桶的访问权限
但调用S3 PutObject时出现400错误,提示认证头格式错误,未携带有效凭证:
panic: operation error S3: PutObject, https response error StatusCode: 400, RequestID: 4TFT6G0T08547RBQ, HostID: r2+1NduQf+v4F1gL/AlERLrNtJR1jeI9mIL7oKoWUFLvuY7lyq+Ug9ElK3YHvl5h8rsbgq/uRAw=, api error AuthorizationHeaderMalformed: The authorization header is malformed; a non-empty Access Key (AKID) must be provided in the credential.
我的Go代码使用AWS SDK v2,相关代码如下:
导入包:
import ( awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" )
配置加载与调用逻辑:
localconfig := load_config() // 通过viper加载本地配置 cfg, err := awsconfig.LoadDefaultConfig(context.TODO()) if err != nil { return nil, err } client = s3.NewFromConfig(cfg) input := &s3.PutObjectInput{ Body: manager.ReadSeekCloser(bytes.NewReader(b)), // b 为上传内容 Bucket: &localconfig.s3bucket, Key: &localconfig.s3key, } _, err = client.PutObject(context.TODO(), input)
根据AWS SDK文档,LoadDefaultConfig应自动加载Pod中ServiceAccount对应的凭证,但实际未生效,请问还需执行哪些步骤才能让请求使用指定的IAM角色凭证?
补充排查信息
修改配置加载代码,添加WithSharedConfigProfile("anything")参数后:
cfg, err := awsconfig.LoadDefaultConfig( context.TODO(), awsconfig.WithSharedConfigProfile("anything"), ) if err != nil { return nil, err }
400错误消失,但出现403错误:
operation error S3: GetObject, https response error StatusCode: 403, RequestID: 3H40VPYKAF64E0ZY, HostID: <long-id>, api error AccessDenied: Access Denied
此时发现应用使用的是节点角色arn:aws:iam::<acct-id>:role/node_group01-eks-node-group-20220420182829219400000001,而非目标角色identity-s3-role-dev,该节点角色无对应权限。无论WithSharedConfigProfile传入什么值,都会加载节点角色凭证,问题疑似出在Go SDK的凭证加载逻辑上。
内容的提问来源于stack exchange,提问作者kingledion
相关产品推荐
相关产品推荐

