Ansible-Load Balancer-Vorlage für mehrere Rechenzentren

Ansible-Load Balancer-Vorlage für mehrere Rechenzentren

Ich migriere die Verwaltung einer vorhandenen Multi-Datacenter-Konfiguration nach Ansible, bin mir aber nicht sicher, wie ich dies am besten modellieren kann, da ich damit noch nicht vertraut bin.

Ich habe drei Rechenzentren D1, D2 und D3. In jedem wird die gleiche Konfiguration identisch wiederholt:

  • EinNginx-Lastenausgleich(lb.D[n]) an eine öffentliche IP gebunden
  • ZweiAnwendungsserver(as[1-2].D[n]), die ausschließlich Datenverkehr vom lokalen Load Balancer empfangen
  • Ein Slave (nur lesen)DB-Server(db.D[n]), aus dem beide App-Server lesen.

Die Hosts-Datei, die ich bisher erstellt habe, sieht ungefähr so ​​aus:

# 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

Ich habe hier absichtlich nur IP-Adressen belassen, weil ich verstehen möchte, wie eine reine Ansible-Lösung funktionieren würde, anstatt auf DNS zurückzugreifen.

Das Problem besteht darin, den Reverse-Proxy von nginx korrekt upstream zu füllen, so dassEs werden nur die lokalen App-Server jedes DC hinzugefügtwenn die Nginx-Rolle ausgeführt und die Konfigurationsdateivorlage auf die Load Balancer-Maschine kopiert wird. Ist es insbesondere möglich, so etwas zu tun?

# 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 %}
 }

Zum einen bin ich mir nicht sicher, ob die Hosts-Datei wirklich Sinn ergibt (sollte ich stattdessen Variablen zu den einzelnen Einträgen hinzufügen? In der aktuellen Konfiguration kann ich so etwas wie [dc][3][appservers] nicht machen, obwohl ich nicht sicher bin, ob dort die Lösung liegt.)

Vielen Dank!

BEARBEITEN 1:

Der Aufbau des Playbooks ist wie folgt:

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

Der Einstiegspunkt von main.yml besteht nur aus zwei Zeilen:

---
- include: servers/webservers.yml
- include: servers/appservers.yml

webservers.yml sammelt Fakten über App-Server (ich dachte, das wäre notwendig, um mein Ziel zu erreichen, auch wenn ich noch nicht ganz sicher bin, wie) und ruft dann zuerst eine Basisrolle auf, die nur einige gemeinsame SSH-Schlüssel, NewRelic-Bindungen und andere Dinge installiert, die auf allen Maschinen in unserer Cloud üblich sind, und ruft dann die eigentliche Webserver-Rolle auf.

---
- 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 }

Die besagte „Webserver“-Rolle installiert nginx, kopiert die SSL-Zertifikate und kopiert anschließend die Jinja2-nginx-Konfigurationsvorlage.

 - name: Install nginx configuration file.
    template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes

Antwort1

Sie können nutzenmagische Variablen group_namesund groupsum in Ihrem Inventar definierte Gruppen nachzuschlagen:

---
- 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 %}
        }

Dieses Playbook liefert Ihnen die folgende Ausgabe.

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;}"
}

Ändern Sie server {{host}};es nach Bedarf.

verwandte Informationen