EC2 绑定 IAM Role 后 SSM Agent 为什么不会立即上线
EC2 绑定 IAM Role 后 SSM Agent 为什么不会立即上线
给运行中的 EC2 实例附加包含 AmazonSSMManagedInstanceCore 的 Instance Profile 后,实例有时不会马上出现在 Systems Manager 中。等几分钟、重启 Agent,甚至等待接近半小时后又会自行恢复。
这通常不是 IAM 策略写错,而是控制面传播、Agent 凭证生命周期和失败退避共同造成的结果。理解这几层延迟后,就能避免反复解绑角色、重装 Agent 或修改网络。
四层延迟
1. Instance Profile 需要传播到 IMDS
调用 AssociateIamInstanceProfile 后,控制面需要把新角色传播到实例元数据服务。在 IMDS 仍返回空或 404 时,Agent 无法获得角色凭证,重启多少次都不会解决问题。
先使用 IMDSv2 验证:
TOKEN=$(curl -sS -X PUT \
-H 'X-aws-ec2-metadata-token-ttl-seconds: 21600' \
http://169.254.169.254/latest/api/token)
curl -sS \
-H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/只有返回角色名,才说明实例侧已经能看到 Instance Profile。
2. 凭证按生命周期中点刷新
SSM Agent 的 credential refresher 不会持续轮询新角色。源码中的 durationUntilRefresh() 会计算当前凭证生命周期,并在生命周期的 50% 处安排下一次刷新,设计思路类似 DHCP T1 定时器。
Core 进程把实例角色凭证视为至少 1 小时有效,因此正常主动刷新点约在 30 分钟;Worker 使用的有效期更短。若 Agent 仍持有旧凭证,它不会因为控制台刚换了角色就立即重新查询。
3. AccessDenied 会触发长退避
最容易误判的是 Agent 首次尝试时角色尚未传播,或角色还没有 SSM 权限。实例角色和 Default Host Management 两条凭证路径都失败后,认证授权类错误会进入长退避。
SSM Agent 源码中的 getLongSleepDuration() 会休眠约 25 分钟,并加入最多 5 分钟随机抖动。即使 IAM 在几秒后已经修好,正在休眠的 Agent 也不会提前醒来。
4. 运行时配置和进程缓存
Agent 会把凭证运行时信息保存在 identity_config.json 中,部分身份信息也有进程内缓存。删除运行时凭证缓存可以触发后台刷新,但只有重启 Agent 才能完整重建进程状态。
从日志判断当前卡在哪一层
Linux 默认日志位于:
sudo grep -iE \
'CredentialRefresher|credential|rotation|Sleeping|RemoteRetrieve|AccessDenied' \
/var/log/amazon/ssm/amazon-ssm-agent.log | tail -50常见日志含义:
| 日志 | 判断 |
|---|---|
Next credential rotation will be in ... | Agent 正在等待正常刷新点 |
Sleeping for ... before retrying | 凭证获取失败后退避 |
Credential config file missing | 缓存已删除,将触发刷新 |
Successfully connected with instance profile role credentials | Instance Profile 路径成功 |
Failed to connect ... instance profile role credentials | 角色凭证或权限验证失败 |
还可以运行 Agent 自带诊断:
sudo ssm-cli get-diagnostics推荐恢复顺序
第一步:确认 IMDS 已经出现角色
如果 IMDS 仍无角色,先等待传播完成。此时重启服务只会让 Agent 再次失败并重新进入退避。
第二步:刷新缓存
较新的 Agent 可以执行:
sudo ssm-cli flush-cached-credentials后台检查器会发现运行时配置缺失,并安排凭证刷新。旧版本没有该命令时,可先备份并删除缓存:
sudo cp -a /var/lib/amazon/ssm/runtimeconfig/identity_config.json \
/var/tmp/identity_config.json.backup 2>/dev/null || true
sudo rm -f /var/lib/amazon/ssm/runtimeconfig/identity_config.json第三步:仍未上线再重启 Agent
sudo systemctl restart amazon-ssm-agent
sudo systemctl --no-pager --full status amazon-ssm-agent重启会清理进程内状态并重新执行身份和凭证选择,是最直接的恢复方式。
第四步:从控制面验证
aws ssm describe-instance-information \
--filters 'Key=InstanceIds,Values=i-xxxxxxxxxxxxxxxxx'如果仍未返回,还要继续检查 VPC Endpoint、DNS、系统时间、防火墙和 SSM 服务端点连通性。IAM 缓存只解释“角色刚附加后延迟”这一类场景,不应覆盖所有 SSM 离线原因。
自动化中的正确做法
最佳方案是在创建实例时就通过 Launch Template、Auto Scaling Group 或 RunInstances 关联 Instance Profile。这样 Agent 首次启动时 IMDS 已有角色,不会先用空身份进入 AccessDenied 长退避。
如果业务必须对运行中实例换角色,自动化流程应当:
- 关联或替换 Instance Profile;
- 轮询 IMDS,直到返回预期角色;
- 执行
flush-cached-credentials; - 超时后再重启 Agent;
- 从 SSM 控制面确认
PingStatus。
源码线索
总结
运行中附加角色后 SSM 不立即上线,常见链路是:角色传播尚未完成 → Agent 首次验证失败 → 进入 25–30 分钟退避。正确顺序应是先看 IMDS,再读 Agent 日志,然后刷新缓存,最后才重启服务。这样既能快速恢复,也能保留足够证据判断真正卡住的位置。
