Скрипты пользовательских данных не работают на моем пользовательском AMI, но работают в стандартном Amazon Linux

За эти несколько дней я много раз обыскивал тему "скрипт пользовательских данных не работает", но до сих пор я еще не получил ни малейшего представления о своем деле, пожалуйста, помогите мне выяснить, что произошло, большое спасибо!

Согласно объяснению данных пользователя AWS:

Когда вы запускаете экземпляр в Amazon EC2, у вас есть возможность передавать пользовательские данные в экземпляр, который можно использовать для выполнения общих задач автоматической настройки и даже запуска сценариев после запуска экземпляра.

Поэтому я попытался передать свои собственные пользовательские данные при запуске экземпляра, это мои пользовательские данные:

\#!/bin/bash

echo 'test' > /home/ec2-user/user-script-output.txt

Но в этом пути нет файла: /home/ec2-user/user-script-output.txt

Я проверил /var/lib/cloud/instance/user-data.txt, файл существует и такой же, как мой скрипт пользовательских данных.

Также я проверил логин /var/log/cloud-init.logНет сообщения об ошибке.

Но скрипт пользовательских данных работает, если я запускаю новый экземпляр с Amazon Linux(2014.09.01), но я не уверен, в чем разница между моим AMI (на основе Amazon Linux) и Amazon Linux.

Единственная другая часть, которую я видел, - это если я запускаю этот скрипт

sudo yum list installed | grep cloud-init

Мой AMI:

cloud-init.noarch 0.7.2-8.33.amzn1 @ amzn-main

Amazon Linux:

cloud-init.noarch 0.7.2-8.33.amzn1 установлен

Я не уверен, что это причина?

Если вам нужна дополнительная информация, я рад сообщить, пожалуйста, дайте мне знать, что произошло в моем собственном AMI и как это исправить?

большое спасибо

Обновить

Только что нашел ответ из этого поста,

Если я добавлю #cloud-boothook в начало файла пользовательских данных, это будет работать!

#cloud-boothook
#!/bin/bash
echo 'test' > /home/ec2-user/user-script-output.txt

Но все еще не уверен, почему.

13 ответов

User_data запускается только при первом запуске. Поскольку ваше изображение является пользовательским, я полагаю, что оно уже было запущено один раз, и поэтому user_data деактивируется.

Для окон это можно сделать, установив флажок в Свойствах Служб Ec2. Сейчас я смотрю, как это сделать автоматически в конце создания собственного изображения.

Я полагаю, что для linux механизм тот же, и user_data необходимо повторно активировать в вашем пользовательском образе.

#cloud-boothook сделать это работает, потому что он меняет сценарий от user_data механизм облачного загрузочного, который запускается при каждом запуске.


РЕДАКТИРОВАТЬ:

Вот код для повторной активации запуска в Windows с помощью powershell:

$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\Config.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Plugin") |?{ $_.Name -eq "Ec2HandleUserData"} |%{ $_.State = "Enabled" }
$xdoc.SelectNodes("//Plugin") |?{ $_.Name -eq "Ec2SetComputerName"} |%{ $_.State = "Enabled" }
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile

$configFile = "C:\\Program Files\\Amazon\\Ec2ConfigService\\Settings\\BundleConfig.xml"
[xml] $xdoc = get-content $configFile
$xdoc.SelectNodes("//Property") |?{ $_.Name -eq "AutoSysprep"} |%{ $_.Value = "Yes" }
$xdoc.OuterXml | Out-File -Encoding UTF8 $configFile

(Я знаю вопрос фокуса linux, но это может помочь другим...)

Как я уже проверял, были некоторые данные начальной загрузки в /var/lib/cloud каталог. После того, как я очистил этот каталог, скрипт пользовательских данных работал нормально.

