Пользовательский AMI Amazon EC2 не запускается при загрузке (пользовательские данные)
Я столкнулся с проблемой при создании пользовательских AMI (изображений) на экземплярах EC2. Если я запускаю экземпляр сервера Windows 2012 по умолчанию с пользовательским сценарием начальной загрузки / пользовательских данных, таким как;
<powershell>
PowerShell "(New-Object System.Net.WebClient).DownloadFile('http://download.microsoft.com/download/3/2/2/3224B87F-CFA0-4E70-BDA3-3DE650EFEBA5/vcredist_x64.exe','C:\vcredist_x64.exe')"
</powershell>
Он будет работать как положено, перейдет по URL, загрузит файл и сохранит его на диске C:.
Но если я настрою экземпляр Windows Server, затем создам из него образ и сохраню его как пользовательский AMI, а затем разверну его с точно таким же сценарием пользовательских данных, он не будет работать. Но если я перейду к экземпляру URL (http://169.254.169.254/latest/user-data
) он покажет, что скрипт успешно импортирован, но не был выполнен.
После проверки журналов ошибок я заметил это регулярно:
Failed to fetch instance metadata http://169.254.169.254/latest/user-data with exception The remote server returned an error: (404) Not Found.
5 ответов
Обновление 15.04.2017: для EC2Launch и Windows Server 2016 AMI
В соответствии с документацией AWS для EC2Launch пользователи Windows Server 2016 могут продолжать использовать постоянные теги, представленные в EC2Config 2.1.10:
Для EC2Config версии 2.1.10 и выше или для EC2Launch вы можете использовать true в пользовательских данных, чтобы включить плагин после выполнения пользовательских данных.
Пример пользовательских данных:
<powershell>
insert script here
</powershell>
<persist>true</persist>
Для последующих ботинок:
Пользователи Windows Server 2016 должны дополнительно включить настройку и включить EC2Launch вместо EC2Config. EC2Config был объявлен устаревшим для AMI Windows Server 2016 в пользу EC2Launch.
Запустите следующую PowerShell, чтобы запланировать задачу Windows, которая будет запускать пользовательские данные при следующей загрузке:
C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 –Schedule
Эта задача отключена после первого запуска. Однако использование тега persist заставляет Invoke-UserData планировать отдельную задачу через Register-FunctionScheduler, чтобы сохранить ваши пользовательские данные при последующих загрузках. Вы можете убедиться в этом на C:\ProgramData\Amazon\EC2-Windows\Launch\Module\Scripts\Invoke-Userdata.ps1
,
Дальнейшее устранение неисправностей:
Если у вас возникают дополнительные проблемы со сценариями пользовательских данных, вы можете найти журналы выполнения пользовательских данных на C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log
для экземпляров, полученных из базы AMI WS 2016.
Оригинальный ответ: для EC2Config и более старых версий Windows Server
Выполнение пользовательских данных автоматически отключается после начальной загрузки. Когда вы создали свое изображение, вероятно, что выполнение уже было отключено. Это настраивается вручную в C:\Program Files\Amazon\Ec2ConfigService\Settings\Config.xml
,
Документация для "Настройка экземпляра Windows с использованием службы EC2Config" предлагает несколько вариантов:
Программно создать запланированное задание для запуска при запуске системы, используя
schtasks.exe /Create
и укажите назначенную задачу для сценария пользовательских данных (или другого сценария) вC:\Program Files\Amazon\Ec2ConfigServer\Scripts\UserScript.ps1
,Программно включить плагин пользовательских данных в Config.xml.
Пример из документации:
<powershell>
$EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\Config.xml"
$xml = [xml](get-content $EC2SettingsFile)
$xmlElement = $xml.get_DocumentElement()
$xmlElementToModify = $xmlElement.Plugins
foreach ($element in $xmlElementToModify.Plugin)
{
if ($element.name -eq "Ec2SetPassword")
{
$element.State="Enabled"
}
elseif ($element.name -eq "Ec2HandleUserData")
{
$element.State="Enabled"
}
}
$xml.Save($EC2SettingsFile)
</powershell>
- Начиная с EC2Config версии 2.1.10, вы можете использовать
<persist>true</persist>
включить плагин после выполнения пользовательских данных.
Пример из документации:
<powershell>
insert script here
</powershell>
<persist>true</persist>
Другое решение, которое мне помогло, - запустить Sysprep с EC2Launch.
Проблема заключается в том, что AWS не восстанавливает маршрут к службе профилей (169.254.169.254) в вашем пользовательском AMI. Смотрите ответ SanjitPatel в этом посте. Поэтому, когда я пытался использовать свой пользовательский AMI для создания спотовых запросов, мои новые экземпляры не могли найти данные пользователя.
Завершение работы с Sysprep, по сути, заставляет AWS заново выполнять всю работу по настройке экземпляра, как если бы он был запущен впервые. Поэтому, когда вы создаете свой экземпляр, выключаете его с помощью Sysprep, а затем создаете свой собственный AMI, AWS правильно настроит маршрут службы профилей для новых экземпляров и выполнит ваши пользовательские данные. Это также позволяет избежать ручного изменения задач Windows и выполнения пользовательских данных при последующих загрузках, как это делает тег persist.
Вот быстрый шаг за шагом:
- Создайте экземпляр, используя один из AWS Windows AMI (Windows Server 2016 Nano Server не поддерживает Sysprep) и передавая нужные пользовательские данные (это может быть необязательным, но хорошо, чтобы убедиться, что сценарии установки проводов AWS правильно обрабатывают пользовательские данные).
- Настройте свой экземпляр по мере необходимости.
- Закройте свой экземпляр с помощью Sysprep. Просто откройте приложение EC2LaunchSettings и нажмите "Завершение работы с Sysprep". Полные инструкции здесь.
- Создайте свой собственный AMI из экземпляра, который вы только что закрыли.
- Используйте свой пользовательский AMI для создания других экземпляров, передавая пользовательские данные при создании экземпляра. Пользовательские данные будут выполнены при запуске экземпляра. В моем случае я использовал экран Spot Request, в котором было текстовое поле User Data.
Надеюсь это поможет!
В конце начального сценария начальной загрузки (UserData) просто добавьте тег persist, как показано ниже. Работает отлично.
<powershell>
insert script here
</powershell>
<persist>true</persist>
Для тех людей, которые пришли сюда из Google и используют экземпляр Server 2016, кажется, что это больше невозможно.
На Server2016 нет службы ec2config, поэтому вы не можете использовать флаг постоянства.
<persist>true</persist>
Описано в посте Энтони Ниса.
Server 2016 использует EC2Launch, и я еще не видел, как можно запускать скрипт при каждой загрузке. Вы можете запустить скрипт при первой загрузке, но последующие загрузки не запустят его.
Я добавил ниже сценарий powershell для запуска во время процесса выпечки AMI, который помог мне решить эту проблему. Это был сервер Windows 2019.
$EC2LaunchInitInstance = "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1"
$EC2LaunchSysprep = "C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\SysprepInstance.ps1"
Invoke-Expression -Command "$EC2LaunchInitInstance -Schedule"
Invoke-Expression -Command "$EC2LaunchSysprep -NoShutdown"