Maximierung der Ansible-Leistung mit ControlPersist und Pipelining

Steigern Sie die Leistung Ihrer Ansible Playbooks erheblich, indem Sie die Wiederverwendung von SSH-Verbindungen mit ControlPersist aktivieren und die Modulausführung durch Pipelining optimieren. Dieser Leitfaden bietet wesentliche Einblicke und praktische Konfigurationen zur Reduzierung der Ausführungszeiten, insbesondere in groß angelegten Umgebungen. Erfahren Sie, wie Sie Ihre `ansible.cfg` für eine schnellere und effizientere IT-Automatisierung einstellen.

33 Aufrufe

Maximierung der Ansible-Leistung mit ControlPersist und Pipelining

Ansible ist ein leistungsstarkes Werkzeug zur Automatisierung der IT-Infrastruktur, das Konfigurationsmanagement und Anwendungsbereitstellung in großem Maßstab ermöglicht. In Umgebungen mit hohem Volumen oder bei der Verwaltung einer großen Anzahl von Knoten kann der inhärente Overhead beim Aufbau von SSH-Verbindungen für jede Aufgabe zu einem erheblichen Engpass werden. Dies kann zu schmerzhaft langsamen Ausführungszeiten von Playbooks führen. Glücklicherweise bietet Ansible zwei leistungsstarke Funktionen, ControlPersist und Pipelining, die die Leistung dramatisch verbessern können, indem sie optimieren, wie Ansible mit verwalteten Knoten kommuniziert.

Diese Anleitung führt Sie durch das Verständnis und die Implementierung von ControlPersist und Pipelining. Durch die Nutzung dieser Techniken können Sie die Ausführungszeiten erheblich verkürzen und Ihre Ansible-Automatisierung effizienter und reaktionsschneller gestalten, insbesondere in Umgebungen mit Hunderten oder Tausenden von Hosts. Die Beherrschung dieser Optimierungen ist entscheidend für alle, die ihre Ansible-Bereitstellungen effektiv skalieren möchten.

Verständnis des Standardverhaltens von Ansible-Verbindungen

Standardmäßig baut Ansible für jede im Playbook ausgeführte Aufgabe eine neue SSH-Verbindung zu jedem verwalteten Host auf. Für jede Verbindung führt es mehrere Schritte aus:

  1. SSH-Verbindung initiieren: Eine neue SSH-Verbindung wird aufgebaut.
  2. Module übertragen: Ansible überträgt die notwendigen Python-Module (oder andere relevante Dateien) auf den Remote-Host.
  3. Modul ausführen: Das Modul wird auf dem Remote-Host ausgeführt.
  4. Ausgabe empfangen: Ansible ruft die Ausführungsergebnisse ab.
  5. Verbindung schließen: Die SSH-Verbindung wird beendet.

Obwohl dieser Ansatz robust ist und für jede Aufgabe einen sauberen Zustand gewährleistet, verbraucht der wiederholte Prozess des Verbindungsaufbaus und der Modulübertragung erheblich Zeit, insbesondere wenn zahlreiche Aufgaben oder ein großes Inventar bearbeitet werden.

Optimierung von Verbindungen mit ControlPersist

ControlPersist ist eine SSH-Funktion, mit der Sie SSH-Verbindungen für einen bestimmten Zeitraum offen halten können, auch nachdem der ursprüngliche Befehl beendet wurde. Das bedeutet, dass nachfolgende Ansible-Aufgaben, die sich an denselben Host richten, die vorhandene, offene Verbindung wiederverwenden können, anstatt eine neue aufzubauen. Dies reduziert die Latenz beim Einrichten von SSH-Sitzungen erheblich.

Wie ControlPersist funktioniert

Wenn ControlPersist aktiviert ist, weist es den SSH-Client an, eine Control-Master-Verbindung aufrechtzuerhalten. Nachfolgende SSH-Verbindungen zum selben Host mit denselben Anmeldeinformationen und Optionen können dann über diese Master-Verbindung gemultiplext werden. Ansible nutzt dies, indem es die Optionen ControlPath und ControlPersist in seiner SSH-Konfiguration festlegt.

Aktivieren von ControlPersist in Ansible