rm -rf /var/lib/cloud/*

Я также столкнулся с той же проблемой на Ubuntu 16.04 HVM AMI. Я поднял вопрос о поддержке AWS, но все еще не смог найти точную причину / ошибку, которая на нее влияет.

Но все же у меня есть кое-что, что может вам помочь.

Перед тем как взять AMI удалите каталог /var/lib/cloud (каждый раз). Затем при создании образа установите его без перезагрузки.

Если эти вещи все еще не работают, вы можете проверить это дальше, заставив пользовательские данные запускаться вручную. Также хвостик /var/log/cloud-init-output.log для статуса облачного init. Он должен заканчиваться чем-то вроде модулей:final, чтобы ваши пользовательские данные запускались. Он не должен застрять на модулях:config.

sudo rm -rf /var/lib/cloud/* sudo cloud-init init sudo cloud-init modules -m final

Я понятия не имею, будут ли вышеуказанные команды работать на CentOS или нет. Я проверил это на Ubuntu.

В моем случае я также попытался удалить каталог /var/lib/cloud, но в нашем случае он не смог выполнить пользовательские данные. Но я придумал другое решение для этого. Мы создали скрипт с вышеприведенными командами и заставили его работать во время загрузки системы.

Я добавил ниже строку в /etc/rc.local, чтобы это произошло.

sudo bash /home/ubuntu/force-user-data.sh || exit 1

Но здесь есть одна загвоздка: он будет запускать скрипт при каждой загрузке, поэтому ваши пользовательские данные будут запускаться при каждой загрузке, подобно # cloud-boothook. Не беспокойтесь, вы можете просто настроить его, просто удалив сам файл force-user-data.sh в конце. Таким образом, ваш force-user-data.sh будет выглядеть примерно так

#!/bin/bash sudo rm -rf /var/lib/cloud/* sudo cloud-init init sudo cloud-init modules -m final sudo rm -f /home/ubuntu/force-user-data.sh exit 0

Я буду признателен, если кто-то может осветить, почему он не может выполнить пользовательские данные.

Это ответ в качестве примера: убедитесь, что в заголовке есть только #!/bin/bash

#!/bin/bash
yum update -y
yum install httpd mod_ssl
service httpd start
chkconfig httpd on

У меня было много проблем с этим. Я предоставлю подробную прогулку.

Я добавил, что я использую terraform для создания экземпляров хостов через конфигурацию запуска и группу автоматического масштабирования.

Я не смог заставить его работать, добавив скрипт в lc.tf

user_data                   = DATA <<
"
#cloud-boothook
#!/bin/bash
echo 'some crap'\'
"
DATA

Я мог бы получить это из пользовательских данных,

wget http://169.254.169.254/latest/user-data

но заметил, что я получаю это с кавычками все еще в этом.

Вот как я заставил его работать: вместо этого я перешел к извлечению его из шаблона, поскольку то, что вы видите, это то, что вы получаете.

user_data                   = "${data.template_file.bootscript.rendered}"

Это означает, что мне также нужно объявить мой файл шаблона следующим образом:

data "template_file" "bootscript" {
  template = "${file("bootscript.tpl")}"

}

Но я все еще получал сообщение об ошибке в облачных журналах инициализации /var/log/cloud-init.log [ПРЕДУПРЕЖДЕНИЕ]: необработанные пользовательские данные не из нескольких частей (text/x-not-multipart): 'Content-Type: text/cloud..."

Затем я нашел эту статью о пользователе, который форматирует данные пользователя. Это имеет смысл, если пользовательские данные могут состоять из нескольких частей, возможно, cloud-init нужны команды cloud-init в одном месте, а скрипт - в другом.

Итак, мой bootscript.tpl выглядит так:

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
echo "some crap"
--//

!/bin/bash

Не оставляйте пробелов в начале строки. Используйте точную команду. В противном случае он может работать в AMAZON Linux AMI, но не в RHEL.

Единственный способ заставить его работать - это добавить # cloud-boothook перед #!/ Bin/bash

Это типичный сценарий пользовательских данных, который устанавливает веб-сервер Apache на вновь созданный экземпляр.

#cloud-boothook
#!/bin/bash

yum update -y 
yum install -y httpd.x86_64 
systemctl start httpd.service 
systemctl enable httpd.service 

без # cloud-boothook он не работает, но с ним работает. Кажется, что у разных пользователей разный опыт. Некоторые могут заставить его работать без него, не зная почему.

В ubuntu 16 удаление /var/lib/cloud/* не работает. Я удалил только экземпляр (ы) из папки / var / lib / cloud /, и тогда все прошло нормально для меня

Я побежал:

sudo rm /var/lib/cloud/instance
sudo rm /var/lib/cloud/instances

Затем я повторил сценарий пользовательских данных, и он работал нормально.

Я использую CentOS и логика для пользовательских данных там проста:

  • В файле /etc/rc.local есть вызов для сценария initial.sh, но сначала он ищет флаг:

    if [ -f /var/tmp/initial ]; then
        /var/tmp/initial.sh &
    fi
    

initial.sh - это файл, который выполняет выполнение пользовательских данных, но в конце концов удаляет флаг. Итак, если вы хотите, чтобы ваш новый AMI снова выполнял пользовательские данные, просто создайте флаг снова перед созданием образа:

touch /var/tmp/initial

просто добавьте -// в конце вашего скрипта пользовательских данных, например:

      #!/bin/bash
#Upgrade ec2 instance
sudo yum update -y 

#Start docker service 
sudo service docker start 

 --//

Пользовательские данные должны выполняться без использования #cloud-boothook (который используется для активации пользовательских данных в кратчайшие сроки во время процесса загрузки).

Я запустил новый Amazon Linux AMI и использовал ваши данные пользователя, а также немного больше:

#!/bin/bash

echo 'bar' > /tmp/bar
echo 'test' > /home/ec2-user/user-script-output.txt
echo 'foo' > /tmp/foo

Это успешно создало три файла.

Скрипты пользовательских данных выполняются как root, поэтому он должен иметь разрешение на создание файлов в любом месте.

Я заметил, что в предоставленном вами коде один пример относится к /home/ec2-user/user-script/output.txt (с подкаталогом) и один пример относится к /home/ec2-user/user-script-output.txt (без подкаталога). Понятно, что команда потерпит неудачу, если вы попытаетесь создать файл в несуществующем каталоге, но ваш пример "Обновления", кажется, показывает, что он действительно работает.

Кроме того, если мы используем интерактивные команды пользователя, такие как

sudo yum install java-1.8.0-devel

Затем нам нужно использовать с такими флагами, как -y

sudo yum install java-1.8.0-devel -y

Вы можете найти это в документации EC2 в разделе "Запускать команды при запуске".

Ссылка: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html#user-data-shell-scripts

Это сработало для меня, вы можете попробовать это

      #!/bin/bash

#Start docker service 
sudo service docker start 
sudo docker start 6f
sudo docker update --restart=always 6f

 --//
Другие вопросы по тегам