Ansible ist ein beliebtes Tool für die Automatisierung von IT-Aufgaben wie Konfigurationsmanagement, Anwendungsbereitstellung und Infrastruktur-Orchestrierung. Allerdings kann die Ausführungszeit von Playbooks auf größeren oder komplexeren Umgebungen zu einer Herausforderung werden. In diesem Blog-Beitrag werde ich verschiedene Techniken vorstellen, mit denen du die Ausführungszeit von Ansible-Playbooks beschleunigen kannst.
1. Parallelisierung mit forks
Ansible führt standardmäßig Tasks nacheinander auf einer bestimmten Anzahl von Hosts aus. Diese Zahl wird durch die Einstellung forks
in der ansible.cfg
bestimmt. Standardmäßig ist dieser Wert auf 5 gesetzt, was für kleinere Umgebungen ausreichen kann, aber in größeren Umgebungen zu einer Flaschenhals führt.
Wie ändere ich die Anzahl der Forks?
Du kannst den Wert von forks
in der ansible.cfg
erhöhen, um mehr Hosts parallel zu bedienen:
[defaults]
forks = 20
Dies bedeutet, dass Ansible bis zu 20 Hosts gleichzeitig bearbeiten kann. Teste den optimalen Wert für deine Umgebung, da eine zu hohe Anzahl von Forks möglicherweise zu Ressourcenengpässen auf dem Ansible-Steuerknoten führen kann.
2. SSH-Verbindung beschleunigen
Die SSH-Verbindung zwischen dem Ansible-Steuerknoten und den Zielhosts ist einer der größten Faktoren für die Performance. Es gibt verschiedene Möglichkeiten, die SSH-Verbindungen zu optimieren:
a) SSH-Persistenz aktivieren
SSH kann für jede Verbindung neu gestartet werden, was Zeit kostet. Du kannst jedoch die SSH-Persistenz aktivieren, um die Verbindung für eine bestimmte Zeit aufrechtzuerhalten:
[defaults]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
Dies hält SSH-Sitzungen bis zu 60 Sekunden nach der letzten Aktivität offen, sodass wiederholte Verbindungen zu Hosts viel schneller aufgebaut werden.
b) Parallele SSH-Verbindungen
Ein weiterer Tipp zur Beschleunigung ist die Verwendung paralleler SSH-Verbindungen, was insbesondere bei einer großen Anzahl von Hosts nützlich ist:
[ssh_connection]
pipelining = True
Durch Aktivierung von Pipelining wird die Anzahl der SSH-Verbindungen pro Task reduziert, da Ansible das Übertragen von Dateien auf Remote-Hosts überspringt.
3. Task-Ausführung mit async
und poll
Wenn du eine Aufgabe hast, die viel Zeit in Anspruch nimmt (z. B. das Neustarten eines Dienstes oder das Herunterladen großer Dateien), kannst du die Task mit async
und poll
im Hintergrund laufen lassen und gleichzeitig mit der Ausführung anderer Tasks fortfahren.
Beispiel für asynchrone Aufgaben:
- name: Starte einen langen Prozess im Hintergrund
command: /bin/some_long_task
async: 300
poll: 0
In diesem Fall führt Ansible den Befehl im Hintergrund aus und wartet nicht auf das Ergebnis. Mit poll: 0
wird die Aufgabe nicht aktiv überwacht. Du kannst später den Status der Aufgabe abfragen, wenn nötig.
4. Verwendung von gather_facts: false
Bei der Standardausführung sammelt Ansible Fakten über jeden Host, auf den es zugreift. Dies ist oft nützlich, kann aber auch die Ausführungszeit unnötig verlängern, insbesondere wenn du diese Fakten in deinem Playbook nicht verwendest. Du kannst das Sammeln von Fakten deaktivieren, wenn es nicht erforderlich ist:
- hosts: all
gather_facts: false
tasks:
- name: Eine einfache Aufgabe
command: echo "Hallo, Welt!"
Das Deaktivieren der Faktenerhebung reduziert die Ausführungszeit erheblich, insbesondere bei vielen Hosts.
5. Rollen- und Aufgabenoptimierung
Optimierung auf der Ebene der Rollen und Aufgaben selbst ist ebenfalls wichtig. Hier einige Best Practices:
a) Verwende when
-Bedingungen effizient
Manchmal wird eine Aufgabe nur unter bestimmten Bedingungen benötigt. Indem du Bedingungslogik verwendest, kannst du unnötige Aufgaben überspringen:
- name: Starte den Webserver nur auf Webserver-Hosts
service:
name: apache2
state: started
when: "'web' in group_names"
b) Reduziere redundante Aufgaben
Wenn du eine Aufgabe auf einer großen Anzahl von Hosts ausführen musst, überlege, ob die Aufgabe nur einmal für die gesamte Gruppe ausgeführt werden kann. Die Verwendung von run_once
kann helfen:
- name: Konfigurationsdatei nur einmal kopieren
copy:
src: /path/to/config
dest: /path/to/config
run_once: true
Dadurch wird die Aufgabe nur einmal für den ersten Host in der Liste ausgeführt.
6. Caching mit fact_caching
Ansible sammelt bei jedem Durchlauf Fakten von Hosts. Wenn sich die Fakten zwischen den Durchläufen nicht ändern, kannst du den Cache aktivieren, um die Ergebnisse zu speichern und die Ausführungszeit zu verkürzen:
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_cache
fact_caching_timeout = 86400
Dies speichert die Fakten in einer JSON-Datei, und Ansible wird sie für die festgelegte Zeit verwenden, anstatt die Fakten jedes Mal erneut zu sammeln.
7. Verwende free
Strategien für große Playbooks
Ansible verwendet standardmäßig die linear
-Strategie, was bedeutet, dass es auf alle Hosts wartet, bevor es zur nächsten Aufgabe übergeht. Für große Playbooks kann die free
-Strategie von Vorteil sein, da sie es ermöglicht, Aufgaben unabhängig auf jedem Host auszuführen, ohne auf andere Hosts zu warten:
- hosts: all
strategy: free
tasks:
- name: Installiere Pakete
apt:
name: nginx
state: present
Mit der free
-Strategie wird die Ausführungszeit insgesamt reduziert, da langsame Hosts nicht den Fortschritt aufhalten.
Fazit
Die Ausführungszeit von Ansible-Playbooks zu beschleunigen erfordert eine Kombination aus Parallelisierung, Optimierung der SSH-Verbindung und effizientem Task-Design. Durch Anpassungen wie das Erhöhen der Anzahl von forks
, die Verwendung von async
, das Deaktivieren des Faktensammelns und die Aktivierung von Caching kannst du die Leistung von Ansible in großen und komplexen Umgebungen erheblich steigern.
Teste die genannten Techniken in deiner Umgebung und finde die beste Konfiguration für deine Anforderungen. Viel Erfolg bei der Beschleunigung deiner Ansible-Workflows!