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

时间:2014-05-01 15:56:52

标签: amazon-web-services centos ami cloud-init

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

4 个答案:

答案 0 :(得分: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
    
  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
    
  3. 如果defaults.cfg中有/etc/cloud/cloud.cfg.d/,请将其删除。

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

    #cloud-config
    hostname: myhostname
    fqdn: myhostname.mydomain.com
    runcmd:
     - echo "I did this thing post-boot"
     - echo "I did this too"
    

    您也可以通过将#cloud-config替换为#!/bin/bash并将bash脚本放在正文中来运行bash脚本,但如果这样做,则应从{删除所有与主机名相关的模块{1}}。


  5. 附加说明

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

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

    在某些情况下," rhel"可能会更好地发挥"发行版"标签比"亚马逊"。我还没知道什么时候。


    参考

答案 1 :(得分:6)

为试图创建启用cloud-init的CentOS AMI(并且能够实际执行您的CloudFormation脚本)的任何人扩展the prior answer,您可以通过执行以下操作取得一些成功:

  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图像
  8. 有一段时间试图找出为什么我的UserData没有被调用,直到我意识到市场中的图像自然只运行你的UserData每个实例一次当然他们已经运行。删除那些已经执行过的指标以及更改distro: rhel文件中的cloud.cfg都可以解决问题。

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

答案 2 :(得分:5)

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

  

本教程解释:

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

配置文件

以下配置文件位于AWS CentOS6上。对于Amazon Linux,请参阅here

# 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

目录树

以下是云路径 /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

脚本文件的内容

以下是示例脚本文件的内容 文件必须位于用户root下。在creating the boot script上查看我的方式。

# 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

执行结果

在初次启动的情况下

# 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

在重启的情况下

# 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

从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

<强>参考
The timing at which the script is run in cloud-init (CentOS6) was examined(已翻译)

答案 3 :(得分:0)