Isso é bastante fácil com o Ansible. Playbook pseudo-ansiável:
---
- hosts: your_server_group
sudo: yes
serial: 1
tasks:
- shell: reboot now
- wait_for: port=22
Eu tenho alguns servidores do Jetty com um loadbalancer antes deles. Agora quero atualizar meu aplicativo sem tempo de inatividade. Quando um jetty desce e não está mais acessível, o balanceador de carga o remove automaticamente da lista, portanto, esse não é o problema.
O principal problema é evitar o tempo de inatividade: então, tenho que garantir que apenas um jetty esteja reiniciando de cada vez - ou tenha certeza de que pelo menos N jettys estejam online!
No momento, estou usando um script bash simples, no qual preciso esperar manualmente para que um jetty volte a ficar on-line novamente antes de reiniciar o próximo jetty e assim por diante.
Agora bash não é muito ideal para esse tipo de coisa e eu espero que existam ferramentas mais adequadas para automatizar toda a tarefa. Por exemplo. Eu poderia usar um simples ping URL http://jetty-number-n.com/ping
que responde OK (200) se o n-ésimo jetty estiver on-line.
Como eu poderia resolver essa tarefa e com qual ferramenta?
Graças a @ceejayoz, encontrei atualização contínua para comentários. Mas ainda é sub-óptimo como eu precisaria definir um tempo limite fixo.
O Salt possui uma opção em lote conveniente.
salt -G 'os:RedHat' --batch-size 25% service.restart jetty
Reinicie o serviço de jetty em 25% dos servidores RedHat por vez.
salt -N group1 -b 2 system.restart
Reinicie os servidores no "group1" predefinido, 2 por vez.
O Puppet tem os conceitos de Serviços e Encomenda . Mas o fantoche é executado em um único servidor. Por isso, não há informações sobre outros sistemas em execução.
Se você quiser usar o fantoche, você pode ter um servidor de controle mestre com um script de inicialização para gerenciar os serviços de cada servidor. Portanto, o script de inicialização executaria a reinicialização em cada servidor e retornaria o código de status. Você poderia fazer isso e encadear cada serviço a partir deste servidor e ordenar, encadear ou notificar e assinar para passar para o próximo.
Você também pode escrever uma biblioteca personalizada para o fantoche, que tratará um servidor como o servidor de controle mestre, mas em vez de usar os scripts de inicialização. Ele pode usar uma biblioteca Ruby personalizada para gerenciar os serviços de cada servidor. É um pouco mais complexo de configurar, mas poderia funcionar.
Eu uso o Puppet no trabalho agora, mas como o primeiro pôster respondeu, isso não parece uma primeira tarefa ideal para o Puppet. Eu não posso falar com ansible (embora eu queira começar a testá-lo).
O Puppet é voltado mais para a implementação de alterações / reinicialização de sistemas simultaneamente - um daemon do Puppet é executado em cada cliente e verifica em um servidor central em um intervalo agendado (padrão a cada meia hora). Se você quiser contrariar o agendamento padrão, você normalmente usa um mecanismo diferente para chamar fantoche.
Se você estiver certo com uma reinicialização simultânea, reiniciar um serviço é uma questão de definir um manifesto com
file { 'your_war_file.war':
ensure => file,
source => "puppet:///...",
}
service { 'jetty':
subscribe => File['your_war_file.war'],
hasrestart => True,
}
diretivas de recursos, em seguida, enviando o manifesto e permitindo que o Puppet faça o que ele quer. Isso pressupõe que você está bem com a chamada
/etc/init.d/jetty restart
que pode ou não ser aceitável ou até mesmo possível.
Você também pode definir seus próprios tipos de recursos personalizados para isso, o que definitivamente está além do escopo de uma simples tarefa de marionete pela primeira vez.
Confira o link , para ver se alguém resolveu um problema semelhante.
A tarefa que você quer fazer pode ser feita usando ansible, e definitivamente poderia ser feito usando Puppet. Vou me concentrar em como realizá-lo usando fantoche.
Você pode implantar seus arquivos WAR no Jetty, usando o fantoche, usando um recurso de "arquivo" normal e um recurso definido inicializado para cada aplicativo.
O Puppet será baixado do URL que você especificar (no seu Puppet Master). O Jetty é capaz de reimplementar arquivos WAR sem reiniciar, se o horário de modificação do arquivo WAR for alterado. Portanto, se o seu manifesto criar uma cópia em $JETTY_HOME/webapps
, ele deverá ser automaticamente selecionado pelo Jetty. Desta forma (ou tocando no context.xml) você não precisa reiniciar manualmente o Jetty.
Para baixar o arquivo WAR do seu Puppet Master para o seu Application Directory, você precisará do seguinte manifesto (substituindo $ 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,
}
}
e você precisa instruir seus nós para obter uma versão específica do seu aplicativo, um após o outro (depois de ter certeza de que ele foi iniciado com êxito em um dos nós). Isso pode ser feito usando um ENC (classificador de nó externo) ou, se você não estiver usando o ENC, modificando o seu Seção site.pp para cada nó (ou grupo de nós):
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'
}
}
A linha include jetty
é necessária apenas se você quiser gerenciar sua configuração do Jetty por meio do fantoche, por exemplo. link e este recurso definido precisa de uma variável appserver-jetty :: $ port. Este exemplo mostra a maneira mais simples de controlar exatamente qual versão do Aplicativo é fornecida por qual nó. Dessa forma, você pode fazer o script da implantação, com base nas suas verificações de integridade, e implantar no node2 somente após o nó 1 estar executando com êxito a nova versão.
Este exemplo é apenas para demonstrar o conceito.
Você pode querer verificar esses recursos adicionais para mais informações e ideias: Ao recarregar os contextos: link
Isso é para implantação e gerenciamento do tomcat, mas as ideias (e os manifestos) são semelhantes: link
Esta é uma alternativa melhor para copiar diretamente os arquivos WAR - usando pacotes nativos (por exemplo, RPM) para implantar seu aplicativo: link