Sie können ControlPersist auf verschiedene Weise aktivieren:

  1. Über ansible.cfg (Empfohlen für globale oder projekt­spezifische Einstellungen):
    Bearbeiten oder erstellen Sie Ihre ansible.cfg-Datei (befindet sich in Ihrem Ansible-Projektverzeichnis, ~/.ansible.cfg oder /etc/ansible/ansible.cfg). Fügen Sie die folgende Konfiguration zum Abschnitt [ssh_connection] hinzu:

    ini [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p

    • -o ControlMaster=auto: Aktiviert die Verbindungsfreigabe. Wenn eine Master-Verbindung vorhanden ist, wird diese verwendet; andernfalls wird eine neue erstellt.
    • -o ControlPersist=600: Hält die Steuerverbindung 600 Sekunden (10 Minuten) offen. Passen Sie diesen Wert basierend auf Ihrem Workflow und Ihren Sicherheitsrichtlinien an. Eine längere Dauer bedeutet mehr potenzielle Wiederverwendung, aber auch mehr offene Ressourcen.
    • -o ControlPath=~/.ssh/ansible_control_%r@%h:%p: Definiert den Pfad für den Steuer-Socket. %r ist der Remote-Benutzername, %h ist der Hostname und %p ist der Port. Dies stellt eindeutige Sockets für verschiedene Verbindungen sicher.
  2. Über Umgebungsvariable:
    Sie können die SSH-Argumente direkt über eine Umgebungsvariable festlegen:

    bash export ANSIBLE_SSH_ARGS='-o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p' ansible-playbook your_playbook.yml

  3. Über Playbook (für diese Einstellung weniger üblich):
    Obwohl möglich, wird generell nicht empfohlen, persistente SSH-Optionen direkt in einem Playbook festzulegen, da es sich um eine Einstellung auf Verbindungsebene handelt. Der Vollständigkeit halber könnten Sie jedoch ansible.builtin.set_fact oder Ähnliches verwenden, um dies zu beeinflussen, aber ansible.cfg wird bevorzugt.

Überlegungen zu ControlPersist

  • Sicherheit: Stellen Sie sicher, dass der ControlPath gesichert ist, sodass nur autorisierte Benutzer auf die Steuer-Sockets zugreifen können. Der Standardpfad im Beispiel ist für Konfigurationen auf Benutzerebene im Allgemeinen sicher.
  • Ressourcenverbrauch: Das Offenhalten von Verbindungen verbraucht Ressourcen sowohl auf dem Steuerknoten als auch auf den verwalteten Knoten. Überwachen Sie den Ressourcenverbrauch, wenn Sie eine sehr große Anzahl von persistenten Verbindungen haben.
  • Verbindungs­zurücksetzung: Wenn ein zwischengeschaltetes Netzwerk­gerät oder der Remote-SSH-Server kürzere Zeitüberschreitungen für Verbindungen erzwingt als ControlPersist, kann die Verbindung dennoch unterbrochen werden. ControlPersist funktioniert am besten in stabilen Netzwerk­umgebungen.

Optimierung der Modulausführung mit Pipelining

Pipelining ist eine weitere leistungsstarke Ansible-Optimierung, die den Overhead der Aufgabenausführung weiter reduziert. Anstatt Module auf den Remote-Host zu übertragen, auszuführen und dann die Ausgabe abzurufen, streamt Pipelining Befehle direkt über die SSH-Verbindung. Das bedeutet, dass Ansible keine Module auf dem Remote-Dateisystem platzieren oder temporäre Dateien für die Ausgabe erstellen muss.

Wie Pipelining funktioniert

Wenn Pipelining aktiviert ist, führt Ansible Module direkt über ssh auf dem Remote-Host aus. Die Standardausgabe und die Standardfehlerausgabe des Moduls werden über dieselbe SSH-Verbindung zurück an Ansible gestreamt. Dies macht es für Ansible unnötig, Dateien auf dem Remote-Dateisystem (wie /usr/bin/ansible_module_name oder temporäre Dateien) zu schreiben und sie dann auszuführen. Dies ist besonders effektiv für Module, die keine Privilegieneskalation oder signifikante Interaktion mit dem Remote-Dateisystem erfordern.

Aktivieren von Pipelining in Ansible

Pipelining wird über die Datei ansible.cfg oder Umgebungsvariablen aktiviert.

  1. Über ansible.cfg:
    Fügen Sie den Abschnitt [ssh_connection] hinzu oder ändern Sie ihn:

    ini [ssh_connection] pipelining = True

  2. Über Umgebungsvariable:
    bash export ANSIBLE_PIPELINING=True ansible-playbook your_playbook.yml

Überlegungen zu Pipelining

  • Privilegieneskalation: Pipelining funktioniert am besten mit Modulen, die keine Privilegieneskalation erfordern (z. B. mit become: yes oder sudo). Wenn become verwendet wird, muss Ansible typischerweise Dateien auf das Remote-System kopieren. Wenn Sie häufig become verwenden, bietet Pipelining möglicherweise nicht so viele Vorteile oder kann sogar Probleme mit bestimmten Modultypen verursachen.
  • Modulkompatibilität: Die meisten integrierten Ansible-Module funktionieren gut mit Pipelining. Benutzerdefinierte Module oder solche, die stark auf Remote-Dateisystemoperationen angewiesen sind, können sich jedoch anders verhalten. Testen Sie gründlich.
  • Verbindungs­stabilität: Eine stabile SSH-Verbindung ist entscheidend für die korrekte Funktion von Pipelining.
  • requiretty SSH-Einstellung: Pipelining ist mit der requiretty-SSH-Option auf dem Remote-Server inkompatibel. Wenn Ihr SSH-Server Defaults requiretty in /etc/sudoers hat, müssen Sie dies möglicherweise deaktivieren oder !requiretty für den spezifischen Benutzer verwenden, mit dem sich Ansible verbindet.

Kombination von ControlPersist und Pipelining für maximale Leistung

Für die signifikantesten Leistungssteigerungen wird dringend empfohlen, sowohl ControlPersist als auch Pipelining zu aktivieren. Diese Kombination adressiert die beiden Haupt­overhead­posten: Verbindungsaufbau und Modulausführung.

So könnte Ihre ansible.cfg mit beiden aktivierten Einstellungen aussehen:

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p
pipelining = True

Wenn beide aktiv sind:

  1. Ansible initiiert eine SSH-Verbindung und richtet bei Bedarf ein ControlMaster ein (ControlPersist).
  2. Für nachfolgende Aufgaben wird die vorhandene, offene Verbindung wiederverwendet.
  3. Module werden direkt über den Stream ausgeführt, ohne auf das Dateisystem kopiert zu werden (Pipelining).

Diese Synergie reduziert die Zeit, die Ansible mit der Kommunikation mit jedem verwalteten Knoten verbringt, drastisch und führt zu wesentlich schnelleren Playbook-Läufen.

Praktisches Beispiel-Szenario

Stellen wir uns ein Playbook vor, das 10 einfache Aufgaben auf 100 Hosts ausführen muss.

Ohne Optimierungen:
Jede Aufgabe erfordert eine neue SSH-Verbindung, Modulübertragung, Ausführung und Verbindungs­schließung. Das entspricht 100 Hosts * 10 Aufgaben * (Verbindungszeit + Modulübertragungs­zeit). Wenn die Verbindungszeit 0,5 Sekunden und die Modulübertragungs­zeit 0,2 Sekunden beträgt, entstehen 700 Sekunden Overhead allein für Kommunikation und Übertragungen, ohne die eigentliche Modulausführung.

Mit aktiviertem ControlPersist und Pipelining:

  1. Die erste Aufgabe auf jedem Host baut die anfängliche Verbindung auf und richtet das ControlMaster ein.
  2. Alle nachfolgenden 9 Aufgaben auf diesem Host verwenden die offene Verbindung wieder und streamen die Modulausführung.

Der Overhead pro Host nähert sich Verbindungszeit + (9 * minimaler Streaming-Overhead). Die Gesamtzeit wird erheblich reduziert, wobei die meiste Playbook­ausführungs­zeit für die eigentliche Arbeit der Module aufgewendet wird und nicht für die Mechanik der Kommunikation.

Wann Vorsicht geboten ist

Obwohl diese Optimierungen leistungsstark sind, sind sie nicht universell ohne Bedenken anwendbar:

  • Umgebung mit strengen Firewalls oder Netzwerk­beschränkungen: Häufige Verbindungs­abbrüche oder Stateful Inspection können ControlPersist stören.
  • Hochsicherheits­umgebungen: Länger bestehende SSH-Verbindungen können in stark regulierten Umgebungen ein Sicherheits­risiko darstellen. Passen Sie die ControlPersist-Dauer entsprechend an.
  • Playbooks, die stark auf become und Dateiopera­tionen angewiesen sind: Die Effektivität von Pipelining wird reduziert, wenn become konsistent verwendet wird, da dies oft Datei­operationen erfordert. Testen Sie die Auswirkungen auf die Leistung.

Fazit

Die Optimierung der Ansible-Kommunikation mit verwalteten Knoten ist ein wichtiger Schritt zu effizienter und skalierbarer Automatisierung. Durch das Verständnis und die Implementierung von ControlPersist und Pipelining können Sie die Ausführungszeiten von Playbooks drastisch verkürzen. ControlPersist hält SSH-Verbindungen am Laufen und reduziert den Verbindungs­overhead, während Pipelining die Modulausführung streamt und die Notwendigkeit von Datei­übertragungen eliminiert. Die Kombination dieser beiden Einstellungen, hauptsächlich über ansible.cfg, ist eine Best Practice für jeden Ansible-Benutzer, der eine signifikante Anzahl von Hosts verwaltet oder komplexe Playbooks ausführt. Testen Sie diese Konfigurationen immer in Ihrer spezifischen Umgebung, um die Leistung zu optimieren und die Kompatibilität sicherzustellen.