Назад | Перейти на главную страницу

Прокручиваемое обновление с марионеткой, ансиблем или тканью

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

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

В настоящий момент я использую простой сценарий bash, в котором мне нужно вручную дождаться, пока один причал снова не вернется в сеть, прежде чем перезапускать следующий причал и так далее.

Теперь bash не очень оптимален для такого рода вещей, и я надеюсь, что есть инструменты, лучше подходящие для автоматизации всей задачи. Например. Я мог бы использовать простой URL-адрес ping http://jetty-number-n.com/ping который отвечает OK (200), если n-я пристань в сети.

Как я мог решить эту задачу и с помощью какого инструмента?

Благодаря @ceejayoz я нашел скользящее обновление для анзибля. Но это все еще неоптимально, так как мне нужно было бы установить фиксированный тайм-аут.

С Ansible это довольно просто. Грубый псевдозависимый сценарий:

---
  - hosts: your_server_group
    sudo: yes
    serial: 1
    tasks:
      - shell: reboot now
      - wait_for: port=22

У соли есть удобный вариант замеса.

salt -G 'os:RedHat' --batch-size 25% service.restart jetty

Перезапустите службу причала на 25% серверов RedHat за раз.

salt -N group1 -b 2 system.restart

Перезагрузите серверы в заранее определенной «группе1», по 2 за раз.

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

Puppet больше ориентирован на одновременное развертывание изменений / перезапуск систем - демон Puppet запускается на каждом клиенте и проверяет центральный сервер с заданным интервалом (по умолчанию каждые полчаса). Если вы хотите изменить расписание по умолчанию, вы обычно используете другой механизм для вызова марионетки.

Если вы согласны с одновременным перезапуском, то перезапуск службы - это вопрос определения манифеста с помощью

file { 'your_war_file.war':
    ensure  => file,
    source  => "puppet:///...",
}
service { 'jetty':
    subscribe  => File['your_war_file.war'],
    hasrestart => True,
}

ресурсов, затем вытолкнуть манифест и позволить Puppet сделать свое дело. Это предполагает, что вы не против звонить

/etc/init.d/jetty restart

что может быть или не быть приемлемым или даже возможным.

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

Проверять, выписываться http://forge.puppetlabs.com/однако, чтобы узнать, решил ли кто-нибудь еще аналогичную проблему.

Puppet имеет концепцию Сервисы и Заказ. Но марионетка работает на одном сервере. Таким образом, он не имеет представления о других системах, на которых он работает.

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

Вы также можете написать собственную библиотеку для марионетки, которая будет рассматривать один сервер как главный управляющий сервер, но вместо использования сценариев инициализации. Он может использовать настраиваемую библиотеку ruby ​​для управления службами каждого сервера. Это немного сложнее в настройке, но может работать.

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

Вы можете развернуть свои файлы WAR на пристани, используя марионетку, используя обычный «файловый» ресурс и определенный ресурс, который вы инициализируете для каждого приложения.

Puppet будет загружен с указанного вами URL-адреса (на вашем Мастере Марионеток). Jetty может повторно развернуть файлы WAR без перезапуска, если время модификации файла WAR изменилось. Итак, если ваш манифест создает копию в $JETTY_HOME/webapps он должен быть автоматически получен Jetty. Таким образом (или нажав context.xml) вам не нужно вручную перезапускать Jetty.

Чтобы загрузить файл WAR из вашего мастера марионеток в каталог приложений, вам понадобится следующий манифест (заменяющий $ JETTY_HOME):

define jetty::deployment($path) {

  notice("Deploying ${name} to http://$hostname:${appserver-jetty::port}/"),
  include jetty,

  file { "$JETTY_HOME/webapps/${name}.war":
    owner => 'root',
    source => $path,
  }
}

и вам нужно проинструктировать свои узлы получать определенную версию вашего приложения один за другим (после того, как вы убедитесь, что оно успешно запустилось на одном из узлов). Это можно сделать с помощью ENC (классификатор внешнего узла) или, если вы не используете ENC, изменив раздел site.pp для каждого узла (или группы узлов):

node jetty-node1 {
   jetty::deployment { "servlet":
     path => '/srv/application/Servlet-1.2.3.war'
   }
},
node jetty-node2 {
   jetty::deployment { "servlet":
     path => '/srv/application/Servlet-2.0.1.war'
   }
}

В include jetty Строка необходима, только если вы хотите управлять конфигурацией Jetty через марионетку, например,. https://github.com/maestrodev/puppet-jetty и этому определенному ресурсу требуется переменная appserver-jetty :: $ port. В этом примере показан простейший способ точно контролировать, какая версия приложения обслуживается каким узлом. Таким образом, вы можете создать сценарий развертывания на основе ваших проверок работоспособности и развернуть на node2 только после того, как node1 успешно запустит новую версию.

Этот пример предназначен только для демонстрации концепции.

Возможно, вы захотите проверить эти дополнительные ресурсы для получения дополнительной информации и идей: При перезагрузке контекстов: https://stackoverflow.com/questions/13965643/auto-reloading-war-in-jetty-standalone

Это для развертывания и управления tomcat, но идеи (и манифесты) аналогичны: http://www.tomcatexpert.com/blog/2010/04/29/deploying-tomcat-applications-puppet

Это для ИМО, лучшей альтернативы прямому копированию файлов WAR - с использованием собственных пакетов (например, RPM) для развертывания вашего приложения: http://www.slideshare.net/actionjackx/automated-java-deployments-with-rpm