You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:06:25