从自定义AMI启动EC2实例时UserData脚本未运行该如何排查
问题根因
从你提供的系统日志可以直接定位到错误:the input device is not a TTY,这是因为你在docker run命令中使用了-it参数,UserData脚本由cloud-init在后台非交互环境执行,没有可用的TTY终端,导致docker命令执行失败,触发整个脚本异常退出。
UserData未执行通用排查步骤
- 首先确认自定义AMI已预装
cloud-init并配置开机自启:AWS官方提供的公共AMI默认已安装配置,如果你是自行制作的自定义AMI,未安装cloud-init会导致UserData完全不触发。 - 检查脚本首行必须指定解释器,比如
#!/bin/sh或#!/bin/bash,缺少首行声明的文件不会被cloud-init识别为可执行脚本。 - 查看cloud-init日志定位具体错误:日志默认存储在
/var/log/cloud-init-output.log和/var/log/cloud-init.log,所有脚本的输出、报错都会记录在该路径下。 - 确认实例IAM权限无相关限制:通常UserData执行不需要额外权限,但如果你配置了cloud-init调用AWS服务的逻辑,需要对应实例角色加权限。
你的脚本修复方案
移除-it参数,添加-d参数让容器在后台运行即可,修改后的脚本如下:
#!/bin/sh systemctl start docker docker run -d --publish 8080:8080 exampleapplication:latest
如果需要保留容器运行日志,可以添加--name参数指定容器名,后续用docker logs 容器名查看日志。
常见遗漏配置项
- 如果你通过API/SDK/terraform等工具传递UserData,需要先对脚本内容做base64编码,控制台手动填写UserData会自动完成编码,无需额外处理。
- 制作自定义AMI时不要清理
/var/lib/cloud/目录下的文件,否则cloud-init会判断当前实例已经完成初始化,不会再执行新的UserData脚本。 - 非AWS官方发行版的镜像需要确认
/etc/cloud/cloud.cfg配置中开启了scripts-user模块,默认状态为开启,手动修改过配置的话需要检查。
关于是否可以直接将脚本部署在AMI内部
可以,有两种常用实现方案:
- 将脚本放入AMI的
/var/lib/cloud/scripts/per-instance/目录下,配置执行权限,cloud-init每次启动新实例时都会自动执行该目录下的所有脚本,适合需要随实例差异化配置调整的逻辑。 - 将脚本封装为systemd服务,配置开机自启,适合不需要随启动参数变化的固定初始化逻辑。
内容的提问来源于stack exchange,提问作者Nane Petrosyan
相关产品推荐
相关产品推荐

