用户数据脚本未在我的自定义 AMI 上运行,但在标准 Amazon linux 中运行
Posted
技术标签:
【中文标题】用户数据脚本未在我的自定义 AMI 上运行,但在标准 Amazon linux 中运行【英文标题】:User-data scripts is not running on my custom AMI, but working in standard Amazon linux 【发布时间】:2015-01-21 02:11:07 【问题描述】:这几天我搜索了很多关于“user-data script is not working”的话题,但是直到现在我还没有对我的情况有任何了解,请帮我弄清楚发生了什么,谢谢很多!
根据AWSUser-data解释:
当您在 Amazon EC2 中启动实例时,您可以选择将用户数据传递给实例,这些数据可用于执行常见的自动化配置任务,甚至在实例启动后运行脚本。
所以我尝试在实例启动时传递我自己的用户数据,这是我的用户数据:
\#!/bin/bash
echo 'test' > /home/ec2-user/user-script-output.txt
但是这个路径下没有文件:/home/ec2-user/user-script-output.txt
我检查了/var/lib/cloud/instance/user-data.txt
,该文件存在并且与我的用户数据脚本相同。
另外我检查了/var/log/cloud-init.log
的登录,没有错误信息。
但是如果我使用 Amazon linux(2014.09.01) 启动一个新实例,用户数据脚本就可以工作,但我不确定我的 AMI(基于 Amazon linux)和 Amazon linux 之间有什么区别。
我看到的唯一不同的部分是如果我运行这个脚本:
sudo yum list installed | grep cloud-init
我的 AMI:
cloud-init.noarch 0.7.2-8.33.amzn1 @amzn-main
亚马逊 Linux:
cloud-init.noarch 0.7.2-8.33.amzn1 已安装
我不确定是不是这个原因?
如果您需要更多信息,我很乐意提供,请告诉我在我自己的 AMI 中发生了什么以及如何修复它?
非常感谢
更新
刚刚从这个post找到答案,
如果我在用户数据文件的顶部添加#cloud-boothook,它会起作用!
#cloud-boothook
#!/bin/bash
echo 'test' > /home/ec2-user/user-script-output.txt
但仍然不知道为什么。
【问题讨论】:
How to make EC2 user-data work on freshly built AMI, made with Packer的可能重复 #cloud-boothook 解决方案对我不起作用。 UserData 仍未运行。 现在有一个官方文档页面。经过所有的尝试,这终于对我有用了。aws.amazon.com/premiumsupport/knowledge-center/… 【参考方案1】:User_data 仅在第一次启动时运行。由于您的图像是自定义图像,我想它已经启动过一次,因此 user_data 已停用。
对于 Windows,可以通过选中 Ec2 Services Properties 中的框来完成。我正在研究如何在自定义图像创建结束时以自动方式执行此操作。
对于linux,我想机制是一样的,需要在你的自定义镜像上重新激活user_data。
#cloud-boothook
使其工作,因为它将脚本从 user_data
机制更改为 cloud-boothook 机制,每次启动都会运行。
编辑:
这是使用 powershell 在 windows 上重新激活启动的代码:
$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\Config.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Plugin") |? $_.Name -eq "Ec2HandleUserData" |% $_.State = "Enabled"
$xdoc.SelectNodes("//Plugin") |? $_.Name -eq "Ec2SetComputerName" |% $_.State = "Enabled"
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile
$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\BundleConfig.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Property") |? $_.Name -eq "AutoSysprep" |% $_.Value = "Yes"
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile
(我知道问题集中在 linux,但它可以帮助其他人......)
【讨论】:
【参考方案2】:正如我测试的那样,/var/lib/cloud
目录中有一些引导数据。
清除该目录后,用户数据脚本正常工作。
rm -rf /var/lib/cloud/*
【讨论】:
【参考方案3】:我在 Ubuntu 16.04 hvm AMI 上也遇到了同样的问题。我已将问题提交给 AWS 支持,但我仍然找不到影响它的确切原因/错误。
但我仍有一些东西可以帮助你。
在使用 AMI 之前删除 /var/lib/cloud 目录(每次)。然后在创建 Image 时,将其设置为 no-reboot。
如果这些方法仍然不起作用,您可以通过强制用户数据手动运行来进一步测试它。还有 tailf /var/log/cloud-init-output.log
用于 cloud-init 状态。它应该以 modules:final 之类的东西结尾,以使您的用户数据运行。它不应该停留在 modules:config 上。
sudo rm -rf /var/lib/cloud/*
sudo cloud-init init
sudo cloud-init modules -m final
我不太清楚上述命令是否可以在 CentOS 上运行。我已经在 Ubuntu 上测试过了。
就我而言,我也尝试过删除 /var/lib/cloud 目录,但在我们的场景中仍然无法执行用户数据。但我想出了不同的解决方案。我们所做的是我们使用上述命令创建了脚本,并让该脚本在系统启动时运行。
我在 /etc/rc.local 中添加了以下行来实现它。
sudo bash /home/ubuntu/force-user-data.sh || exit 1
但这里有个问题,它会在每次启动时执行脚本,这样您的用户数据就会在每次启动时运行,就像 #cloud-boothook 一样。不用担心,您可以通过在最后删除 force-user-data.sh 本身来调整它。所以你的 force-user-data.sh 看起来像
#!/bin/bash
sudo rm -rf /var/lib/cloud/*
sudo cloud-init init
sudo cloud-init modules -m final
sudo rm -f /home/ubuntu/force-user-data.sh
exit 0
如果有人能说明为什么它无法执行用户数据,我将不胜感激。
【讨论】:
太棒了。你为我节省了很多时间!【参考方案4】:以答案为例:确保标题中只有#!/bin/bash
#!/bin/bash
yum update -y
yum install httpd mod_ssl
service httpd start
chkconfig httpd on
【讨论】:
【参考方案5】:我在这方面遇到了很多麻烦。我将提供详细的演练。
另外一个问题是我使用 terraform 通过启动配置和自动缩放组来实例化主机。
我无法通过在 lc.tf 中添加内联脚本来使其工作
user_data = DATA <<
"
#cloud-boothook
#!/bin/bash
echo 'some crap'\'
"
DATA
我可以从用户数据中获取它,
wget http://169.254.169.254/latest/user-data
但注意到我得到它时仍然包含引号。
这就是我让它工作的方式:我改为从模板中提取它,因为所见即所得。
user_data = "$data.template_file.bootscript.rendered"
这意味着我还需要像这样声明我的模板文件:
data "template_file" "bootscript"
template = "$file("bootscript.tpl")"
但我仍然在云初始化日志中收到错误 /var/log/cloud-init.log [警告]:未处理的非多部分(文本/x-not-multipart)用户数据:'Content-Type: text/cloud...'
然后我找到了this article about user data formatting user,这是有道理的,如果用户数据可以分为多个部分,也许 cloud-init 需要 cloud-init 命令在一个地方,而脚本在另一个地方。
所以我的 bootscript.tpl 看起来像这样:
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
echo "some crap"
--//
【讨论】:
【参考方案6】:在 ubuntu 16 上,删除 /var/lib/cloud/* 不起作用。我只从文件夹 /var/lib/cloud/ 中删除了实例,然后它对我来说运行良好
我跑了:
sudo rm /var/lib/cloud/instance
sudo rm /var/lib/cloud/instances
然后我重试了我的用户数据脚本,它运行良好
【讨论】:
这在 Ubuntu 上对我有用,但我需要运行sudo rm -r /var/lib/cloud/instances
,因为 instances
是一个目录。【参考方案7】:
我使用的是 CentOS,用户数据的逻辑很简单:
在文件 /etc/rc.local 中有一个对 initial.sh 脚本的调用,但它首先查找一个标志:
if [ -f /var/tmp/initial ]; then
/var/tmp/initial.sh &
fi
initial.sh 是执行用户数据的文件,但最后它删除了标志。因此,如果您希望新的 AMI 再次执行用户数据,只需在创建映像之前再次创建标志:
touch /var/tmp/initial
【讨论】:
【参考方案8】:只需在用户数据脚本的末尾添加 --// 即可,例如:
#!/bin/bash
#Upgrade ec2 instance
sudo yum update -y
#Start docker service
sudo service docker start
--//
【讨论】:
你能解释一下这是做什么的吗?【参考方案9】:用户数据应该可以在不使用#cloud-boothook
(用于在启动过程中尽早激活用户数据)的情况下正常执行。
我启动了一个新的 Amazon Linux AMI 并使用了您的用户数据,以及一些额外的:
#!/bin/bash
echo 'bar' > /tmp/bar
echo 'test' > /home/ec2-user/user-script-output.txt
echo 'foo' > /tmp/foo
这成功创建了三个文件。
用户数据脚本以root
执行,因此它应该有权在任何位置创建文件。
我注意到在您提供的代码中,一个示例引用了/home/ec2-user/user-script/output.txt
(带有子目录),一个示例引用了/home/ec2-user/user-script-output.txt
(没有子目录)。如果您尝试在不存在的目录中创建文件,该命令会失败,这是可以理解的,但您的“更新”示例似乎表明它确实有效。
【讨论】:
感谢您的回答,对此感到抱歉,/home/ec2-user/user-script/output.txt 是错字,已经修复,现在我仍然不知道为什么它没有如果我删除#cloud-boothook 将无法正常工作,但仍在尝试解决【参考方案10】:!/bin/bash
不要在行首留下任何空白。使用确切的命令。否则它可能会在 AMAZON Linux AMI 中运行,但不会在 RHEL 中运行。
【讨论】:
【参考方案11】:我让它工作的唯一方法是在 #!/bin/bash 之前添加 #cloud-boothook
这是一个典型的用户数据脚本,用于在新创建的实例上安装 Apache Web 服务器
#cloud-boothook
#!/bin/bash
yum update -y
yum install -y httpd.x86_64
systemctl start httpd.service
systemctl enable httpd.service
没有#cloud-boothook 它不起作用,但有了它,它就可以工作。似乎不同的用户有不同的体验。有些人可以在没有它的情况下让它工作,不知道为什么。
【讨论】:
【参考方案12】:另外, 如果我们使用像
这样的用户交互命令sudo yum install java-1.8.0-devel
然后,我们需要使用 -y 之类的标志
sudo yum install java-1.8.0-devel -y
您可以在 EC2 文档的 Run commands at launch 下找到此内容。
参考:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts
【讨论】:
以上是关于用户数据脚本未在我的自定义 AMI 上运行,但在标准 Amazon linux 中运行的主要内容,如果未能解决你的问题,请参考以下文章
属性或方法“sendResetMail”未在实例上定义,但在渲染期间引用
使用React Native的Firebase查询未在我的屏幕上显示(但在console.log上显示)
TFS Api 未在 Dev Azure 上的自定义流程模板中提供自定义状态