启用IMDSv2时Spark应用无法加载AWS凭证问题求助
问题:启用IMDSv2后Spark无法通过EC2实例角色访问S3
场景与错误
- 在EC2实例上运行Spark 3.4.1应用,通过附加实例角色、配置Spark使用IAM角色的方式访问S3,无需硬编码访问密钥,该方式在IMDSv1下正常工作。
- 启用IMDSv2后,执行
spark.read.json("s3a://bucket/data*").count()时抛出错误:com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain - 已尝试将
aws-java-sdk及aws-java-sdk-bundle更新至1.12.599版本,问题仍未解决。 - 需求:在启用IMDSv2的前提下正常读取S3数据。
解决方案
1. 配置Spark支持IMDSv2的凭证获取
在Spark配置中添加以下参数,强制使用支持IMDSv2的实例角色凭证提供器:
# 指定凭证提供器 spark.hadoop.fs.s3a.aws.credentials.provider=com.amazonaws.auth.InstanceProfileCredentialsProvider # 启用IMDSv2支持 spark.hadoop.fs.s3a.imdsv2.enabled=true
也可以在提交作业时通过--conf参数传递:
spark-submit \ --conf spark.hadoop.fs.s3a.aws.credentials.provider=com.amazonaws.auth.InstanceProfileCredentialsProvider \ --conf spark.hadoop.fs.s3a.imdsv2.enabled=true \ --class your.main.Class \ your-app.jar
2. 检查EC2实例的IMDSv2配置
- 确认实例的IMDSv2配置:执行以下AWS CLI命令查看,确保
HttpTokens为required,HttpPutResponseHopLimit至少为1(若Spark运行在容器内,需设置为2或更高):aws ec2 describe-instances --instance-ids <你的实例ID> --query 'Reservations[*].Instances[*].MetadataOptions' - 若
HttpPutResponseHopLimit值过低,可通过以下命令更新:aws ec2 modify-instance-metadata-options --instance-id <你的实例ID> --http-put-response-hop-limit 2 --http-tokens required
3. 解决依赖冲突问题
Spark自带的旧版本AWS SDK可能与你引入的1.12.599版本冲突:
- 检查Spark安装目录下的
jars文件夹,移除所有旧版本的aws-java-sdk-*.jar和aws-java-sdk-bundle-*.jar,仅保留你指定的1.12.599版本文件。 - 通过
spark-shell --verbose命令查看加载的依赖列表,确认AWS SDK版本正确。
4. 手动验证IMDSv2可用性
在EC2实例上执行以下命令,验证是否能正常获取IMDSv2会话令牌和实例角色信息:
# 获取会话令牌(有效期6小时) TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") # 获取实例关联的IAM角色名称 curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/
若能返回角色名称,说明IMDSv2配置正常;否则需检查实例是否正确附加了IAM角色,以及实例的网络策略是否允许访问IMDS端点。
内容的提问来源于stack exchange,提问作者Samba shiva
相关产品推荐
相关产品推荐

