Wie wir mehr als 700 Server nach Salt migriert haben
Lange Zeit waren wir mit einer komplexen und umständlichen Konfiguration mit 2 Git-Repositorys zufrieden, in denen ein Teil der Daten in MySQL gespeichert ist und der andere Teil Puppet 3.8 ist. Unsere Anforderungen wuchsen jedoch allmählich, die Anzahl der Dienste nahm zu und die Konfigurationsleistung nahm ab. Dann haben wir uns die Aufgabe gestellt, die Konfiguration zu verbessern und alle verfügbaren Daten und Tools zu optimieren.
Unser Team hat in 3 Schritten eine geeignete Konfiguration für sich ausgewählt. Wir teilen unsere Erfahrungen mit der Salzoptimierung, wie man sie ohne zusätzlichen Aufwand anwendet und anpasst.
Hinweis: Auf Habré haben wir großartige Artikel von unseren Kollegen gefunden, sodass wir uns nicht mit den bereits behandelten Themen befassen werden. Wir empfehlen dringend zu lesen:
Was ist gut an SaltStack und welche Aufgaben können damit gelöst werden - Artikel ausSicherheit, Positive Technologien.
Installation, Start, erste Befehle und Vertrautheit mit Funktionen - Artikel des Autorszerghack007...
Salt ist ein Konfigurationsmanagement- und Remote-Ausführungssystem. Ein in Python geschriebenes Open Source-Infrastruktur-Framework.

Warum Salz?
Salt, Ansible, Puppet und Chef sind gute Optionen für die Auswahl eines Konfigurationsmanagement-Tools. Wir haben uns für Salt entschieden, weil wir folgende Vorteile priorisiert haben:
- Modularität, Verfügbarkeit der API in der kostenlosen Version im Gegensatz zu Ansible.
- Python, was bedeutet, dass Sie jede Komponente leicht verstehen und die fehlende Funktionalität selbst schreiben können.
- Hohe Leistung und Skalierbarkeit. Der Assistent stellt mit ZeroMQ eine dauerhafte Verbindung zu den Minions her, um maximale Leistung zu erzielen.
- Reaktoren sind eine Art Trigger, die ausgeführt werden, wenn eine bestimmte Nachricht im Nachrichtenbus angezeigt wird.
- Orchestrierung - Die Möglichkeit, komplexe Beziehungen aufzubauen und Aktionen in einer bestimmten Reihenfolge auszuführen. Konfigurieren Sie beispielsweise zuerst den Load Balancer und dann den Webserver-Cluster.
- Puppe und Chef sind in Ruby geschrieben. Unser Team hat keinen kompetenten Spezialisten für die Arbeit mit dieser Programmiersprache, aber Python ist bekannt und wird von uns häufig verwendet.
- Für die Teams, die Ansible bereits verwendet haben, ist die Möglichkeit zur Verwendung von Ansible-Spielbüchern relevant. Auf diese Weise können Sie schmerzlos nach Salt migrieren.
Bitte beachten Sie:
Wir verwenden Salt seit fast zwei Jahren und empfehlen Ihnen, die folgenden Punkte zu beachten:
- Salt, , . , . , SaltStack .
- SaltStack . , . : , . , cmd.run file.managed, .

