【问题标题】:How do I set up cloud-init on custom AMIs in AWS? (CentOS)如何在 AWS 中的自定义 AMI 上设置 cloud-init? (CentOS)
【发布时间】:2014-06-18 03:36:29
【问题描述】:

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

【问题讨论】:

  • 在这种情况下什么是“PCI”?
  • @JDS 指的是Payment Card Industry Data Security Council制定的准则。处理信用卡付款需要合规,这通常是一个强大的安全标准。
  • whereswalden:好的,谢谢。必须注意你知道的“行话”。

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


【解决方案1】:

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. 如果/etc/cloud/cloud.cfg.d/中有defaults.cfg,请删除。

  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 脚本,但如果这样做,您应该从cloud_init_modules 中删除所有与主机名相关的模块。


附加说明

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

一般来说,cloud-init 似乎是根据指定的模块来做事的。一些模块,如“disable-ec2-metadata”,只需指定即可。其他的,比如“runcmd”,只有在 cloud.cfg 或 cloud-config 用户数据中指定了参数时才会执行。下面的大部分文档只告诉您每个模块可以使用哪些参数,而不是模块的名称,但默认的 cloud.cfg 应该有一个完整的模块列表开始。我发现禁用模块的最佳方法就是将其从列表中删除。

在某些情况下,“rhel”可能比“amazon”更适合“distro”标签。我还真不知道什么时候。


参考文献

【讨论】:

  • 您要编辑的配置文件实际上是/etc/cloud/cloud.cfg,而不是/etc/cloud.cfg。我对 /etc/cloud.cfg 进行了所有更改(包括将 disable_root 设置为 false),创建了一个 ami,然后立即锁定了从 ami 创建的任何实例以及我的原始实例,因为 cloud-init 实际上没有读取那个文件。
  • 没错!已编辑。
  • 那么,这个/etc/cloud/cloud.cfg 是否保存在AMI 中 并重建了AMI?谢谢
  • @JDS:是的,它必须存在于您希望 cloud-config 用户数据工作的所有实例上,否则没有任何东西可以使用用户数据。
  • @whereswalden 谢谢。我看了又看,我认为一定是这样,但我找不到任何明确的说法,在安装了 cloud-init 的情况下构建您的 AMI。它在很多地方暗示,但免费提供的 Centos AMI 似乎没有它,而且我似乎不得不重新烘焙。很抱歉我的多嘴,但我喝了点啤酒
【解决方案2】:

这里有一个简短的教程,介绍如何在 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(翻译)

【讨论】:

  • 我发现你必须确保在 shell 脚本上设置了可执行权限
【解决方案3】:

对于任何尝试创建启用cloud-init(并且能够实际执行您的 CloudFormation 脚本)的 CentOS AMI 的人来说,扩展 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 映像

花了很长时间试图弄清楚为什么我的 UserData 没有被调用,直到我意识到市场上的图像自然地每个实例只运行你的 UserData 一次,当然它们已经运行了。删除那些已经执行的指标以及更改cloud.cfg 文件中的distro: rhel 就可以了。

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

【讨论】:

  • 引用另一个答案时,链接它会很有帮助。顺序可能会改变。
【解决方案4】:
猜你喜欢
  • 1970-01-01
  • 2020-08-18
  • 2022-01-16
  • 2016-11-01
  • 1970-01-01
  • 2022-01-21
  • 2019-12-27
  • 2020-06-30
  • 2020-05-02
相关资源
最近更新 更多