
Tengo más de 80 hosts que ejecutan mi aplicación y estoy actualizando un manual de estrategias ansible existente desde hace mucho tiempo para cambiar nuestro balanceador de carga. En nuestra configuración actual del balanceador de carga, los hosts se pueden agregar o eliminar del balanceador de carga en una sola jugada mediante el pago a la CLI de AWS. Sin embargo, estamos cambiando a un balanceador de carga configurado en algunos de nuestros propios hosts, y entraremos y sacaremos hosts manipulando archivos de texto en esos hosts usando ansible. Esencialmente, necesito un bucle interno sobre diferentes hosts dentro de un libro de jugadas, mientras uso Serial.
Tengo problemas para estructurar el libro de jugadas de modo que pueda distribuir blockinfile
comandos a los hosts en el grupo tag_Type_edge
mientras los implemento en los 80 tag_Type_app
hosts con serial: 25%.
Esto es lo que quiero poder hacer:
---
- 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"
¿Cómo puedo estructurar esto para permitir el bucle interno tag_Type_edge
mientras uso serial: 25% en todas las tag_Type_app
cajas?
Respuesta1
En Ansible, ejecutar una tarea en un host, pero en nombre de otro, podría requerir el uso de una cosa inteligente llamadadelegación. De hecho, un ejemplo en los documentos es sacar hosts de un balanceador de carga.
Como ocurre con cualquier tarea, se puede ejecutar varias veces en un bucle en algunos nombres de host. No el ciclo de reproducción, sino el ciclo de tareas. Un ejemplo ayuda, adoptando su 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') }}"
inventario_hostnames es un complemento de búsqueda que realiza patrones de inventario, cualquier patrón puede ir allí.
Un par de cosas complicadas sobre esto. Cualquier falla en el bucle "borde" hará que falle el host de la "aplicación". Lo que dejará un estado parcial de algunos hosts perimetrales habilitados y otros no. A menos que tengas algún mecanismo de retroceso, como un bloque con un rescate que lo deshaga.
Como ciclo de tareas, algunas funciones relacionadas con el inventario y el juego no se aplicarán. No puede restringir más los hosts perimetrales --limit
en la línea de comando. Tampoco puedes usar serial
para agruparlos, esto ya está en una obra.
Además, ejecutará una cantidad relativamente grande de tareas, al menos la aplicación ✕ edge ✕ 2. Esto puede ser un poco lento. Podría mitigar un poco aumentando las bifurcaciones.
Si su balanceador de carga de múltiples hosts tuviera un único plano de control, no necesitaría tocar tantos hosts. Realizar una tarea por servidor de aplicaciones. Puede que no estés preparado para esto en este momento, pero es algo que debes considerar.