Как настроить cloud-init для пользовательских AMI в AWS? (CentOS)

Определение пользовательских данных для экземпляров в AWS представляется действительно полезным для выполнения всех видов действий типа bootstrap. К сожалению, я должен использовать пользовательский CentOS AMI, который не исходил из одного из предоставленных AMI по причинам PCI, поэтому cloud-init еще не установлен и не настроен. Я просто хочу, чтобы он установил имя хоста и запустил небольшой bash script. Как мне заставить работать?

Ответ 1

cloud-init - очень мощный, но очень недокументированный инструмент. Даже после того, как он был установлен, есть много модулей по умолчанию, которые перезаписывают вещи, которые вы, возможно, уже определили в своем AMI. Вот инструкции по минимальной настройке с нуля:

Инструкции

  • Установите 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
    
  • Измените /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 linux AMI is based on CentOS
      distro: amazon
    
  • Если в /etc/cloud/cloud.cfg.d/ есть defaults.cfg, удалите его.

  • Чтобы воспользоваться этой конфигурацией, определите следующие пользовательские данные для новых экземпляров:

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

    Вы также можете просто запустить bash script, заменив #cloud-config на #!/bin/bash и помещая bash script в тело, но если вы это сделаете, вы должны удалить все имя хоста, связанных с cloud_init_modules.


Дополнительные примечания

Обратите внимание, что это минимальная конфигурация, и cloud-init способен управлять пользователями, ключами ssh, точками подключения и т.д. Посмотрите приведенные ниже ссылки для дополнительной документации по этим конкретным функциям.

В общем, кажется, что cloud-init делает материал на основе указанных модулей. Некоторые модули, такие как "disable-ec2-metadata", делают вещи просто путем указания. Другие, такие как "runcmd", только делают вещи, если указаны их параметры, либо в cloud.cfg, либо в пользовательских данных cloud-config. Большая часть приведенной ниже документации только сообщает вам, какие параметры возможны для каждого модуля, а не то, что вызывается этим модулем, но по умолчанию для cloud.cfg должен быть полный список модулей. Лучший способ, которым я нашел отключить модуль, - это просто удалить его из списка.

В некоторых случаях "rhel" может работать лучше для тега "distro", чем "amazon". Я действительно не понял, когда.


Ссылки

Ответ 2

Развернувшись на предыдущем ответе для тех, кто пытается создать CentOS AMI, который cloud-init включен (и способен фактически выполнять ваши сценарии CloudFormation), у вас может быть некоторые успехи, сделав следующее:

  • запустите рынок CentOS AMI w/Updates - убедитесь, что присутствует облако-init или sudo yum install -y cloud-init
  • rm -rf /var/lib/cloud/data
  • rm -rf /var/lib/cloud/instance
  • rm -rf /var/lib/cloud/instances/*
  • замените /etc/cloud/cloud.cfg на конфигурацию в ответе выше, но убедитесь, что вы установили distro: rhel
  • Добавьте помощники CloudFormation (http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html)
  • создать образ AMI из этого экземпляра

Было время, пытаясь выяснить, почему мои UserData не были вызваны, пока я не понял, что изображения на рынке, естественно, запускают только UserData за один экземпляр и, конечно же, они уже запущены. Удаление указателей, которые уже были выполнены вместе с изменением distro: rhel в файле cloud.cfg, сделало трюк.

Для любопытных значение distro: должно соответствовать одному из скриптов python в /usr/lib/python2.6/site-packages/cloudinit/distros. Как оказалось, AMI, который я запускал, не имел amazon.py, поэтому вам нужно использовать rhel для CentOS. В зависимости от запуска AMI и версии cloud-init, YMMV.

Ответ 3

Вот краткий учебник о том, как запускать скрипты во время запуска, используя cloud-init на AWS EC2 (CentOS).

В этом руководстве объясняется:

  • как установить конфигурационный файл /etc/cloud/cloud.cfg
  • как выглядит путь облака /var/lib/cloud/scripts
  • файлы script под облачным путем, используя пример, и
  • как проверить, выполняются ли файлы script во время запуска экземпляра

Файл конфигурации

Конфигурационный файл ниже находится на 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

Дерево каталогов

Вот как выглядит путь облака /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

Содержимое script Files

Вот содержимое примера script файлов.
Файлы должны находиться под пользователем root. Посмотрите мой способ создать загрузку 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

Ссылка
Проверено время, в течение которого script запускается в cloud-init (CentOS6) (переведено)