, , , .
. .
Gegeben:
Unsere anfängliche Konfiguration lautet also:
- 2 Git-Repositorys (eines ist für Ingenieure und Administratoren; das zweite ist für hochkritische Server, die nur Administratoren zur Verfügung stehen);
- ein Datenelement in MySQL;
- der andere Teil - in Puppet 3.8 (übertrieben mit Vererbung, praktisch ohne Verwendung von Hiera - Schlüsselwertspeicherung).
Ziel: Migration des Konfigurationsmanagementsystems nach Salt, Steigerung der Leistung, Vereinfachung und Verständlichkeit der Serververwaltung.
Lösung:
Zunächst haben wir begonnen, die ursprüngliche Konfiguration von separaten nicht kritischen Service-Servern nach Salt zu migrieren und gleichzeitig veralteten Code zu entfernen.
Dann haben wir die Konfiguration für VDS-Server vorbereitet. In unserem Fall sind dies Profile für Service-Server, Entwicklungsserver und Client-Server.
Das Hauptproblem beim Wechsel von Puppet zu Salt war ein veraltetes Betriebssystem (2018 gab es Ubuntu 12.04 und 14.04). Vor der Migration musste das Betriebssystem aktualisiert werden, ohne den Betrieb des Dienstes / Servers zu beeinträchtigen. Ansonsten war alles einfach genug: Die Kollegen wurden nach und nach in den Prozess einbezogen.
Zu den Hauptvorteilen stellte das Team beispielsweise eine verständlichere Syntax fest. Meine Kollegen und ich waren uns einig, Salt Best Practices- Tipps zu verwenden , ergänzten sie jedoch durch unsere eigenen Empfehlungen, die unsere Besonderheiten widerspiegeln.
Das Team bewertete auch die Methoden zur Bereitstellung der Konfiguration: Push (der Master "drückt") und Pull (der Minion "zieht"). Der Masterless-Modus hilft, wenn Sie etwas Einfaches testen müssen und gleichzeitig nicht mit dem Git-Repository herumspielen müssen. Wenn Sie einen Minion im Masterless-Modus ausführen, können Sie das Salt-Konfigurationsmanagement auf einem Computer verwenden, ohne auf einem anderen Computer zum Salt-Master wechseln zu müssen. Die Konfiguration ist vollständig lokal.
Bis zu 300 Schergen mit einer solchen Lösung hatten wir keine ernsthaften Probleme. Die Master-Konfiguration zu diesem Zeitpunkt ist ein VDS mit 6 Kernen und 4 GB Speicher.
Sobald jedoch die Anzahl der Schergen 300 erreichte, stieg der durchschnittliche Lastgrad (durchschnittliche Systemlast) auf 3,5 bis 4, und das System verlangsamte sich erheblich. Früher dauerte der Befehl state.apply 30-40 Sekunden, jetzt dauert es 18 Minuten!
Ein solches Ergebnis war für uns natürlich inakzeptabel. Darüber hinaus haben Experten anderer Unternehmen über Erfolgsgeschichten mit 10.000 Schergen geschrieben. Wir begannen herauszufinden, was los war.
Beobachtungen des Meisters gaben keine eindeutige Antwort auf die Frage. Es gab genügend Speicher, das Netzwerk war nicht geladen, die Festplatte war zu 10% ausgelastet. Wir dachten, GitLab sei schuld, aber es war auch nicht schuld.
Es scheint, dass nicht genügend Prozessorleistung vorhanden war: Beim Hinzufügen von Kernen fiel der Lastdurchschnitt natürlich ab, und der Befehl state.apply wurde ausgeführt, obwohl schneller, etwa 5 bis 7 Minuten, aber nicht so schnell, wie wir wollten.
Das Hinzufügen von Arbeitern löste das Problem teilweise, erhöhte jedoch den Speicherverbrauch erheblich.
Dann haben wir beschlossen, die Konfiguration selbst zu optimieren.
Bühne 1
Da Säulen ein geschützter Speicher sind, ist der Zugriff auf den Speicher mit Verschlüsselungsvorgängen verbunden, und Sie müssen für den Zugriff mit der CPU-Zeit bezahlen. Daher haben wir die Anzahl der Anrufe an Säulen reduziert: Die gleichen Daten wurden nur einmal erfasst; Wenn sie an anderer Stelle benötigt wurden, wurde über den Import auf sie zugegriffen ({% - aus dem Importprofil 'defaults / pillar.sls'%}).
Die Konfiguration wird einmal pro Stunde angewendet, die Ausführungszeit wird zufällig ausgewählt. Nachdem wir analysiert hatten, wie viele Aufgaben pro Minute ausgeführt werden und wie gleichmäßig sie über eine Stunde verteilt sind, stellten wir fest: Zu Beginn der Stunde, von der 1. bis zur 8. Minute, vergehen die meisten Aufgaben und in der 34. Minute keine! Wir haben einen Läufer geschrieben, der einmal pro Woche alle Schergen durchlief und die Aufgaben gleichmäßig verteilte. Dank dieses Ansatzes wurde die Last gleichmäßig und ohne Sprünge.
Es gab Vorschläge, auf einen Eisenserver zu wechseln, aber zu diesem Zeitpunkt war er nicht da und ... wir haben das Problem auf andere Weise gelöst. Wir haben etwas Speicher hinzugefügt und den gesamten Cache darin abgelegt. Beim Betrachten des Grafana-Dashboards dachten wir zuerst, dass der Salt-Master nicht funktioniert, da der Lastdurchschnitt auf 0,5 gesunken ist. Wir haben die Ausführungszeit von state.apply überprüft und waren auch überrascht - 20-30 Sekunden. Es war ein Sieg!
Stufe 2
Sechs Monate später stieg die Zahl der Schergen auf 650, und ... die Leistung verschlechterte sich erneut. Das Diagramm "Lastdurchschnitt" wächst mit der Anzahl der Schergen.
Als erstes haben wir den Pillar-Cache aktiviert und die Lebensdauer auf 1 Stunde festgelegt (pillar_cache_ttl: 3600). Wir haben festgestellt, dass unsere Commits jetzt nicht sofort ausgeführt werden und warten müssen, bis der Master den Cache aktualisiert.
Da wir überhaupt nicht warten wollten, haben wir Hooks in GitLab erstellt. Dadurch konnte im Commit angegeben werden, für welchen Minion Sie den Cache aktualisieren müssen. Der Cache von Pillars reduzierte die Last erheblich und die Zeit zum Anwenden der Konfiguration.
Stufe 3
Wir haben ein wenig über Debug-Protokolle meditiert und eine Hypothese aufgestellt: Was ist, wenn wir das Aktualisierungsintervall für das Datei-Backend und den Dateilisten-Cache (gitfs_update_interval, fileserver_list_cache_time) erhöhen? Das Update fand einmal pro Minute statt und dauerte manchmal bis zu 15 Sekunden. Durch Erhöhen des Aktualisierungsintervalls von 1 Minute auf 10 Minuten haben wir wieder an Geschwindigkeit gewonnen! Der LA-Indikator verringerte sich von 1,5 auf 0,5. Die Zeit zum Anwenden der Konfiguration wurde auf die gewünschten 20 Sekunden reduziert. Trotz der Tatsache, dass LA nach einiger Zeit wieder wuchs, änderte sich die Geschwindigkeit der Ausführung von state.apply nicht wesentlich. Ein erzwungenes Update dieser Caches wurde den Hooks bei Git Push hinzugefügt.

Wir haben Elasticsearch um Analysen erweitert: Wir haben die integrierte elasticsearch_return neu geschrieben und können jetzt die Ergebnisse von state.apply (durchschnittliche Ausführungszeit, längster Status und Anzahl der Fehler) verfolgen.
Ergebnisse
Jetzt sind wir mit der Leistung von Salt völlig zufrieden. Es ist geplant, die Anzahl der Schergen zu verdoppeln. Wie unser Meister mit einer solchen Belastung umgehen wird, ist immer noch schwer zu sagen. Vielleicht wenden wir uns der horizontalen Skalierung zu oder finden einen magischen Parameter. Die Zeit wird zeigen!
Wenn Sie gitfs als Backend verwenden, geben Sie ihm eine Fünf! Wahrscheinlich haben Sie dieselben Probleme wie wir. Gerne diskutieren wir dieses Thema in den Kommentaren.