如何在AWS中的自定义AMI上设置cloud-init?(CentOS的)

whe*_*den 30 centos amazon-web-services cloud-init amazon-ami

在AWS中为实例定义userdata似乎对执行各种引导类型操作非常有用.不幸的是,由于PCI原因,我必须使用不是源自其中一个提供的AMI的自定义CentOS AMI,因此尚未安装和配置cloud-init.我只是想要它设置一个主机名并运行一个小的bash脚本.我如何让它工作?

whe*_*den 50

cloud-init是一个非常强大但非常缺乏的工具.即使安装完毕,默认情况下仍会激活很多模块,这些模块会覆盖您在AMI上已定义的内容.以下是从头开始进行最小设置的说明:

说明

  1. 从标准存储库安装cloud-init.如果您担心PCI,您可能不想使用AWS的自定义存储库.

    # rpm -Uvh https://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    # yum install cloud-init
    
    Run Code Online (Sandbox Code Playgroud)
  2. 编辑/etc/cloud/cloud.cfg,yaml文件,以反映您所需的配置.下面是一个最小配置,包含每个模块的文档.

    #If this is not explicitly false, cloud-init will change things so that root
    #login via ssh is disabled. If you don't want it to do anything, set it false.
    disable_root: false
    
    #Set this if you want cloud-init to manage hostname. The current
    #/etc/hosts file will be replaced with the one in /etc/cloud/templates.
    manage_etc_hosts: true
    
    #Since cloud-init runs at multiple stages of boot, this needs to be set so
    #it can log in all of them to /var/log/cloud-init.
    syslog_fix_perms: null
    
    #This is the bit that makes userdata work. You need this to have userdata
    #scripts be run by cloud-init.
    datasource_list: [Ec2]
    datasource:
      Ec2:
        metadata_urls: ['http://169.254.169.254']
    
    #modules that run early in boot
    cloud_init_modules:
     - bootcmd  #for running commands in pre-boot. Commands can be defined in cloud-config userdata.
     - set-hostname  #These 3 make hostname setting work
     - update-hostname
     - update-etc-hosts
    
    #modules that run after boot
    cloud_config_modules:
     - runcmd  #like bootcmd, but runs after boot. Use this instead of bootcmd unless you have a good reason for doing so.
    
    #modules that run at some point after config is finished
    cloud_final_modules:
     - scripts-per-once  #all of these run scripts at specific events. Like bootcmd, can be defined in cloud-config.
     - scripts-per-boot
     - scripts-per-instance
     - scripts-user
     - phone-home  #if defined, can make a post request to a specified url when done booting
     - final-message  #if defined, can write a specified message to the log
     - power-state-change  #can trigger stuff based on power state changes
    
    system_info:
      #works because amazon's linux AMI is based on CentOS
      distro: amazon
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果有一个defaults.cfg/etc/cloud/cloud.cfg.d/,将其删除.

  4. 要利用此配置,请为新实例定义以下userdata:

    #cloud-config
    hostname: myhostname
    fqdn: myhostname.mydomain.com
    runcmd:
     - echo "I did this thing post-boot"
     - echo "I did this too"
    
    Run Code Online (Sandbox Code Playgroud)

    您也可以通过简单地更换运行bash脚本#cloud-config#!/bin/bash和把bash脚本在身,但如果你这样做,你应该删除所有的主机名相关模块cloud_init_modules.


补充说明

请注意,这是一个最小配置,cloud-init能够管理用户,ssh密钥,挂载点等.请查看下面的参考资料,以获取有关这些特定功能的更多文档.

通常,cloud-init似乎根据指定的模块执行操作.一些模块,比如"disable-ec2-metadata",只是通过指定来完成.其他人,比如"runcmd",只有在指定参数时才会执行操作,无论是在cloud.cfg中,还是在cloud-config userdata中.下面的大多数文档仅告诉您每个模块可能的参数,而不是模块的调用,但默认的cloud.cfg应该有一个完整的模块列表.我发现禁用模块的最好方法就是从列表中删除它.

在某些情况下,"rhel"可能比"amazon"更适合"发行"标签.我还没弄到什么时候.


参考


Che*_*ana 7

以下是有关如何在AWS EC2(CentOS)上使用cloud-init在启动期间运行脚本的简要教程.

本教程解释:

  • 如何设置配置文件 /etc/cloud/cloud.cfg
  • 云路径是/var/lib/cloud/scripts怎样的
  • 云路径下的脚本文件使用示例,和
  • 如何检查脚本文件是否在启动实例期间执行

配置文件

以下配置文件位于AWS CentOS6上.对于Amazon Linux,请参阅此处.

# cat /etc/cloud/cloud.cfg
manage_etc_hosts: localhost
user: root
disable_root: false
ssh_genkeytypes: [ rsa, dsa ]

cloud_init_modules:
 - resizefs
 - update_etc_hosts
 - ssh

cloud_final_modules:
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user
Run Code Online (Sandbox Code Playgroud)

目录树

以下是云路径的/var/lib/cloud/scripts样子:

# cd /var/lib/cloud/scripts
# tree `pwd`
/var/lib/cloud/scripts
??? per-boot
?     ??? per-boot.sh
??? per-instance
?     ??? per-instance.sh
??? per-once
       ??? per-once.sh
Run Code Online (Sandbox Code Playgroud)

脚本文件的内容

以下是示例脚本文件的内容.
文件必须在用户之下root.请参阅我创建启动脚本的方法.

# cat /var/lib/cloud/scripts/per-boot/per-boot.sh
#!/bin/sh
echo per-boot: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-instance/per-instance.sh
#!/bin/sh
echo per-instance: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-once/per-once.sh   
#!/bin/sh
echo per-once: `date` >> /tmp/per-xxx.txt
Run Code Online (Sandbox Code Playgroud)

执行结果

在初始启动的情况下

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST
Run Code Online (Sandbox Code Playgroud)

在重新启动的情况下

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST
Run Code Online (Sandbox Code Playgroud)

在从AMI开始的情况下

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST 
per-boot: 1 January 3, 2013 Thursday 17:44:08 JST
Run Code Online (Sandbox Code Playgroud)

参考
检查(翻译)在cloud-init(CentOS6)中运行脚本的时间


big*_*oot 6

对于任何尝试创建已启用的CentOS AMI (并且能够实际执行CloudFormation脚本)的人,可以扩展先前的答案,cloud-init通过执行以下操作可能会取得一些成功:

  1. 推出具有更新功能的CentOS AMI市场 - 确保存在cloud-init或 sudo yum install -y cloud-init
  2. rm -rf /var/lib/cloud/data
  3. rm -rf /var/lib/cloud/instance
  4. rm -rf /var/lib/cloud/instances/*
  5. 替换/etc/cloud/cloud.cfg上面的答案中的配置,但请确保您设置distro: rhel
  6. 添加CloudFormation帮助程序(http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html)
  7. 从此实例创建AMI图像

有一段时间试图找出为什么我的UserData没有被调用,直到我意识到市场中的图像自然只运行你的UserData每个实例一次,当然他们已经运行.删除那些已经与改变一起执行的各项指标distro: rhelcloud.cfg的文件并获得成功.

对于好奇,该distro:值应该对应于其中一个python脚本/usr/lib/python2.6/site-packages/cloudinit/distros.事实证明我推出的AMI没有amazon.py,所以你需要使用rhelCentOS.根据您启动的AMI和cloud-init的版本,YMMV.