DevOps

Ansible, Logrotate, Millionen Dateien und Timeouts

Bekanntlich steuern wir so gut wie alles auf unseren Servern mit Ansible. Dazu zählt auch die Konfiguration von logrotate. Ansible erstellt mittels der template-Funktion entsprechende logrotate-Konfigurationsdateien, rollt sie auf die gewünschten Hosts aus und überprüft die Funktion mittels des Debug-Modus von logrotate.

Während einer Konfigurationsänderung auf allen Hosts hat Ansible bei drei Hosts eines Datenbank-Clusters nicht mehr reagiert, auch einSTRG-C oder quit() haben nicht funktioniert, einzig ein kill auf den Ansible-Prozess haben geholfen. Subsequente Ansible-Läufe hatten den gleichen Ausgang, hier musste ich also näher analysieren.

Andere Ansible-Playbooks liefen problemlos auf den Hosts, es musste also was mit dem logrotate-Playbook zu tun haben. Zum Glück führt die zugehörige Rolle nur 2 Aufgaben aus, eine davon das Kopieren der Konfigurationen und Validieren dieser.

Der nächste Schritt beim Problemlösen war, Ansible im verbose-Mode laufen zu lassen. Dort gab es jedoch auch keine ungewöhnlichen Ereignisse, nur eben, dass der copy-Task nicht weiterläuft. Ansible funktioniert grundlegend so, dass es alle zu übertragenden Dateien sowie Python-Scripte auf den Client überträgt und dort das Python-Script ausführt, was dann die eigentliche Aufgabe durchführt. Eine dieser übertragenenen Dateien war eine normale logrotate-Konfigurationsdatei.

Um zu sehen, ob das Problem nun bei Ansible oder logrotate liegt, habe ich die übertragene Datei in logrotate gefüttert:

Dieser Aufruf lief dann minutenlang, also war das Problem doch bei logrotate zu suchen! Ein Aufruf von logrotate mit den bereits vorhandenen Konfigurationsdateien hat ebenfalls so lange gedauert, also scheint es nicht an der neuen Konfiguration gelegen zu haben.

Um zu sehen, was genau der logrotate-Prozess tut, habe ich ihn mit strace gestartet:

Dieser Aufruf hat Millionen folgender Zeilen produziert:

Zu diesem Problem gibt es bereits viele Lösungen im Internet, keine hat jedoch zu Erfolg geführt. Beim Durchlesen der man-Page für logrotate fiel mir dann auf, dass logrotate selbt eine Status-Datei schreibt, in der der Bearbeitungsstatus der Dateien vermerkt ist, welche logrotate bearbeitet.

Eine Überprüfung der Datei ergab dann, dass diese 222MB groß ist und 2383547 (2,3 Millionen) Zeilen beinhaltet! Etwas viel für eine Statusdatei.

In der Datei selbst fand ich dann den Grund für die lange Laufzeit: logrotate hat Millionen von Status-Dateien des Datenbankclusters verwaltet. Eine kurze Absprache mit den Kollegen hat dann ergeben, dass dies ursprünglich so eingerichtet wurde, da logrotate dann aber stundenlang lief, wurde die Konfiguration wieder zurückgebaut, so dass logrotate keine Statusdateien des Clusters mehr rotiert.

Leider hat die Status-Datei von logrotate dies nicht mitbekommen und weiterhin versucht, alle Dateien, die in ihr standen, zu rotieren; selbst wenn sie nicht mehr vorhanden waren.

Die Lösung des Problems war dann trivial: Die Statusdatei löschen und einen neuen logrotate-Lauf starten, so dass die Datei neu erzeugt wurde. Dann war die Rotation auch nur noch eine Sache von Sekunden und Ansible konnte die Konfiguration wieder auf allen Hosts anpassen.

Beitragsbild: Wikimedia Commons

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.