Systemd: wenn set-default nicht funktioniert

Fedora empfiehlt auf den eigenen Seiten, daß man das Default.Target mit dem Befehl:

systemctl set-default graphical.target

setzen könnte. Das  graphical.target ist dabei die Desktopoberfläche. Mit dem multi-user.target bekommt man nur die auf Server übliche Textkonsole zusehen.

Leider stimmt das nicht für jede Fedoraversion und z.b. bei Fedora 19 muß man selbst Hand anlegen:

ln -sf /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target

Man kann auch den direkten runlevel als Ziel angeben:

z.b.  /etc/systemd/system/default.target -> /lib/systemd/system/runlevel3.target

Im laufenden Betrieb kann man als Root mithilfe des isolate Befehls zwischen den Runleveln umschalten. Das ist zu Debugzwecken ganz praktisch.

systemctl isolate multi-user.target

Systemd schickt alte Einträge zum Syslogd

Die Bild-Zeitung könnte mit der folgenden Schlagzeile öffnen:

„Systemd wahnsinnig – Syslogd kurz vor dem Zusammenbruch“

Wenn man einen Produktivserver im Netz hat, möchte man solche Schlagzeilen lieber nicht lesen, dennoch können Sie passieren. Mit den folgenden kleinen Anweisungen kann man das Desaster beenden.

Aber zunächst mal zum eigentlichen Problem:

Der Syslogd läuft mit 95% CPU Last, aber ansonsten ist auf dem System nichts zu sehen, was die Nachrichten produzieren könnte. Der erste Blick geht daher nach /var/log/messages:

Jul 16 20:21:01 systemd: Started Session 29860 of user root.
Jul 16 20:21:01 systemd: Starting Session 29859 of user munin.
Jul 16 20:21:01 systemd: Started Session 29859 of user munin.
Jul 16 20:21:01 systemd: Starting Session 29862 of user root.
Jul 16 20:21:01 systemd: Started Session 29862 of user root.
Jul 25 07:34:20 rsyslogd-2177: imjournal: begin to drop messages due to rate-limiting

Was wir sehen, sind eine Flut von alten Nachrichten und die Meldung, daß imournal daran gehindert wurde, weitere Nachrichten zu loggen, weil es zu viele wurden. Was Sie oben nicht sehen ist, daß das Ganze mit Nachrichten aus April begonnen hat. 3,7 GB an Logfiles sollten nochmal durch den Syslogd gejagt werden.

Auch wenn die eigentlichen Nachrichten nicht mehr in /var/log/messages auftauchen, so verbraucht der Syslogd trotzdem noch eine Menge CPU Leistung, meistens soviel er bekommt.

Ein Neustart von syslogd machts nur schlimmer, weil die alten Nachrichten dann wieder ins Log geschrieben werden.

Die Lösung:

Man editiere /etc/systemd/journald.conf :

 [Journal]
 #Storage=auto
 #Compress=yes
 #Seal=yes
 #SplitMode=login
 #SyncIntervalSec=5m
 #RateLimitInterval=30s
 #RateLimitBurst=1000
 #SystemMaxUse=
 #SystemKeepFree=
 #SystemMaxFileSize=
 #RuntimeMaxUse=
 #RuntimeKeepFree=
 #RuntimeMaxFileSize=
 #MaxRetentionSec=
 #MaxFileSec=1month
 #ForwardToSyslog=yes
 #ForwardToKMsg=no
 #ForwardToConsole=no
 #TTYPath=/dev/console
 #MaxLevelStore=debug
 #MaxLevelSyslog=debug
 #MaxLevelKMsg=notice
 #MaxLevelConsole=info

in dem man das hier einfügt oder ändert, ganz wie Sie möchten:

[Journal]
 MaxRetentionSec=10day

Wenn man dann den Journaldienst des Systemd neustartet, werden alle alten Files aus /var/log/journal/ entfernt und der Systemd schickt nur noch 10 Tage Logs an den Syslogd. Das ist aber i.d.R.  in wenigen Sekunden durch und die Last des Systems geht auf normal zurück.

 systemctl restart systemd-journald

Als positiver Seiteneffekt werden gleich noch monatealte Logdaten gelöscht. In unserem Fall waren es satte 3 GB.

Das Ende der Orgie erkennt man im Logfile des Syslogds an dieser Meldung:

Jul 25 07:35:13 rsyslogd-2177: imjournal: 229963 messages lost due to rate-limiting

Das wäre früher oder vermutlich sehr viel später auch ohne die Anpassungen im in der journal.conf passiert.

Da aber nach 17 Minuten erst 1 Monat verarbeitet wurde, ist es aus Performancegründen des Servers ratsam das zu beschleunigen.

Systemd und die Limits

„Jedes System kommt irgendwann an seine Grenzen.“ Einer meiner Server hatte die Grenze heute überschritten. Die Folge, der Apache stieg mit dieser Meldung aus :

„apache (24)Too many open files: couldn’t spawn child process:“

Jetzt können Sie soviel googlen wie Sie wollen, alles was zu dem Fehler kommt ist nicht hilfreich. Alle Hinweise  von RedHat zu limitfiles auf  /etc/security/limits.conf  oder /proc/sys/fs/file-max können Sie getrost vergessen, die greifen in dem Fall gar nicht.

Wenn Sie jetzt ein System V haben, ist /etc/init.d/httpd für Sie da. Tragen Sie dort einfach ulimit -n 100000 ein und starten Sie den Apache neu. Fall erledigt.

Für den Systemd, wie ihn Fedora seit FC 16 einsetzt, sieht die Sache ähnlich einfach aus, wenn man weiß wo man suchen muß. Aber mal ehrlich, würden SIe als Linuxer darauf kommen, daß „man systemd.exec“ die Hilfeseite zum Systemd öffnet? Ich nicht, .exe oder ähnliche Erweiterungen sind Windows Extentions.

Die Manpage liefert eine Übersicht zu den Variblen  die man im Unitfile benutzen kann und eine davon ( immerhin 5 Bildschirmseiten voll davon gibt es ) ist Ihr Freund: „LimitNOFILE

Suchen Sie mit „locate httpd.service“ ihr Unitfile, das ist üblicherweise unter /usr/lib/systemd/system/httpd.service zu finden. Tragen Sie dort im Servicebereich die Variable ein :

[Service]
Type=forking
PIDFile=/var/run/httpd/httpd.pid
LimitNOFILE=1000000
EnvironmentFile=/etc/sysconfig/httpd

Führen Sie noch die zwei Zeilen aus :

systemctl –system daemon-reload
systemctl restart httpd

und Ihr Apache rennt wieder 🙂

Ursachenanalyse:

Jedes Apache Child öffnet alle Domainlogs auf dem Server. Wenn Sie nun einen Multidomainwebserver haben, so wie meine Kunden, dann kommen dort schnell 1000 Vhosts zusammen. Das macht 1000 Files pro httpd-Child und damit viel mehr offene Files als Fedora defaultmäßig bereitstellt.

Hier wäre natürlich ein Logfilebroker für Apache die richtige Lösung, aber da brauchen wir wohl seitens Apache nicht drauf hoffen.