Ansible Load Balancer-Vorlage für mehrere Rechenzentren

7

Ich migriere die Verwaltung eines vorhandenen Multi-Rechenzentrums-Setups nach Ansible, bin mir jedoch nicht sicher, wie ich es am besten modellieren kann, da ich neu darin bin.

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

  • Ein Nginx Load Balancer (lb.D [n]), der an eine öffentliche IP gebunden ist
  • Zwei Anwendungsserver (als [1-2] .D [n]), die Datenverkehr ausschließlich vom lokalen Load Balancer empfangen
  • Ein Slave- DB-Server (schreibgeschützt ) (db.D [n]), von 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 im Upstream korrekt auszufüllen, sodass nur die lokalen App-Server für jeden Domänencontroller hinzugefügt werden, wenn die Nginx-Rolle ausgeführt und die Konfigurationsdateivorlage auf den Load Balancer-Computer 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 völlig sinnvoll ist (sollte ich stattdessen Variablen zu den einzelnen Einträgen hinzufügen? In der aktuellen Konfiguration kann ich so etwas wie [dc] [3] [appservers] nicht ausführen, obwohl ich nicht sicher bin Hier liegt die Lösung.)

Vielen Dank!

EDIT 1:

Die Struktur des Spielbuchs 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 main.yml-Einstiegspunkt 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, obwohl ich noch nicht ganz sicher bin, wie) und ruft dann zuerst eine Basiserolle auf, die nur einige gemeinsam genutzte SSH-Schlüssel, NewRelic-Bindungen und andere installiert Dinge, die jedem Computer in unserer Cloud gemeinsam sind, rufen dann die eigentliche Webserverrolle 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 }

Diese "Webserver" -Rolle installiert nginx, kopiert die SSL-Zertifikate und kopiert schließlich die Konfigurationsvorlage für jinja2 nginx.

 - name: Install nginx configuration file.
    template: src=files/loadbalancer.j2 dest=/etc/nginx/sites-available/{{ project_name }} backup=yes
Davide
quelle
1
Sie sind auf dem richtigen Weg, sollten sich jedoch nicht auf die Hostdatei für Variablen verlassen. Dafür sind Ihre Rollen host_var / main.yml gedacht und Sie verwenden das Register für Ihre Vorlagen in der Playbook-Datei. Weitere Informationen finden Sie unter blog.codecentric.de/de/2014/08/… . Ich werde morgen früh eine ausführliche Antwort geben.
Dwight Spencer
Ich habe auch vergessen zu fragen, wie strukturierst du das Playbook?
Dwight Spencer
Vielen Dank! Ich habe den Blog-Beitrag gelesen, den Sie verlinkt haben: Ist die hostvarsVariable der Schlüssel zu all dem?
Davide

Antworten:

3

Sie können magische Variablen verwenden group_names und groupsin Ihrem Inventar definierte Gruppen nachschlagen:

---
- 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 gibt 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 server {{host}};Sie nach Bedarf.

yaegashi
quelle