Ulimit-Dateideskriptorgrenzwerte werden für bestimmte Prozesse nicht angewendet

14

Ich habe kürzlich einen unserer Redis-Prozesse daraufhin überprüft, welche Ulimits angewendet wurden:

cat /proc/<redis-pid>/limits

Und war überrascht zu erfahren, dass es sich um den niedrigen Standardwert handelt:

Limit                     Soft Limit           Hard Limit           
Max open files            4016                 4016 

Ich war überrascht, weil wir folgendes konfiguriert haben:

# /etc/sysctl.conf 
fs.file-max = 100000

.

# /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000

.

# /etc/ssh/sshd_config
UsePAM yes

.

# /etc/pam.d/sshd
session required pam_limits.so

Kann mir jemand sagen, warum das erhöhte ulimit nicht auf den laufenden Redis-Prozess angewendet wird?

Der Redis-Prozess wird ausgeführt, während der Benutzer "redis" ausgeführt wird. Der Server wurde neu gestartet, da die Grenzwerte erhöht wurden. Wir sind bei Debian Squeeze.

UpTheCreek
quelle

Antworten:

19

Unter Linux können Ressourcenlimits je nach Anforderung an verschiedenen Orten festgelegt werden.

  1. /etc/security/limits.conf Datei.
  2. /etc/sysctl.conf Datei.
  3. ulimit Befehl

/etc/security/limits.confist Teil von pam_limits und daher werden die in dieser Datei festgelegten Grenzwerte während der Anmeldesitzungen vom pam_limits-Modul gelesen. Die Anmeldesitzung kann von sshoder durch sein terminal. Und pam_limits wirkt sich nicht auf die hier erwähnten Daemon-Prozesse aus .

/etc/sysctl.confist eine systemweite globale Konfiguration, hier können wir keine benutzerspezifische Konfiguration einstellen. Hiermit wird die maximale Ressourcenmenge festgelegt, die von allen Benutzern / Prozessen verwendet werden kann, die zusammengeführt werden.

ulimitBefehl wird verwendet, um die Grenzen der Shell festzulegen. Wenn also ein Limit ulimitfür eine Shell festgelegt wird, erhält der Prozess, der von der Shell erzeugt wird, aufgrund der Regel, dass child processdie parent processesEigenschaften geerbt werden, auch diesen Wert .

Und so wird Ihnen in Ihrem Fall, da das redisals Teil von initkeinem der oben genannten Schritte gestartet wird, direkt weiterhelfen. Um dies zu erreichen, müssen Sie den ulimitBefehl verwenden, um den neuen Wert im Init-Skript selbst festzulegen. Wie unten im Skript,

ulimit -n 100000
if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS.

Es ist bereits ein Fehler in der Wunschliste , dem Sie eine ulimitFunktion hinzufügen können start-stop-daemon .

Überprüfen Sie auch in der redisKonfiguration, ob es dort eine Möglichkeit gibt, Grenzen festzulegen.

Kannan Mohan
quelle
Tolle Zusammenfassung Kannan! Ich habe jetzt das ulimit zum Startskript hinzugefügt. Es ist schade, dass es keine Möglichkeit gibt, nur das Limit für den Benutzer festzulegen, das mit desaminierten Prozessen funktioniert (da wir mehrere Startskripten haben), aber das funktioniert. Vielen Dank!
UpTheCreek
Gute Antwort. Der untergeordnete Prozess, der die Eigenschaften des übergeordneten Prozesses erbt, hat mich überrascht. Die Grenzwerte sahen für den Benutzer, der den untergeordneten Prozess ausführt, korrekt aus, es war jedoch das Limit des Eigentümers des übergeordneten Prozesses, der verwendet wurde.
synchronisieren
2

Der Parameter sysctl fs.file-max ist ein weites globales Systemlimit. Ich halte es nicht für eine gute Idee, in ulimit denselben Wert festzulegen.

Wenn Sie ulimit 100000 und sysctl.conf 100000 angeben, kann ein Benutzer das System blockieren

Wenn Sie über Ihr Problem sprechen, müssen Sie sicher sein, dass Ihr System pam_limits verwendet

man pam_limits
grep -i limit /etc/pam.d/*
c4f4t0r
quelle
Danke - Ich werde dann in Betracht ziehen, den Wert für fs.file-max zu erhöhen. In Bezug auf Pam - ich glaube, wir verwenden dies (ich habe der Frage eine zusätzliche Konfiguration hinzugefügt). Ich bin mir allerdings nicht sicher, ob ich PAM verstehe, da unsere Einstellungen sich auf SSH zu beziehen scheinen, das von diesem Benutzer nicht verwendet wird. Gibt es eine andere Datei, die ich konfigurieren muss? Ich könnte in den Init-Skripten für redis immer eine ulimit-Einstellung setzen, müsste dies aber lieber nicht tun.
UpTheCreek
2

Sie haben pam_limits für sshd aktiviert. Wird dieser Befehl jedoch in einer SSH-Sitzung ausgeführt? Möglicherweise müssen Sie dieselbe Zeile zu /etc/pam.d/loginund / oder /etc/pam.d/suund / oder hinzufügen /etc/pam.d/sudo.

Allgegenwart
quelle
Vielen Dank. Ich vermutete, dass das nicht ganz richtig war. Der Prozess wird diese Zeile in einem init.d Skript gestartet: if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS. Welche Pam wäre in diesem Fall angebracht?
UpTheCreek
In Ihrem Skript können Sie ulimit -n 100000
c4f4t0r
Verwendet das Skript init.d einen su [user] -cBefehl, um das Skript als anderer Benutzer zu starten, oder wird Ihr Programm als Root ausgeführt? Wenn es verwendet wird su, würden Sie es in setzen /etc/pam.d/su. Wenn Sie als rootausführen, sind Sie wahrscheinlich mit dem Vorschlag von c4f4t0r, den ulimitBefehl in Ihr Init-Skript einzufügen, besser dran . rootEs ist erlaubt, beliebige Limits festzulegen, sodass Sie sich in diesem Fall nicht wirklich um pam kümmern müssen.
Omnipresence
1
Vielen Dank. Es verwendet --chuid redis:redisauf start-stop-daemon. Ich habe das ulimit jetzt zum Startskript hinzugefügt.
UpTheCreek