Neue DHCP-Bereiche in Ansible umsetzen

Hallo,

leider können mit der Rolle, die ich gebaut habe, die DHCP-Bereiche nur berechnet werden, wenn man alle Gateways ausrollt, weil Ansible sonst beim Durchsuchen aller Gateways in den Rollen collectd und gateways_kea_configure ins Schleudern kommt. Dort werden nämlich auch die server_ids der anderen Gateways in der jeweiligen Domäne benötigt um damit Berechnungen anzustellen.

Außerdem dauert das Berechnen der Bereiche ewig. Mir ist nicht klar, weil es nur drei verschachtelte Schleifen sind, wäre das eine halbwegs performante Programmiersprache, wäre das in Sekunden erledigt. Ansible braucht irgendwie gefühlt 45 min nur zum Berechnen der Variablen. Zumindest auf meinem Laptop, auf dem i7 ging es schneller.

Wie wollen wir weiter verfahren? Ein passabler Weg wäre, in der Übergangsphase weiterhin die server_id und die DHCP-Bereiche in die host_vars zu schreiben und später dann einmal komplett zu eleminieren.

Unabhängig davon müsste man auch die Algorithmen in collectd und gateways_kea_configure ändern, sofern man auf die server_id komplett verzichten will. Einen Algorithmus um das Partnergateway zu ermitteln, hab ich geschrieben. Den könnte man hier lokal anwenden. Schön ist anders, aber geht wohl nicht anders.

Was meint ihr?

  1. Auf Performance verzichten und den dualen Weg weitergehen, die fehlenden Variablen am Anfang zu berechnen. Dazu müsste die Rolle, die die fehlenden Variablen berechnet, noch so umgebaut werden, dass sie das für alle Gateways tut, auch wenn man nur eines ausrollt.
  2. Nur noch statische IP-Bereiche, aus der Domänenliste eine simple Liste machen
  3. Weiterhin die gesamte, ausführliche Konfiguration in die host_vars schreiben, was aber weiterhin inkonsistent zu IPV6 wäre.

@Adminteam

Grüße
Matthias

Wieder alle IP-Bereiche für die Domänen ≤ 15 eingetragen und die Rolle, die die Berechnung durchführt, deaktiviert.

Zumindest übergangsweise.

Könnte man nicht einfach™ die rollen anpassen? Werden die Variablen an so vielen stellen verwendet?
Also ich meine:

If ansiblevariable.dhcpstart ist defined Then 
    DHCP_Start = ansiblevariable.dhcpstart
else
    DHCP_Start = fancyberechnungsgedönse
Finde

Dann würde das ganze immer nur an der Stelle ausgeführt wo es gebraucht werden würde…

Die Server ID kann man theoretisch auch manuell belassen…

Das könnte man natürlich tun. Da würde man den Code an mehrere Stellen kopieren müssen. Das ist programmiertechnisch nicht ideal.

Nur den DHCP-Bereich zu automatisieren, aber die server_id nicht, finde ich irgendwie unschön.

Man müsste mal gucken, warum Ansible so lange dafür braucht. Das kann es eigentlich nicht sein, dass das so ewig dauert.

Um noch deine Frage nach der Anzahl der Verwendungen zu beantworten:

mpw@Server0:~/gits/ansible-ffms/roles$ grep -ri 'server_id' *|wc -l
60

Das halte ich nicht für praktikabel. Zumal die Berechnung dann 60 statt einmal duchgeführt wird.

1 „Gefällt mir“

Anfangs nur als Witz gemeint, denke ich mittlerweile, dass es durchaus ein möglicher, ggf. sogar besserer Weg wäre: Wir definieren und eine Variablenstruktur, sodass sie möglichst allgemeingültig, aber auch administrierbar ist. Daraus generieren wir uns dann (mit einem Programm in einer $programmiersprache != Ansible) die hostvars, so wie wir sie brauchen.

Während wir bei unserer Variablenstruktur darauf achten, dass dort keine Redundanzen enthalten sind, könnten unsere hostvars ja dann beliebig viele Redundanzen enthalten. Wir würden die hostvars so generieren, dass jede Rolle damit optimal arbeiten kann.

Abgesehen vom aktuellen Problem mussten wir ja schon häufig total abgefahrene Hacks anwenden um irgendwie eine neue Rolle an unsere Variablenstruktur anzupassen, nur weil die Art der Traversierung/Iterierung für das aktuelle Problem nicht so optimal passte, dieses Problem wäre dann passeé. Passen die aktuellen Variablen nicht, so generieren wir einfach eine weitere Struktur, die für das aktuelle Problem optimal funktioniert.

Als kleinen Nebeneffekt könnte man dadurch auch signifikant (!) übersichtlichere Rollen und Templates herstellen, die dann auch besser verständlich werden.

Wenn wir das ganze dann Abstraktion von Komplexität nennen, hört es sich sogar ganz gut an. :stuck_out_tongue:

