
Tenho mais de 80 hosts que executam meu aplicativo e estou atualizando um manual ansible existente há muito tempo para alterar nosso balanceador de carga. Em nossa configuração atual do balanceador de carga, os hosts podem ser adicionados/removidos do balanceador de carga em uma única execução, desembolsando para a AWS CLI. No entanto, estamos mudando para um balanceador de carga configurado em alguns de nossos próprios hosts e colocaremos e retiraremos hosts manipulando arquivos de texto nesses hosts usando ansible. Essencialmente, preciso de um loop interno em diferentes hosts em um manual, ao usar Serial.
Estou tendo problemas para estruturar o manual de forma que eu possa distribuir blockinfile
comandos para hosts em grupo tag_Type_edge
durante a implantação nos 80 tag_Type_app
hosts com serial: 25%.
Aqui está o que eu quero ser capaz de fazer:
---
- hosts: tag_Type_app
serial: "25%"
pre_tasks:
- name: Gathering ec2 facts
action: ec2_metadata_facts
- name: Remove from load balancers
debug:
msg: "This is where I'd fan out to multiple different hosts from group tag_Type_edge to manipulate
text files to remove the 25% of hosts from tag_Type_app from the load balancer"
tasks:
- name: Do a bunch of work to upgrade the app on the tag_Type_app machines while out of the load balancer
debug:
msg: "deploy new code, restart service"
post_tasks:
- name: Put back in load balancer
debug:
msg: "This is where I'd fan out to multiple different hosts from group tag_Type_edge to manipulate
text files to *add* the 25% of hosts from tag_Type_app back into the load balancer"
Como posso estruturar isso para permitir o loop interno tag_Type_edge
ao usar serial: 25% em todas as tag_Type_app
caixas?
Responder1
No Ansible, executar uma tarefa em um host, mas em nome de outro, poderia exigir o uso de uma coisa inteligente chamadadelegação. Na verdade, um exemplo nos documentos é retirar hosts de um balanceador de carga.
Como acontece com qualquer tarefa, ela pode ser executada várias vezes em loop em alguns nomes de host. Não o ciclo de jogo, mas um ciclo de tarefa. Um exemplo ajuda, adotando seu esqueleto:
---
- name: Example loop over load balancers for each app server
hosts: tag_Type_app
serial: "25%"
pre_tasks:
- name: Gathering ec2 facts
action: ec2_metadata_facts
- name: Remove from load balancers
debug:
msg: "Remove app instance {{ inventory_hostname }} from edge node {{ item }}"
delegate_to: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'tag_Type_edge') }}"
tasks:
- name: Do a bunch of work to upgrade the app on the tag_Type_app machines while out of the load balancer
debug:
msg: "deploy new code, restart service"
post_tasks:
- name: Put back in load balancer
debug:
msg: "Add app instance {{ inventory_hostname }} to edge node {{ item }}"
delegate_to: "{{ item }}"
loop: "{{ query('inventory_hostnames', 'tag_Type_edge') }}"
inventário_hostnames é um plugin de pesquisa que cria padrões de inventário, qualquer padrão pode ir até lá.
Algumas coisas complicadas sobre isso. Qualquer falha no loop "edge" fará com que o host "app" falhe. O que deixará um estado parcial de alguns hosts de borda habilitados e outros não. A menos que você tenha algum mecanismo de retorno, como um bloco com resgate que o desfaz.
Como um ciclo de tarefas, alguns recursos relacionados ao inventário e ao jogo não serão aplicados. Você não pode restringir ainda mais os hosts de borda --limit
na linha de comando. Nem você pode serial
agrupá-los, isso já está em uma peça.
Além disso, ele executará um número relativamente grande de tarefas, pelo menos app ✕ edge ✕ 2. Isso pode ser um pouco lento. Poderia mitigar um pouco aumentando os garfos.
Se o seu balanceador de carga de vários hosts tivesse um único plano de controle, não seria necessário tocar em tantos hosts. Fazendo uma tarefa por servidor de aplicativos. Você pode não estar preparado para isso no momento, mas há algo a considerar.