![Plantilla de balanceador de carga Ansible para múltiples centros de datos](https://rvso.com/image/658734/Plantilla%20de%20balanceador%20de%20carga%20Ansible%20para%20m%C3%BAltiples%20centros%20de%20datos.png)
Estoy migrando la gestión de una configuración de varios centros de datos existente a Ansible, pero no estoy seguro de cuál es la mejor manera de modelarlo, ya que soy nuevo en esto.
Tengo tres centros de datos D1, D2 y D3. En cada uno, la misma configuración se repite de forma idéntica:
- Unequilibrador de carga nginx(lb.D[n]) vinculado a una IP pública
- Dosservidores de aplicaciones(como[1-2].D[n]) que reciben tráfico únicamente del balanceador de carga local
- Un esclavo (solo lectura)servidor de base de datos(db.D[n]) desde el cual leen ambos servidores de aplicaciones.
El archivo de hosts que creé hasta ahora se parece a esto:
# DC1 -----------
[dc_1_webservers]
10.43.0.10
[dc_1_appservers]
10.43.0.20
10.43.0.21
[dc_1_dbservers]
10.43.0.30
[dc_1:children]
dc_1_webservers
dc_1_appservers
dc_1_dbservers
# DC2 -----------
[dc_2_webservers]
10.43.10.10
[dc_2_appservers]
10.43.10.20
10.43.10.21
[dc_2_dbservers]
10.43.10.30
[dc_2:children]
dc_2_webservers
dc_2_appservers
dc_2_dbservers
# DC3 -----------
[dc_3_webservers]
10.43.20.10
[dc_3_appservers]
10.43.20.20
10.43.20.21
[dc_3_dbservers]
10.43.20.30
[dc_3:children]
dc_3_webservers
dc_3_appservers
dc_3_dbservers
[webservers:children]
dc_1_webservers
dc_2_webservers
dc_3_webservers
[appservers:children]
dc_1_appservers
dc_2_appservers
dc_3_appservers
He dejado deliberadamente solo direcciones IP aquí porque me gustaría entender cómo funcionaría una solución Ansible pura, en lugar de recurrir a DNS.
El problema es completar correctamente el proxy inverso de nginx en sentido ascendente, de modo quesolo se agregan los servidores de aplicaciones locales para cada DCcuando se ejecuta la función nginx y la plantilla del archivo de configuración se copia en la máquina del equilibrador de carga. En particular, ¿es posible hacer algo como esto?
# file /etc/nginx/sites-enabled/loadbalancer.conf in lb.D[n] (i.e. lb.D2)
upstream backend {
# Iterate over the app servers in the current data center (i.e. D2)
{% for host in [datacenters][current_datacenter][appservers] %}
# Add each local app server IP to the load balancing pool
# (i.e. 10.43.10.20 and 10.43.10.21 for DC2)
server {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }};
{% endfor %}
}
Por un lado, no estoy seguro de que el archivo hosts tenga completamente sentido (¿debería agregar variables a las entradas individuales? En la configuración actual no puedo hacer algo como [dc][3][appservers], aunque no estoy seguro). ahí está la solución).
¡Muchas gracias!
EDITAR 1:
La estructura del libro de jugadas es la siguiente:
main.yml
hosts
vars.yml
servers/
webservers.yml
appservers.yml
roles/
base/
files/
ssh/
newrelic/
tasks/
main.yml
handlers/
main.yml
webserver/
files/
ssl_certs/
templates/
nginx/
loadbalancer.j2
tasks/
main.yml
handlers/
main.yml
appserver/
files/
pip/
requirements.txt
templates/
supervisor/
gunicorn.j2
tasks/
main.yml
handlers/
main.yml
El punto de entrada de main.yml tiene solo dos líneas:
---
- include: servers/webservers.yml
- include: servers/appservers.yml
webservers.yml recopila datos sobre servidores de aplicaciones (pensé que sería necesario para lograr mi objetivo, aunque todavía no estoy completamente seguro de cómo), y luego primero invoca una función base que simplemente instala algunas claves SSH compartidas, enlaces NewRelic y otros cosas que son comunes a todas las máquinas en nuestra nube, luego invoca la función real del servidor web.
---
- name: Gather data about appservers
hosts: appservers
gather_facts: yes
tasks:
- debug: Gather Facts
- name: Configure all frontend web servers
hosts: webservers
sudo: yes
roles:
- { role: base }
- { role: webserver }
Dicha función de "servidor web" instala nginx, copia los certificados SSL y finalmente copia la plantilla de configuración nginx de jinja2.
- name: Install nginx configuration file.
template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes
Respuesta1
Puedes utilizarvariables mágicas group_names
y groups
buscar grupos definidos en su inventario:
---
- hosts: webservers
vars:
dcs: [dc_1, dc_2, dc_3]
tasks:
- debug:
msg: |
upstream backend {
{%- for dc in dcs %}
{%- if dc in group_names %}
{%- for host in groups[dc+'_appservers'] %}
server {{host}};
{%- endfor %}
{%- endif %}
{%- endfor %}
}
Este manual le dará el siguiente resultado.
TASK: [debug ] ****************************************************************
ok: [10.43.0.10] => {
"msg": "upstream backend { server 10.43.0.20; server 10.43.0.21;}"
}
ok: [10.43.10.10] => {
"msg": "upstream backend { server 10.43.10.20; server 10.43.10.21;}"
}
ok: [10.43.20.10] => {
"msg": "upstream backend { server 10.43.20.20; server 10.43.20.21;}"
}
Cambie server {{host}};
según sea necesario.