Нажатие на несколько экземпляров EC2 на балансировщике нагрузки

Я пытаюсь найти хороший способ вытолкнуть новую фиксацию для группы экземпляров сервера EC2 за ELB (балансировщик нагрузки). Каждый экземпляр запускает Nginx и PHP-FPM

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

  • Dev выполняется на локальной машине
  • После того, как изменения будут готовы, я выполняю "начальный хозяин" git, чтобы нажать изменения в BitBucket (где я размещаю все мои репозитории git)
  • После нажатия на битбакет, я хотел бы иметь новую версию вытесняется во все экземпляры EC2 одновременно.
  • Я хотел бы сделать это, не имея SSH для каждого экземпляра (Очевидно).

Есть ли способ настроить удаленные серверы для приема удаленного нажатия? Есть ли лучший способ сделать это?

Ответ 1

Да, я делаю это все время (с тем же стеке приложений).

  • Используйте базовый AMI из надежного источника, например, по умолчанию "Amazon Linux" или сканируйте свой собственный.

  • Как часть конфигурации запуска, используйте поле "пользовательские данные" для загрузки процесса инициализации при загрузке. Это может быть так же просто, как оболочка script, которая запускает yum install nginx php-fpm -y и копирует файлы из ведра S3 или вытягивает из вашего репо. В AMA, созданная Amazon, также включена поддержка сценариев cloud-init, если вам требуется немного больше гибкости. Если вам нужна еще большая мощность, вы можете использовать инструмент управления изменениями и оркестровки, например Puppet, Chef или Salt (мой личный фаворит).

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

    • В полной мере используйте облако и просто создайте совершенно новый парк экземпляров, которые захватывают новый код при загрузке. Затем вы переворачиваете балансировщик нагрузки, чтобы указать на новый флот. Это мгновенно и дает вам действительно быстрый способ вернуться к старому флоту, если что-то пойдет не так. Через несколько часов (или дней) вы затем открутите старые экземпляры.
    • Вы можете использовать инструмент, например Fabric или Capistrano, чтобы выполнить параллельное развертывание "push" ко всем экземплярам сразу. Как правило, это просто повторное выполнение того же script, что серверы запускались при загрузке. Salt and Puppet MCollective также обеспечивают аналогичную функциональность, которая объединяется с их базовым обеспечением "pull".

Ответ 2

Вариант 1

Только проблема, вам нужно будет поддерживать список компьютеров для запуска обновления.

Другой вариант

Имейте cron задание, чтобы вытащить из вашего аккаунта bitbucket. на регулярной основе.

Ответ 3

Инструментом для этого задания является Capistrano.

Я использую потрясающий жемчуг под названием capistrano-ec2group, чтобы сопоставить роли capistrano с группами безопасности EC2.

Это означает, что вам нужно только применить к вашим экземплярам группу безопасности EC2 (например, app-web или app-db), чтобы capistrano знал, что им нужно развернуть.

Это означает, что вам не нужно вести список IP-адресов сервера в своем приложении.

Изменение вашего рабочего процесса будет заключаться в том, что вместо того, чтобы сосредоточиться на автоматизации развертывания при нажатии на битбакет, вы будете нажимать и выполнять

cap deploy

Если вы действительно не хотите делать шаги, сделайте псевдоним: D

alias shipit=git push origin master && cap deploy

Ответ 4

Это решение основывается на идее E_p. E_p говорит, что проблема в том, что вам нужно будет поддерживать список серверов где-нибудь, чтобы сообщить каждому серверу, чтобы вытащить новое обновление. Если бы это был я, я бы просто использовал теги в ec2, чтобы определить группу серверов (например, "Role = WebServer" ). Таким образом, вы можете просто использовать интерфейс командной строки ec2, чтобы перечислить экземпляры и запустить команду pull для каждого из них.

for i in \
    `ec2din --filter "tag-value=WebServer" --region us-east-1 \
    | grep "running" \
    | cut -f17`\
; do ssh $i "cd /var/www/html && git pull origin"; done

Примечание. Я проверил код, который извлекает IP-адреса всех помеченных экземпляров и подключается к ним через ssh, но не определенную команду git pull.

Вам нужны инструменты amazon cli, где бы вы ни захотели, чтобы они запускались, а также ключи ssh, установленные для серверов, которые вы пытаетесь обновить. Не уверен, какие возможности битбакет, но я предполагаю, что этот код не сможет работать там. Вам нужно либо сделать, как предлагает E_p, и направить ваши обновления на отдельный экземпляр управления, и включить этот код в свой крюк после фиксации, ИЛИ, если вы хотите сохранить головную боль, которую вы можете сделать, как Я сделал и просто установил инструменты CLI на свой локальный компьютер и запускаю его вручную, когда вы хотите развернуть обновления.

Кредит AdamK за ответ на другой вопрос, который упростил извлечение ip-адреса из вывода ec2din и повторить результаты: Как я могу убить все мои EC2 экземпляры из командной строки?

Справочник инструментов CLI EC2: http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/Welcome.html

Ответ 5

Лучше всего на самом деле использовать AMI для развертывания.

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

Для развертывания я использую группу автомасштабирования за балансировщиком нагрузки (не требуется динамическое масштабирование или что-то еще). В простой настройке, где у вас есть фиксированное количество серверов в группе автомасштабирования (например, 10 экземпляров). Я бы изменил AMI, связанный с группой автомасштабирования, на новый AMI, а затем запустил несколько экземпляров за раз в группе автомасштабирования. Итак, скажем, у меня есть 10 экземпляров, и я завершаю два, чтобы удалить их до 8 экземпляров. Группа автомасштаба настроена на минимум 10 экземпляров, поэтому она автоматически запускает два новых экземпляра с новым AMI. Затем вы можете продолжать удалять экземпляры с любой скоростью, имеющей смысл для вашего уровня нагрузки, чтобы не влиять на производительность вашего флота.

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

Если вы хотите сделать это полностью автоматизированным (т.е. непрерывное развертывание), тогда вам может понадобиться использовать систему сборки, такую ​​как Jenkins, которая позволит совершить коммит, чтобы начать сборку, а затем запустить необходимое AWS команды для создания AMI и их развертывания.

Ответ 6

Я ищу решение той же проблемы. Я наткнулся на этот пост и подумал, что это интересный подход

https://gist.github.com/Nilpo/8ed5e44be00d6cf21f22#pc

Перейдите к "Отправка изменений на несколько серверов"

По сути, идея состоит в том, чтобы создать еще один удаленный сервер, назовите его "производственный" или как хотите, а затем добавьте несколько URL (ip всех серверов) в этот пульт. Это может быть сделано путем редактирования .git/config

Затем вы можете запустить git push production <branch> и он должен распространяться на все URL, перечисленные в разделе "production"

Одним из требований к этому подходу является то, что репо на серверах должны быть чистыми репозиториями, а для обновления рабочего дерева вам понадобится хук post-receive.

Вот пример того, как это сделать: Настройка перехвата после получения для чистого репо