Ansible ist ein großartiges Werkzeug zur Automatisierung von IT-Infrastrukturen. Allerdings kann die Ausführung großer und komplexer Playbooks auf vielen Hosts manchmal zeitaufwendig sein. In diesem Blogbeitrag stellen wir verschiedene Methoden vor, um die Ausführung von Ansible Playbooks zu beschleunigen und die Performance zu optimieren.
1. Parallele Ausführung mit forks
Ansible führt standardmäßig Aufgaben sequenziell auf einer begrenzten Anzahl von Hosts aus, die durch den forks
Parameter gesteuert wird. Standardmäßig ist der Wert auf 5 gesetzt, d. h. Ansible führt Tasks auf fünf Hosts gleichzeitig aus.
Dieser Wert kann je nach Größe und Kapazität Ihrer Umgebung angepasst werden. Um den Wert für forks
zu ändern, können Sie entweder die Ansible-Konfigurationsdatei (ansible.cfg
) bearbeiten oder den Wert über die Kommandozeile übergeben.
Anpassung in der Konfigurationsdatei:
[defaults]
forks = 20
Anpassung über die Kommandozeile:
ansible-playbook -f 20 mein-playbook.yml
Durch Erhöhen von forks
können Sie Ansible dazu bringen, mehr Hosts gleichzeitig zu verwalten, was zu einer schnelleren Ausführung führt. Allerdings sollten Sie sicherstellen, dass Ihr Ansible-Controller (der Server, der die Playbooks ausführt) die Last bewältigen kann.
2. Serielle Ausführung mit serial
Es kann manchmal vorkommen, dass Sie die Ausführung auf bestimmten Hosts schrittweise durchführen möchten, um eine Überlastung oder Ausfallzeiten zu vermeiden. Dafür können Sie den serial
Parameter nutzen, der angibt, auf wie vielen Hosts gleichzeitig gearbeitet werden soll.
- hosts: webserver
serial: 5
tasks:
- name: Apache installieren
apt:
name: apache2
state: present
In diesem Beispiel wird die Installation von Apache auf jeweils 5 Hosts gleichzeitig ausgeführt, bevor die nächsten 5 Hosts abgearbeitet werden.
3. Verwendung von Asynchronen Aufgaben (async
und poll
)
Ein weiteres wichtiges Feature zur Beschleunigung ist die asynchrone Ausführung von Aufgaben. Wenn eine Aufgabe lange dauert, z. B. ein Datenbank-Backup oder eine große Dateiübertragung, müssen Sie nicht darauf warten, bis die Aufgabe abgeschlossen ist. Stattdessen können Sie die Aufgabe asynchron laufen lassen und später den Status überprüfen.
Die Parameter async
und poll
ermöglichen es Ihnen, die Kontrolle darüber zu haben, wie lange eine Aufgabe laufen darf und wie oft der Status überprüft wird.
tasks:
- name: Langes Skript im Hintergrund ausführen
command: /usr/local/bin/langes-skript.sh
async: 600
poll: 0
- name: Status der Aufgabe überprüfen
async_status:
jid: "{{ ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 5
In diesem Beispiel wird das Skript für maximal 600 Sekunden im Hintergrund ausgeführt, ohne auf das Ergebnis zu warten (poll: 0
). Später kann der Status überprüft werden, um festzustellen, ob die Aufgabe erfolgreich abgeschlossen wurde.
4. Minimierung von SSH-Verbindungen
Ein Großteil der Ausführungszeit in Ansible wird durch die wiederholte Erstellung von SSH-Verbindungen zu den Remote-Hosts verursacht. Das Aktivieren von persistent SSH-Verbindungen kann die Performance verbessern, da die SSH-Verbindung während der gesamten Playbook-Ausführung aufrechterhalten wird.
Um persistente SSH-Verbindungen zu aktivieren, bearbeiten Sie die ansible.cfg
Datei:
[ssh_connection]
pipelining = True
control_path = /tmp/ansible-ssh-%%h-%%p-%%r
pipelining = True
: Pipelining reduziert die Anzahl der SSH-Sitzungen, indem Befehle ohne TTY in einer einzigen SSH-Verbindung gesendet werden.control_path
: Dieser Parameter gibt den Pfad zu den SSH-Verbindungen an, sodass sie wiederverwendet werden können.
Achtung: Pipelining funktioniert nur, wenn requiretty
in Ihrer /etc/sudoers
-Datei deaktiviert ist.
5. Nutzung von Fact-Caching
Ansible sammelt zu Beginn jedes Playbooks automatisch Informationen über die Zielsysteme, sogenannte Facts. Diese Informationen (z. B. Speicherplatz, CPU-Details) können zeitaufwendig zu sammeln sein. Mit Fact-Caching können Sie diese Daten zwischenspeichern, sodass sie nicht bei jeder Playbook-Ausführung erneut abgerufen werden müssen.
Um Fact-Caching zu aktivieren, müssen Sie die Konfiguration in ansible.cfg
anpassen:
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_cache
fact_caching_timeout = 7200
gathering = smart
: Dies stellt sicher, dass Facts nur gesammelt werden, wenn sie wirklich benötigt werden.fact_caching = jsonfile
: Facts werden im JSON-Format in einem Cache abgelegt.fact_caching_timeout = 7200
: Definiert die Gültigkeitsdauer des Caches in Sekunden (hier: 2 Stunden).
Mit aktivem Fact-Caching reduziert sich die Zeit für das Sammeln von Fakten, besonders bei wiederholten Playbook-Ausführungen.
6. Optimierung der Playbook-Struktur
Die Art und Weise, wie Playbooks geschrieben sind, hat einen direkten Einfluss auf die Ausführungszeit. Hier sind einige Tipps zur Optimierung:
- Vermeiden Sie unnötige Aufgaben: Verwenden Sie die
when
-Bedingung, um Aufgaben nur dann auszuführen, wenn sie wirklich erforderlich sind. Dies spart Zeit und Ressourcen.
- name: Starte den Webserver neu, wenn die Konfiguration geändert wurde
service:
name: apache2
state: restarted
when: config_changed
- Verwenden Sie
failed_when
undchanged_when
: Verhindern Sie unnötige Ausführungen, indem Sie Ansible mitteilen, wann eine Aufgabe als erfolgreich oder geändert betrachtet werden soll.
- name: Überprüfe Datei
command: test -f /tmp/testfile
changed_when: false
- Verwendung von Blocks: Fassen Sie zusammenhängende Aufgaben in einem Block zusammen. Dies erleichtert die Struktur und bietet mehr Kontrolle über das Fehlerhandling.
tasks:
- block:
- name: Paket installieren
apt:
name: apache2
state: present
- name: Konfigurationsdatei kopieren
copy:
src: apache.conf
dest: /etc/apache2/apache.conf
- name: Apache neu starten
service:
name: apache2
state: restarted
when: ansible_os_family == "Debian"
7. Parallelisierung von Aufgaben mit strategy: free
Ansible führt standardmäßig Aufgaben in einer sequentiellen Reihenfolge aus, d. h. die Hosts warten darauf, dass jeder Host dieselbe Aufgabe abgeschlossen hat, bevor sie mit der nächsten beginnen. Um dies zu umgehen und die Ausführung zu beschleunigen, können Sie die Strategie free
verwenden.
---
- hosts: webserver
strategy: free
tasks:
- name: Installiere Apache
apt:
name: apache2
state: present
Mit der Strategie free
führt Ansible Aufgaben auf einem Host unabhängig davon aus, ob die Aufgabe auf anderen Hosts abgeschlossen ist. Dies kann zu einer deutlichen Beschleunigung führen, vor allem, wenn Aufgaben unterschiedlich lange dauern.
8. Rollout mit delegate_to
Wenn Sie Aufgaben auf einem zentralen Host ausführen müssen, anstatt auf allen Hosts separat, kann die Verwendung von delegate_to
helfen. Dies spart Zeit, da bestimmte Aufgaben nur auf einem Host ausgeführt werden.
- name: Lade Software von einem zentralen Server herunter
get_url:
url: http://zentraler-server/software.tar.gz
dest: /tmp/software.tar.gz
delegate_to: zentraler-server
9. Reduzieren der Ausführungszeit durch Bedingungsprüfung
Stellen Sie sicher, dass Sie unnötige Aufgaben vermeiden, indem Sie vorherige Ergebnisse zwischenspeichern und prüfen, ob sie ausgeführt werden müssen. Beispiel:
- name: Konfigurationsdatei kopieren, wenn sie sich geändert hat
copy:
src: apache.conf
dest: /etc/apache2/apache.conf
notify: Apache neu starten
changed_when: "'checksum' in result and result['checksum'] != old_checksum"
Fazit
Die Ausführung von Ansible Playbooks kann durch verschiedene Techniken erheblich beschleunigt werden. Durch die Parallelisierung von Aufgaben, Nutzung von asynchronen Tasks, Aktivierung von Fact-Caching und Optimierung der Playbook-Struktur können Sie die Performance Ihrer Automatisierungsprozesse erheblich verbessern. Die Wahl der richtigen Methode hängt von Ihrer Umgebung, den ausgeführten Aufgaben und den verfügbaren Ressourcen ab.