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

AWS EC2子进程随机报Unable to locate credentials问题求助

赏金说明

我已找到临时解决方法,详见我的回答。
但仍有两点疑问:

  • 下述脚本在哪个环节被限流——调用IMDS时?还是IMDS调用STS时?
  • 为何将凭证从父进程传递给子进程无效?似乎限流并非发生在凭证请求阶段,而是后续环节,比如「验证通过环境变量传递的凭证」等。

回答任意一个问题即可获得赏金,若能提供文档/源码参考更佳。

请勿建议改用Python或其他语言重写,此不在本问题讨论范围内

原始问题

我有一台配备96 vCPU的AWS EC2主机,执行以下脚本:该脚本会异步启动子进程(数量上限由脚本参数指定),每个子进程调用AWS CLI后退出。

#!/bin/bash

function f() {
 p=$1
 echo "$(date) entering f($p)"
 aws sts get-caller-identity
 echo "$(date) leaving f($p)"
}

a=""
for i in {1..400}; do
  a="$a
  $i"
done

jobs_limit=$1

while read line; do
    jobs=$(jobs -r | wc -l)
    while [ $jobs -ge $jobs_limit ]; do
      sleep 0.1
      jobs=$(jobs -r | wc -l)
    done
    echo "$(f $line)" &
done < <(echo "$a")

wait

**问题:**当子进程数量超过40时,部分进程会随机出现Unable to locate credentials. You can configure credentials by running "aws configure".错误。

以下是脚本在不同数量限制下的执行输出:

sh-4.2$ /tmp/b.sh 40 2>&1 | egrep 'Unable to locate credentials' | wc -l
0

sh-4.2$ /tmp/b.sh 40 2>&1 | egrep 'Unable to locate credentials' | wc -l
0

sh-4.2$ /tmp/b.sh 44 2>&1 | egrep 'Unable to locate credentials' | wc -l
22

sh-4.2$ /tmp/b.sh 44 2>&1 | egrep 'Unable to locate credentials' | wc -l
7

sh-4.2$ /tmp/b.sh 48 2>&1 | egrep 'Unable to locate credentials' | wc -l
18

sh-4.2$ /tmp/b.sh 48 2>&1 | egrep 'Unable to locate credentials' | wc -l
14

如上述结果所示,当限制为40时无错误,超过40则会出现随机数量的错误。

有人能解释这是怎么回事吗?


我曾猜测是调用/metadata端点获取凭证时遇到了速率限制,因此修改脚本在父进程中获取凭证并传递给子进程,但问题依然存在:

function f() {
 p=$1
 cc=$2
 echo "$(date) entering f($p)"
  k=$(echo $cc | jq .AccessKeyId -r)
  s=$(echo $cc | jq .SecretAccessKey -r)
  t=$(echo $cc | jq .Token -r)
  AWS_ACCESS_KEY_ID=$k AWS_SECRET_ACCESS_KEY=$s AWS_SESSION_TOKEN=$t aws sts get-caller-identity
 echo "$(date) leaving f($p)"
}

...

creds=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/EMRJobFlowRole)

...

   echo "$(f $line $creds)" &

...

问题解答

1. 限流发生在IMDS调用STS的环节

IMDS本身的请求速率限制(比如IMDSv2令牌获取默认是每秒1000次/实例)远高于当前并发量,不会触发。真正的瓶颈是STS服务:sts:GetCallerIdentity接口默认的账户级速率限制是每秒100次,当子进程并发数超过40后,大量并行请求会快速触达这个阈值,导致STS返回限流错误。此时IMDS无法从STS获取到有效临时凭证,AWS CLI就会抛出Unable to locate credentials的错误。

2. 传递凭证后仍无效的原因

即使在父进程获取凭证并传递给子进程,AWS CLI在使用临时凭证时,依然会自动尝试刷新凭证(哪怕当前凭证未过期)。大量子进程同时触发凭证刷新请求,同样会触达STS的速率限制,导致部分进程刷新失败,进而抛出凭证不存在的错误。此外,bash传递大变量(如完整的JSON凭证)时,偶尔会出现变量截断或传递异常,但从测试结果来看,核心原因还是后续STS调用的限流。

如果要验证,可以给aws sts get-caller-identity添加--debug参数,日志中会明确显示STS请求被限流的报错信息。

内容的提问来源于stack exchange,提问作者Alexander Pavlov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:09:55