每次启动EC2实例时,如何运行cloud-init启动脚本?

Adr*_*scu 54 cloud amazon-ec2 cloud-init

我有一个基于Amazon Linux AMI运行AMI的EC2实例.与所有此类AMI一样,它支持cloud-init系统,用于根据传递到每个实例的用户数据运行启动脚本.在这种特殊情况下,我的用户数据输入恰好是一个包含几个其他启动脚本的Include文件:

#include
http://s3.amazonaws.com/path/to/script/1
http://s3.amazonaws.com/path/to/script/2
Run Code Online (Sandbox Code Playgroud)

我第一次启动我的实例时,cloud-init启动脚本正确运行.但是,如果我对实例进行软重启(例如,通过运行sudo shutdown -r now),则实例会在不再运行启动脚本的情况下重新启动.如果我进入系统日志,我可以看到:

Running cloud-init user-scripts
user-scripts already ran once-per-instance
[  OK  ]
Run Code Online (Sandbox Code Playgroud)

这不是我想要的 - 我可以看到启动脚本每个实例生命周期只运行一次的实用程序,但在我的情况下,这些应该在每次实例启动时运行,就像正常的启动脚本一样.

我意识到一个可能的解决方案是rc.local在第一次运行后手动让我的脚本插入.然而,这似乎很麻烦,因为cloud-init和rc.d环境略有不同,我现在必须分别在首次启动和所有后续启动时调试脚本.

有谁知道我怎么能告诉cloud-init总是运行我的脚本?这听起来像是cloud-init的设计者会考虑的事情.

smo*_*ser 58

在11.10,12.04及更高版本中,您可以通过使'scripts-user'运行'always'来实现这一目标.在/etc/cloud/cloud.cfg中你会看到类似的东西:

cloud_final_modules:
 - rightscale_userdata
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user
 - keys-to-console
 - phone-home
 - final-message
Run Code Online (Sandbox Code Playgroud)

这可以在引导后修改,或者可以通过用户数据插入覆盖此节的cloud-config数据.即,在用户数据中,您可以提供:

#cloud-config
cloud_final_modules:
 - rightscale_userdata
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - [scripts-user, always]
 - keys-to-console
 - phone-home
 - final-message
Run Code Online (Sandbox Code Playgroud)

也可以像你在描述中所做的那样'#included'.不幸的是,现在,你无法修改'cloud_final_modules',但只能覆盖它.我希望在某些时候添加修改配置节的功能.

有关这方面的更多信息,请参阅http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/view/head:/doc/examples/cloud-config中的cloud-config文档. .文本

或者,您可以将文件放在/ var/lib/cloud/scripts/per-boot中,它们将由'scripts-per-boot'路径运行.

  • 这是一个进行内联修改的单行程序:`sed -i's/scripts-user $ /\[scripts-user,always \] /'/ etc/cloud/cloud.cfg` (3认同)
  • 截至2017年,数据已移至其他地方.使用/etc/cloud/cloud.cfg.d/并在那里放一个新文件. (2认同)

小智 20

/etc/init.d/cloud-init-user-scripts,编辑此行:

/usr/bin/cloud-init-run-module once-per-instance user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
Run Code Online (Sandbox Code Playgroud)

 /usr/bin/cloud-init-run-module always user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure
Run Code Online (Sandbox Code Playgroud)

祝好运 !


Eri*_*ger 9

cloud-init现在支持这个,请参阅文档中的runcmd vs bootcmd命令描述(http://cloudinit.readthedocs.io/en/latest/topics/examples.html#run-commands-on-first-boot):

"RUNCMD":

#cloud-config

# run commands
# default: none
# runcmd contains a list of either lists or a string
# each item will be executed in order at rc.local like level with
# output to the console
# - runcmd only runs during the first boot
# - if the item is a list, the items will be properly executed as if
#   passed to execve(3) (with the first arg as the command).
# - if the item is a string, it will be simply written to the file and
#   will be interpreted by 'sh'
#
# Note, that the list has to be proper yaml, so you have to quote
# any characters yaml would eat (':' can be problematic)
runcmd:
 - [ ls, -l, / ]
 - [ sh, -xc, "echo $(date) ': hello world!'" ]
 - [ sh, -c, echo "=========hello world'=========" ]
 - ls -l /root
 - [ wget, "http://slashdot.org", -O, /tmp/index.html ]
Run Code Online (Sandbox Code Playgroud)

"bootcmd":

#cloud-config

# boot commands
# default: none
# this is very similar to runcmd, but commands run very early
# in the boot process, only slightly after a 'boothook' would run.
# bootcmd should really only be used for things that could not be
# done later in the boot process.  bootcmd is very much like
# boothook, but possibly with more friendly.
# - bootcmd will run on every boot
# - the INSTANCE_ID variable will be set to the current instance id.
# - you can use 'cloud-init-per' command to help only run once
bootcmd:
 - echo 192.168.1.130 us.archive.ubuntu.com >> /etc/hosts
 - [ cloud-init-per, once, mymkfs, mkfs, /dev/vdb ]
Run Code Online (Sandbox Code Playgroud)

还要注意bootcmd中的"cloud-init-per"命令示例.从它的帮助:

Usage: cloud-init-per frequency name cmd [ arg1 [ arg2 [ ... ] ]
   run cmd with arguments provided.

   This utility can make it easier to use boothooks or bootcmd
   on a per "once" or "always" basis.

   If frequency is:
      * once: run only once (do not re-run for new instance-id)
      * instance: run only the first boot for a given instance-id
      * always: run every boot
Run Code Online (Sandbox Code Playgroud)

  • bootcmd部分在未完全引导的系统上执行,可能无法按预期工作. (3认同)

Adr*_*scu 7

一种可能性,虽然有些苛刻,但是删除了cloud-init用来确定用户脚本是否已经运行的锁定文件.在我的案例中(Amazon Linux AMI),此锁定文件位于/var/lib/cloud/sem/并命名user-scripts.i-7f3f1d11(最后的哈希部分在每次启动时都会更改).因此,添加到Include文件末尾的以下用户数据脚本将起到作用:

#!/bin/sh
rm /var/lib/cloud/sem/user-scripts.*
Run Code Online (Sandbox Code Playgroud)

我不确定这是否会对其他任何事情产生任何不利影响,但它在我的实验中起作用.