我在这几天搜索了很多关于“用户数据脚本无法正常工作”的话题,但直到现在,我还没有对我的案例有任何了解,请帮我弄清楚发生了什么,谢谢很多!
根据AWS User-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
但仍不确定原因。
答案 0 :(得分:22)
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的问题,但它可以帮助其他人......)
答案 1 :(得分:4)
正如我测试的那样,/var/lib/cloud
目录中有一些引导数据。
清除该目录后,用户数据脚本正常工作。
rm -rf /var/lib/cloud/*
答案 2 :(得分:1)
我正在使用CentOS,而userdata的逻辑很简单:
在文件/etc/rc.local中有一个initial.sh脚本的调用,但它首先查找一个标志:
if [ -f /var/tmp/initial ]; then
/var/tmp/initial.sh &
fi
initial.sh是执行用户数据的文件,但最后会删除该标志。因此,如果您希望新的AMI再次执行用户数据,只需在创建映像之前再次创建标志:
touch /var/tmp/initial
答案 3 :(得分:1)
我在Ubuntu 16.04 hvm AMI上也面临同样的问题。我已将问题提交给AWS支持,但我仍无法找到影响它的确切原因/错误。
但我仍然有一些可能对你有用的东西。
在采取AMI之前删除/ var / lib / cloud目录(每次)。然后在创建Image时,将其设置为no-reboot。
如果这些事情仍然无效,您可以通过强制手动运行用户数据来进一步测试。还为cloud-init状态设置了tailf /var/log/cloud-init-output.log
。它应该以模块之类的结尾:final来使用户数据运行。它不应该停留在模块上: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 :(得分:1)
我遇到了很多麻烦。我会提供详细的步行。
我补充说,我正在使用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 [警告]:未处理的非多部分(text / 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"
--//
答案 5 :(得分:0)
用户数据应该可以在不使用#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
(无子目录)。如果您尝试在不存在的目录中创建文件,该命令将会失败,但您的“更新”示例似乎表明它确实可以正常工作。
答案 6 :(得分:0)
这是示例的答案:确保您仅在标题中#!/bin/bash
#!/bin/bash
yum update -y
yum install httpd mod_ssl
service httpd start
chkconfig httpd on
答案 7 :(得分:0)
不要在行的开头留任何空白。使用精确命令。否则,它可能会在AMAZON Linux AMI中运行,但不会在RHEL中运行。
答案 8 :(得分:0)
让它起作用的唯一方法是在#!/ 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的情况下不起作用,但是在它的作用下,它可以起作用。似乎不同的用户有不同的体验。有些人可以不用它就能工作,不知道为什么。
答案 9 :(得分:0)
另外, 如果我们使用的是用户交互命令,例如
sudo yum install java-1.8.0-devel
然后,我们需要使用-y这样的标志
sudo yum install java-1.8.0-devel -y
您可以在EC2文档中的“启动时运行命令”下找到它。
参考:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts
答案 10 :(得分:0)
在ubuntu 16上,删除/ var / lib / cloud / *不起作用。我只从文件夹/ var / lib / cloud /中删除了一个实例,然后对我来说运行正常
我跑了
sudo rm /var/lib/cloud/instance
sudo rm /var/lib/cloud/instances
然后我重试了我的用户数据脚本,它运行正常
答案 11 :(得分:0)
只需在用户数据脚本的末尾添加 --// ,例如:
#!/bin/bash
#Upgrade ec2 instance
sudo yum update -y
#Start docker service
sudo service docker start
--//