Les limites du descripteur de fichier Ulimit ne sont pas appliquées pour un processus particulier

14

J'ai récemment vérifié l'un de nos processus redis pour savoir quels ulimits étaient appliqués en utilisant:

cat /proc/<redis-pid>/limits

Et a été surpris d'apprendre qu'il était à la faible valeur par défaut:

Limit                     Soft Limit           Hard Limit           
Max open files            4016                 4016 

J'ai été surpris, car nous avons configuré les éléments suivants:

# /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

Quelqu'un peut-il me dire pourquoi l'augmentation ulimit n'est pas appliquée au processus de redis en cours d'exécution?

Le processus redis s'exécute en tant qu'utilisateur «redis», le serveur a été redémarré depuis que les limites ont été augmentées. Nous sommes sur Debian Squeeze.

Jusqu'à la crique
la source

Réponses:

19

Sous Linux, les limites de ressources peuvent être définies à divers emplacements en fonction du type d'exigence.

  1. /etc/security/limits.conf fichier.
  2. /etc/sysctl.conf fichier.
  3. ulimit commander

/etc/security/limits.conffait partie de pam_limits et donc les limites qui sont définies dans ce fichier sont lues par le module pam_limits pendant les sessions de connexion. La session de connexion peut être par sshou via terminal. Et pam_limits n'affectera pas les processus du démon comme mentionné ici .

/etc/sysctl.confest une configuration globale à l'échelle du système, nous ne pouvons pas définir de configuration spécifique à l'utilisateur ici. Il définit la quantité maximale de ressources qui peut être utilisée par tous les utilisateurs / processus mis ensemble.

ulimitest utilisée pour définir les limites du shell. Et donc quand une limite est définie avec ulimitsur un shell, le processus qui est généré à partir du shell obtient également cette valeur en raison de la règle qui child processhérite de laparent processes propriétés.

Et donc pour votre cas, comme le redisdémarrage de initrien de ce qui précède ne vous aidera directement. Pour ce faire, vous devez utiliser la ulimitcommande pour définir la nouvelle valeur dans le script init lui-même. Comme ci-dessous dans le script,

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

Il y a déjà un bug dans la liste de souhaits pour ajouter une ulimitfonctionnalité àstart-stop-daemon .

Vérifiez également dans la redisconfiguration s'il existe un moyen de fournir des limites.

Kannan Mohan
la source
Grand résumé Kannan! Je suis maintenant allé de l'avant et j'ai ajouté ulimit au script de démarrage. Dommage qu'il n'y ait aucun moyen de simplement fixer la limite pour l'utilisateur qui fonctionnera avec les processus désamonisés (car nous avons plusieurs scripts de démarrage), mais cela fonctionne. Je vous remercie!
UpTheCreek
Très bonne réponse. Le processus enfant héritant des propriétés du processus parent m'a surpris, les limites semblaient toutes correctes pour l'utilisateur exécutant le processus enfant, mais c'était la limite du propriétaire du processus parent qui était utilisée.
synchronisation
2

Le paramètre sysctl fs.file-max est une large limite globale du système, je ne pense pas que ce soit une bonne idée de définir dans ulimit la même valeur.

Si vous définissez dans ulimit 100000 et dans sysctl.conf 100000 également, un utilisateur peut bloquer le système

De toute façon, en parlant de votre problème, vous devez être sûr que votre système utilise pam_limits

man pam_limits
grep -i limit /etc/pam.d/*
c4f4t0r
la source
Merci - je vais alors envisager d'augmenter la valeur fs.file-max. Concernant le pam - je crois que nous l'utilisons (j'ai ajouté quelques config supplémentaires à la question). Je ne suis pas vraiment sûr de comprendre PAM, car nos paramètres semblent être liés à SSH, qui n'est pas utilisé par cet utilisateur. Y a-t-il un autre fichier que je dois configurer? Je pourrais toujours mettre un paramètre ulimit dans les scripts d'initialisation pour redis, mais je préfère ne pas avoir à le faire.
UpTheCreek
2

Vous avez activé pam_limits pour sshd, mais cette commande est-elle exécutée à partir d'une session SSH? Vous devrez peut-être ajouter la même ligne à /etc/pam.d/loginet / ou /etc/pam.d/suet / ou /etc/pam.d/sudo.

Omniprésence
la source
Merci. Je soupçonnais que ce n'était pas tout à fait ça. Le processus est en cours de démarrage de cette ligne dans un script init.d: if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS. Quel pam serait approprié dans ce cas?
UpTheCreek
dans votre script, vous pouvez utiliser ulimit -n 100000
c4f4t0r
Le script init.d utilise-t-il une su [user] -ccommande pour démarrer le script en tant qu'autre utilisateur ou votre programme s'exécute-t-il en tant que root? S'il utilise su, alors vous le mettriez /etc/pam.d/su. Si vous utilisez as root, vous feriez probablement mieux avec la suggestion de c4f4t0r d'ajouter la ulimitcommande dans votre script init. rootest autorisé à définir toutes les limites qu'il souhaite, vous n'avez donc pas vraiment à vous soucier du pam pour ce cas.
Omniprésence
1
Merci. Il utilise --chuid redis:redissur start-stop-daemon. J'ai ajouté ulimit au script de démarrage maintenant.
UpTheCreek