如何让Spark应用通过ServiceAccount生成的AWS会话令牌访问S3?
问题描述
我正尝试在Kubernetes上部署运行于小型YARN集群的Spark应用,目前尚未完成。通过ConfigMap中的配置文件配置Spark,该应用需将AWS S3桶作为默认文件系统(FS)。
在Kubernetes部署中,我使用了关联IAM角色ARN的服务账户(ServiceAccount),部署成功后环境变量如下:
AWS_DEFAULT_REGION=..... AWS_REGION=..... AWS_ROLE_ARN=...... AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token AWS_STS_REGIONAL_ENDPOINTS=regional
我希望Spark使用该文件中存储的会话令牌及角色名称,尝试用TemporaryAWSCredentialsProvider,但无法传递会话令牌,当前配置如下:
spark.hadoop.fs.s3a.aws.credentials.provider: org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider spark.hadoop.fs.s3a.session.token.file: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
配置无效,报错:
No AWS Credentials provided by TemporaryAWSCredentialsProvider : org.apache.hadoop.fs.s3a.CredentialInitializationException: Access key, secret key or session token is unset
请问如何传递该令牌?或有其他可行方案吗?
可行解决方案
方案一:使用WebIdentityTokenCredentialsProvider
TemporaryAWSCredentialsProvider不支持处理EKS的Web身份令牌场景,应该用专门的WebIdentityTokenCredentialsProvider,这是Hadoop AWS模块针对这类场景的实现。修改Spark配置如下:
spark.hadoop.fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.auth.WebIdentityTokenCredentialsProvider spark.hadoop.fs.s3a.web.identity.token.file=${env:AWS_WEB_IDENTITY_TOKEN_FILE} spark.hadoop.fs.s3a.web.identity.role.arn=${env:AWS_ROLE_ARN} spark.hadoop.fs.s3a.region=${env:AWS_REGION}
这个提供者会自动读取令牌文件内容,通过STS服务获取临时凭证,无需手动处理会话令牌。
方案二:利用AWS SDK默认凭证链
如果你的Hadoop和Spark版本支持,可直接依赖AWS SDK的默认凭证链,它会自动识别EKS服务账户的环境变量。只需设置:
spark.hadoop.fs.s3a.aws.credentials.provider=com.amazonaws.auth.DefaultAWSCredentialsProviderChain
默认凭证链会优先读取AWS_ROLE_ARN和AWS_WEB_IDENTITY_TOKEN_FILE环境变量,自动调用STS获取临时凭证,无需额外配置。
注意事项
- 确保hadoop-aws客户端版本≥3.3.0,
WebIdentityTokenCredentialsProvider在该版本后才稳定支持。 - 验证服务账户关联的IAM角色拥有足够的S3访问权限,比如
s3:ListBucket、s3:GetObject、s3:PutObject等。 - YARN集群容器需能访问STS服务,可通过配置VPC端点或打通网络实现,否则无法获取临时凭证。
内容的提问来源于stack exchange,提问作者JBoy
相关产品推荐
相关产品推荐

