Скрипты пользовательских данных не работают на моем пользовательском 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
--//