EC2 User-data自定义命令未执行问题排查求助
排查Elastic Beanstalk User Data自定义命令未执行的问题
我来帮你梳理下为什么你的自定义Shell命令没生效,以及对应的解决办法:
1. 文件名拼写错误(直接导致命令执行失败)
先看你的自定义命令里的这一行:
chmod 750 91install_cloudwatchlogs_agent.sh && chmod 750 91_awslogs_restart.sh
第一个文件名91install_cloudwatchlogs_agent.sh少了下划线,应该和你之前aws s3 cp下载的文件名一致——91_install_cloudwatchlogs_agent.sh。这个拼写错误会让chmod命令直接失败,又因为用了&&串联命令,前面失败后后续的cp操作也会被终止执行。
2. 自定义命令的位置错误(导致代码根本没被运行)
再看原始User Data的脚本结构:
while true; do # 下载EB初始化脚本 curl https://s3.dualstack.us-west-2.amazonaws.com/... > /tmp/ebbootstrap.sh RESULT=$? if [[ "$RESULT" -ne 0 ]]; then sleep_delay else # 执行初始化脚本后直接exit 0退出 /bin/bash /tmp/ebbootstrap.sh '...' && exit 0 fi done
- 如果你把自定义命令放在这个
while循环之后:因为脚本执行成功初始化脚本后就直接exit 0了,循环永远不会结束,后面的代码根本没机会运行。 - 如果你把自定义命令放在
while循环之前:此时EB的初始化环境还没准备好——比如AWS CLI可能还未安装,实例角色的临时凭证还没获取到,导致aws s3 cp无法正常执行,又因为没有错误处理逻辑,失败后也不会留下明显的日志痕迹。
3. 正确的调整方案
方案一:修改User Data脚本,在EB初始化完成后执行命令
把自定义命令移到exit 0之前,也就是在EB基础初始化成功后、脚本退出前运行,同时修正文件名拼写:
# 原脚本的else块修改为如下内容 else /bin/bash /tmp/ebbootstrap.sh 'https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/aws-elasticbeanstalk-tools-1.20-1.noarch.rpm' 'https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/awseb-ruby-2.2.4-x86_64-20160503_1008.tar.gz https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/basehooks.tar.gz' 'https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/beanstalk-core-2.11.gem https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/beanstalk-core-healthd-1.1.gem https://s3.dualstack.us-west-2.amazonaws.com/elasticbeanstalk-env-resources-us-west-2/stalks/eb_node_js_4.0.1.143.7/lib/executor-1.2.gem' 'https://cloudformation-waitcondition-us-west-2.s3-us-west-2.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-west-2%3A731735707548%3Astack/awseb-e-qprmcmyjbp-stack/261dc900-e722-11e7-bcbb-503ac9ec2461/AWSEBInstanceLaunchWaitHandle?AWSAccessKeyId=AKIAIY5RM4DUXMU25KNA&Expires=1514038355&Signature=Nha6e4UQYJLWCOjxnj7nHXYzFDY%3D' 'arn:aws:cloudformation:us-west-2:731735707548:stack/awseb-e-qprmcmyjbp-stack/261dc900-e722-11e7-bcbb-503ac9ec2461' 'us-west-2' '30755f954950' 'e9af7960-20f2-46da-9353-a69cb7dedeff' '' 'nginx' '' && \ # 在这里添加修正后的自定义命令 aws s3 cp s3://oidevops/beanstalk/application-configs/chatbot-admin/dev/91_install_cloudwatchlogs_agent.sh . && \ aws s3 cp s3://oidevops/beanstalk/application-configs/chatbot-admin/dev/91_awslogs_restart.sh . && \ chmod 750 91_install_cloudwatchlogs_agent.sh && chmod 750 91_awslogs_restart.sh && \ cp 91_install_cloudwatchlogs_agent.sh /opt/elasticbeanstalk/hooks/appdeploy/post && \ cp 91_awslogs_restart.sh /opt/elasticbeanstalk/hooks/restartappserver/post && \ cp 91_awslogs_restart.sh /opt/elasticbeanstalk/hooks/configdeploy/post && \ exit 0 fi
这样修改后,只有EB基础初始化完成后,才会执行你的自定义命令,且所有命令用&&串联,确保前一步成功后才会继续执行。
方案二:使用Elastic Beanstalk配置文件(推荐)
更符合EB最佳实践的方式是通过.ebextensions配置文件管理hook脚本,无需修改User Data。在你的应用代码根目录创建.ebextensions/cloudwatchlogs.config,内容如下:
files: "/opt/elasticbeanstalk/hooks/appdeploy/post/91_install_cloudwatchlogs_agent.sh": mode: "0750" owner: root group: root source: https://oidevops.s3.amazonaws.com/beanstalk/application-configs/chatbot-admin/dev/91_install_cloudwatchlogs_agent.sh "/opt/elasticbeanstalk/hooks/restartappserver/post/91_awslogs_restart.sh": mode: "0750" owner: root group: root source: https://oidevops.s3.amazonaws.com/beanstalk/application-configs/chatbot-admin/dev/91_awslogs_restart.sh "/opt/elasticbeanstalk/hooks/configdeploy/post/91_awslogs_restart.sh": mode: "0750" owner: root group: root source: https://oidevops.s3.amazonaws.com/beanstalk/application-configs/chatbot-admin/dev/91_awslogs_restart.sh
EB会自动帮你下载并配置好这些hook脚本,更易维护和版本控制。
4. 验证与日志排查
修改完成后,你可以通过以下方式验证效果:
- 查看
/var/log/eb-cfn-init.log日志(原脚本已将输出重定向到这里),检查自定义命令的执行记录。 - 检查目标目录(如
/opt/elasticbeanstalk/hooks/appdeploy/post)是否存在你的脚本文件。 - 确认实例的IAM角色拥有
s3:GetObject权限,能够访问S3桶中的脚本文件。
内容的提问来源于stack exchange,提问作者Christian Dechery
相关产品推荐
相关产品推荐

