如何使 cloud-init 启动脚本在每次 EC2 实例启动时运行?
我有一个运行基于 Amazon Linux AMI 的 AMI 的 EC2 实例。与所有此类 AMI 一样,它支持 cloud-init 系统,用于基于用户数据运行启动脚本传递到每个实例中。在这种特殊情况下,我的用户数据输入恰好是一个包含文件,该文件提供了几个其他启动脚本:
#include
http://s3.amazonaws.com/path/to/script/1
http://s3.amazonaws.com/path/to/script/2
我第一次启动实例时,cloud-init 启动脚本正确运行。但是,如果我对实例进行软重启(例如,通过运行 sudo shutdown -r now),实例将重新启动,而无需在第二次运行启动脚本周围的时间。如果我进入系统日志,我可以看到:
Running cloud-init user-scripts
user-scripts already ran once-per-instance
[ OK ]
这不是我想要的 - 我可以看到启动脚本在每个实例生命周期中只运行一次的实用程序,但在我的情况下,这些脚本应该在每次实例启动时运行,就像普通的启动脚本一样。
我意识到一个可能的解决方案是在第一次运行后手动将我的脚本插入到 rc.local 中。然而,这似乎很麻烦,因为 cloud-init 和 rc.d 环境略有不同,我现在必须在首次启动和所有后续启动时分别调试脚本。
有谁知道我如何告诉 cloud-init 始终运行我的脚本?这听起来确实像是 cloud-init 的设计者会考虑到的事情。
I have an EC2 instance running an AMI based on the Amazon Linux AMI. Like all such AMIs, it supports the cloud-init system for running startup scripts based on the User Data passed into every instance. In this particular case, my User Data input happens to be an Include file that sources several other startup scripts:
#include
http://s3.amazonaws.com/path/to/script/1
http://s3.amazonaws.com/path/to/script/2
The first time I boot my instance, the cloud-init startup script runs correctly. However, if I do a soft reboot of the instance (by running sudo shutdown -r now
, for instance), the instance comes back up without running the startup script the second time around. If I go into the system logs, I can see:
Running cloud-init user-scripts
user-scripts already ran once-per-instance
[ OK ]
This is not what I want -- I can see the utility of having startup scripts that only run once per instance lifetime, but in my case these should run every time the instance starts up, like normal startup scripts.
I realize that one possible solution is to manually have my scripts insert themselves into rc.local
after running the first time. This seems burdensome, however, since the cloud-init and rc.d environments are subtly different and I would now have to debug scripts on first launch and all subsequent launches separately.
Does anyone know how I can tell cloud-init to always run my scripts? This certainly sounds like something the designers of cloud-init would have considered.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
另一种方法是在用户数据脚本中使用
#cloud-boothook
。来自 文档:Another approach is to use
#cloud-boothook
in your user data script. From the docs:请使用 bash 脚本上方的以下脚本。
之前,我将 hello world 打印到我的文件
停止实例
示例:在添加到 userdata脚本
please use the below script above your bash script.
example: here m printing hello world to my file
stop instance before adding to userdata
script
在 Amazon Linux 2 上对我有用的是删除
/var/lib/cloud/instance/sem/
下的信号量:理论上,可以创建一个 cron 来定期删除这些文件
What worked for me on Amazon Linux 2 was removing semaphores under
/var/lib/cloud/instance/sem/
:In theory one could create a cron to remove these files periodically
在 11.10、12.04 及更高版本中,您可以通过使“scripts-user”“始终”运行来实现此目的。
在 /etc/cloud/cloud.cfg 中,您将看到类似以下内容:
这可以在启动后修改,或者可以通过用户数据插入覆盖此节的云配置数据。即,在用户数据中,您可以提供:
也可以是“#included”,正如您在描述中所做的那样。
不幸的是,现在您无法修改“cloud_final_modules”,而只能覆盖它。我希望在某个时候添加修改配置部分的功能。
云配置文档中有更多关于此的信息:
https://github.com/canonical/cloud-init/tree/master /doc/examples
或者,您可以将文件放入 /var/lib/cloud/scripts/per-boot 中,它们将通过 'scripts-per-boot' 路径运行。
In 11.10, 12.04 and later, you can achieve this by making the 'scripts-user' run 'always'.
In /etc/cloud/cloud.cfg you'll see something like:
This can be modified after boot, or cloud-config data overriding this stanza can be inserted via user-data. Ie, in user-data you can provide:
That can also be '#included' as you've done in your description.
Unfortunately, right now, you cannot modify the 'cloud_final_modules', but only override it. I hope to add the ability to modify config sections at some point.
There is a bit more information on this in the cloud-config doc at
https://github.com/canonical/cloud-init/tree/master/doc/examples
Alternatively, you can put files in /var/lib/cloud/scripts/per-boot , and they'll be run by the 'scripts-per-boot' path.
在
/etc/init.d/cloud-init-user-scripts
中,编辑此行:祝
你好运!
In
/etc/init.d/cloud-init-user-scripts
, edit this line:to
Good luck !
cloud-init 现在原生支持此功能,请参阅文档中的 runcmd 与 bootcmd 命令描述 (http://cloudinit.readthedocs.io/en/latest/topics/examples.html#run-commands-on-first-boot):
"runcmd":
“bootcmd”:
另请注意 bootcmd 中的“cloud-init-per”命令示例。从它的帮助:
cloud-init supports this now natively, see runcmd vs bootcmd command descriptions in the documentation (http://cloudinit.readthedocs.io/en/latest/topics/examples.html#run-commands-on-first-boot):
"runcmd":
"bootcmd":
also note the "cloud-init-per" command example in bootcmd. From it's help:
一种可能(虽然有些黑客行为)是删除 cloud-init 用于确定用户脚本是否已运行的锁定文件。就我而言 (Amazon Linux AMI),此锁定文件位于
/var/lib/cloud/sem/
中,名为user-scripts.i-7f3f1d11
(最后的哈希部分每次启动都会改变)。因此,添加到包含文件末尾的以下用户数据脚本将起到作用:我不确定这是否会对其他任何内容产生不利影响,但它在我的实验中有效。
One possibility, although somewhat hackish, is to delete the lock file that cloud-init uses to determine whether or not the user-script has already run. In my case (Amazon Linux AMI), this lock file is located in
/var/lib/cloud/sem/
and is nameduser-scripts.i-7f3f1d11
(the hash part at the end changes every boot). Therefore, the following user-data script added to the end of the Include file will do the trick:I'm not sure if this will have any adverse effects on anything else, but it has worked in my experiments.
我在这个问题上苦苦挣扎了近两天,尝试了所有我能找到的解决方案,最后结合多种方法,提出了以下方案:
这是 DynamoDb 跨区域复制过程的设置。
I struggled with this issue for almost two days, tried all of the solutions I could find and finally, combining several approaches, came up with the following:
This is the setup for DynamoDb cross-region replication process.
如果有人想在 CDK 上执行此操作,这里有一个 python 示例。
对于 Windows,用户数据具有特殊的
persist
标签,但对于Linux,需要使用多部分用户数据 首先设置cloud-init。此 Linux 示例使用cloud-config
(请参阅 参考博客)部分类型而不是cloud-boothook
需要一个cloud-init-per
(另请参阅 bootcmd) 调用我无法测试(例如:cloud-init-pre always
)。Linux 示例:
Windows 示例:
If someone wants to do this on CDK, here's a python example.
For Windows, user data has a special
persist
tag, but for Linux, you need to use MultiPart User data to setup cloud-init first. This Linux example worked withcloud-config
(see ref blog) part type instead ofcloud-boothook
which requires acloud-init-per
(see also bootcmd) call I couldn't test out (eg:cloud-init-pre always
).Linux example:
Windows example: