Implantação de alta disponibilidade com Ansible
-
21-12-2019 - |
Pergunta
Estou usando o Ansible para implantar pares de instâncias NGinx/Tomcat e estou tentando melhorar a disponibilidade durante a implantação.
Uma instância lógica é 1 NGinx + 1 Tomcat:Tenho 4 instâncias lógicas espalhadas por 2 locais distantes (veja o arquivo hosts abaixo).
Eu lanço um manual chamado deploy.xml que se parece com isto:
- hosts: ngx-servers
pre_tasks:
- include: tasks/remove-server.yml
roles:
- role: ngx-server
- hosts: app-servers
roles:
- role: app-server
- hosts: ngx-servers
tasks:
- include: tasks/add-server.yml
O que eu quero é implantar 50% das minhas 4 instâncias lógicas antes de implantar as outras (e parar tudo se algo der errado).Uma solução poderia ser direcionar primeiro montigny-app-servers/montigny-ngx-servers (em vez de app-servers/ngx-servers) e depois o segundo local, mas eu precisaria duplicar o conteúdo do playbook (e assim por diante, se precisar adicionar outros locais de servidor).
Alguma idéia de fazer isso corretamente?
Aqui está meu arquivo hosts:
#
# Serveurs d'application
#
# Montigny
[montigny-app-servers]
mo-app-server-1 ansible_ssh_host=1y.domain.fr ansible_ssh_user=devops
mo-app-server-2 ansible_ssh_host=2y.domain.fr ansible_ssh_user=devops
# Bievre
[bievre-app-servers]
bi-app-server-1 ansible_ssh_host=1b.domain.fr ansible_ssh_user=devops
bi-app-server-2 ansible_ssh_host=2b.domain.fr ansible_ssh_user=devops
# Tous
[app-servers:children]
montigny-app-servers
bievre-app-servers
#
# Serveurs NGinx
#
# Montigny
[montigny-ngx-servers]
mo-ngx-server-1 ansible_ssh_host=1y.domain.fr ansible_ssh_user=devops
mo-ngx-server-2 ansible_ssh_host=2y.domain.fr ansible_ssh_user=devops
# Bievre
[bievre-ngx-servers]
bi-ngx-server-1 ansible_ssh_host=1b.domain.fr ansible_ssh_user=devops
bi-ngx-server-2 ansible_ssh_host=2b.domain.fr ansible_ssh_user=devops
# Tous
[ngx-servers:children]
montigny-ngx-servers
bievre-ngx-servers
Solução
Uma solução poderia ser direcionar primeiro montigny-app-servers/montigny-ngx-servers (em vez de app-servers/ngx-servers) e depois o segundo local
Isso é o que fazemos, algumas mudanças:
Adicione grupos geolocalizados:
[Montigny-servers:children]
montigny-app-servers
montigny-ngx-servers
[bievre-servers:children]
bievre-app-servers
bievre-ngx-servers
Então você pode executar seu manual nos subconjuntos com as opções -l/--limnit
$ ansible-playbooks -i inventory site.yml -l Montigny-servers && \
ansible-playbooks -i inventory site.yml -l bievre-servers
dessa forma, ele primeiro executará instâncias lógicas de Montigny e, se tudo correr bem (saída 0), executará o manual para instâncias bievre
Encontre mais exemplos:http://docs.ansible.com/playbooks_best_practices.html#what-this-organization-enables-examples
Outras dicas
Concordo com a ideia de colocar seus hosts em grupos separados para que você possa executar comandos primeiro em um grupo e depois no outro.
Você deve ser capaz de colocar isso em um manual - se você criar as ações fundamentais em um script de inclusão, poderá criar um manual que terá várias seções '- hosts', cada uma das quais chamará o script de inclusão.
Isso seria algo como:
---
- hosts: firstgroupname
tasks:
- include: pathandnameofincludescript.yaml
- hosts: secondgroupname
tasks:
- include: pathandnameofincludescript.yaml
e seu script de inclusão seria algo como:
---
- name: action 1
command: echo hello world
- name: action 2
command: echo hello again
Observe a diferença de recuo para scripts de inclusão - é muito importante!YAML pode ser irritante às vezes....
Ok, aqui está o que acho que você realmente quer.
Você pode usar o serial palavra-chave para dizer quantos hosts o ansible deve gerenciar ao mesmo tempo em uma jogada.Portanto, no exemplo abaixo, o ansible executaria as jogadas apenas em dois hosts por vez.
Por padrão, o anisble continuará executando as peças mesmo se as duas primeiras máquinas falharem, então você pode usar o max_fail_percentage palavra-chave para definir a porcentagem de falhas aceitáveis antes de parar.No exemplo abaixo, o Ansible irá parar se 1% das máquinas falharem.
Fonte: http://docs.ansible.com/playbooks_delegation.html#rolling-update-batch-size
- hosts: app-servers`
serial: 2
max_fail_percentage: 1
roles:
- role: deploy-env
E então, na sua função de implantação, tenha:
- name: remove from LB
include: remove-server.yml
delegate_to: paired_nginx_box
/* app-server tasks */
- name: add to LB
include: add-server.yml
delegate_to: paired_nginx_box