Als Sprache würde ich Python empfehlen. Bash ginge natürlich auch, Hauptsache kein verkrüppeltes Jinja2. Etwas objektorientiertes wäre imho aber von Vorteil.

Man könnte dann die Generierung der jeweils aktuellen hostvars manuell erfoderlich machen, z. B. durch Ausführen des dedizierten Programms bzw. makefile. Oder man lässt es mittels Ansible als lokale Aktion laufen und lädt dann das Ansible inventory neu.

Ein weiterer Vorteil wäre, dass wir nicht immer alle Rollen anfassen müssten, wenn wir etwas an unserer Struktur ändern (Abstraktion halt).

PS: Es zeigt sich eigentlich immer das selbe Problem: Ansible ist echt super, wenn man die hosts einzeln betrachtet, aber sobald es Abhängigkeiten zwischen verschiedenen Hosts hat, geht das große Kotzen los, weil man das einfach nicht sauber ausgedrückt bekommt. Dieses Problem würde man hiermit sehr allgemein eliminieren. U. A. weil wir uns halt eine Struktur überlegen können, die genau auf unser Problem passt und uns nicht immer entscheiden müssen, ob es jetzt in group_vars/all, group_vars/gateways oder host_vars/XY am Besten aufgehoben ist.

2 „Gefällt mir“

Ich würde vorher gerne mal verstehen, warum Ansible, bzw. diese eine Rolle, die die Variablen berechnet, so super langsam ist. Gibt es für Python da vernünftige Debugger, die zeigen, wo es hängt?

Ich finde, das deine Lösung auf jeden Fall praktikabel ist. Gefallen tut sie mir bisher nicht, aber ich könnte mich daran gewöhnen.

Aus meiner Sicht: Dafür. Ich sehe natürlich nur einen kleinen Teil der Sache, aber den eigentlichen Code für die automatische Domänenzuordnung von R nach Pyhton zu portieren ist wahrscheinlich weniger Arbeit als das ganze Auslesen und Manipulieren der Ansible-Dateien (und sicher deutlich robuster).

Hast du mal die Debug Ausgaben rausgeworfen?

Selbst ohne --diff läuft es glaube ich 20 min auf einem i7 oder so.

Ansible bietet sogar eine Schnittstelle zur dynamischen Generierung des inventory: Developing dynamic inventory — Ansible Documentation

2 „Gefällt mir“

Es wird halt noch schwieriger dann Leute ins Team zu holen, weil die Einstiegshürde immer höher wird.

Imho wird es dadurch signifikant einfacher.

Ich hab heute morgen die Rolle „calculate_missing_inventory_variables“ mal ohne gather_facts ausgerollt, das lief in wenigen Sekunden durch.

Eventuell können wir gucken, ob man einzelne Rollen nur lokal ausführen kann und dann im Anschluss erst die SSH-Verbindung aufbaut.

Ich habe dazu an einer Stelle ansible_hostname auf inventory_hostname umgestellt. Vielleicht war das schon alles, um das zu beschleunigen.

Müsste man gucken, ob man das doch so in den Griff bekommt.

Dazu habe ich, während der Suche nach was anderem, etwas gefunden: Controlling where tasks run: delegation and local actions — Ansible Documentation

Oh und zusätzlich: Controlling where tasks run: delegation and local actions — Ansible Documentation

1 „Gefällt mir“

Also sobald man gather_facts wieder aktiviert, läuft das einfach super langsam.

@jotzt baut die Berechnung der Partnergateways und die DHCP-Bereiche jetzt in der R-Skript ein und dann können wir Ansible etwas entschlacken.

Ist erledigt, die Einträge haben jetzt die folgende Form:

vm_id: 6 # paradox
[...]
   "53":
      dhcp_start: 10.53.64.0
      dhcp_ende: 10.53.127.255
      server_id: 2
      partner:"tj01"
1 „Gefällt mir“

Inwiefern entschlacken?

Durch die neue Variable kann man vermutlich ein paar Algorithmen hier und da vereinfachen.

@corny456 @MPW Das Skript ist fertig. DHCP-Bereiche werden jetzt automatisiert berechnet. Damit hat das Skript auch keine Probleme mehr, wenn Gateways hinzugefügt oder entfernt werden. Auch kann in der hosts-Datei capacity=0 angegeben werden, dem Gateway werden dann keine Domänen zugeteilt.

Die Domänen werden jetzt anhand des 80 %-Quantils der L2TP-Verbindungen und anhand der mittleren Tx/Rx-Raten verteilt. Das hat zum Ziel, die Gateways mit den ganz großen Domänen in Spitzenzeiten stärker zu entlasten.

Außerdem wird jetzt jede Kombination aus Gateways zunächst nur einer Domäne zugeteilt, sodass maximal zwei Domänen gleichzeitig vom gleichen Gateway-Paar bedient werden.

Skript ist getestet und im Master-Branch.