Ограничения дескриптора файла Ulimit не применяются для конкретного процесса

14

Недавно я проверил один из наших процессов redis к тому, что ulimits, где применяется, используя:

cat /proc/<redis-pid>/limits

И был удивлен, узнав, что это было при низком значении по умолчанию:

Limit                     Soft Limit           Hard Limit           
Max open files            4016                 4016 

Я был удивлен, потому что у нас настроено следующее:

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

Может кто-нибудь сказать мне, почему увеличенный ulimit не применяется к запущенному процессу redis?

Процесс redis выполняется как пользователь 'redis', сервер был перезагружен, так как ограничения были увеличены. Мы на Debian Squeeze.

UpTheCreek
источник

Ответы:

19

В Linux ограничения ресурсов могут быть установлены в разных местах в зависимости от типа требования.

  1. /etc/security/limits.conf файл.
  2. /etc/sysctl.conf файл.
  3. ulimit команда

/etc/security/limits.confявляется частью pam_limits, поэтому ограничения, установленные в этом файле, читаются модулем pam_limits во время сеансов входа в систему. Сеанс входа в систему может быть sshили через terminal. И pam_limits не повлияет на процессы демона, как упомянуто здесь .

/etc/sysctl.confэто глобальная конфигурация всей системы, здесь мы не можем установить конкретную конфигурацию пользователя. Он устанавливает максимальный объем ресурса, который может использоваться всеми пользователями / процессами, помещаемыми в gether.

ulimitКоманда используется для установки ограничений оболочки. И поэтому, когда для ulimitоболочки установлен лимит , процесс, который запускается из оболочки, также получает это значение из-за правила, которое child processнаследует parent processesсвойства.

И так для вашего случая, поскольку redisзапуск как часть initничего из вышеперечисленного не поможет вам напрямую. Правильный способ сделать это состоит в том, что вы должны использовать ulimitкоманду для установки нового значения в самом скрипте инициализации. Как показано ниже в сценарии,

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

В списке пожеланий уже есть ошибка, к которой можно добавить ulimitфункцию start-stop-daemon .

Также проверьте в redisконфигурации, есть ли какой-либо способ установить ограничения там.

Каннан Мохан
источник
Отличное резюме Каннан! Теперь я пошел вперед и добавил ulimit в скрипт запуска. Жаль, что нет способа просто установить предел для пользователя, который будет работать с деамонизированными процессами (так как у нас есть несколько сценариев запуска), но это работает. Спасибо!
UpTheCreek
Отличный ответ. Меня удивило то, что дочерний процесс, унаследовавший свойства родительского процесса, все ограничения выглядели корректно для пользователя, выполняющего дочерний процесс, но это был предел от владельца родительского процесса, который использовался.
Синхронизация
2

Параметр sysctl fs.file-max является широким глобальным системным пределом, я не думаю, что это хорошая идея для установки того же значения в ulimit.

Если вы установили ulimit 100000 и sysctl.conf 100000, один пользователь может заблокировать систему

В любом случае, говоря о вашей проблеме, вы должны быть уверены, что ваша система использует pam_limits

man pam_limits
grep -i limit /etc/pam.d/*
c4f4t0r
источник
Спасибо - тогда я подумаю о повышении значения fs.file-max. Что касается pam - я думаю, что мы используем это (я добавил несколько дополнительных настроек в вопрос). Я не совсем уверен, что понимаю PAM, поскольку наши настройки, похоже, относятся к SSH, который не используется этим пользователем. Есть ли другой файл, который мне нужно настроить? Я всегда мог поставить параметр ulimit в сценарии инициализации для redis, но я бы не стал этого делать.
UpTheCreek,
2

Вы включили pam_limits для sshd, но выполняется ли эта команда из сеанса SSH? Возможно, вам придется добавить ту же строку в /etc/pam.d/loginи / или /etc/pam.d/suи / или /etc/pam.d/sudo.

вездесущность
источник
Благодарю. Я подозревал, что это было не совсем правильно. Процесс идет начал эту строку в init.d скрипт: if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS. Какая Пэм подойдет в этом случае?
UpTheCreek,
в вашем скрипте вы можете использовать ulimit -n 100000
c4f4t0r
Использует ли скрипт init.d su [user] -cкоманду для запуска скрипта от имени другого пользователя, или ваша программа запускается от имени пользователя root? Если он использует su, то вы бы вставили /etc/pam.d/su. Если вы работаете как root, вам, вероятно, лучше с предложением c4f4t0r добавить ulimitкоманду в ваш скрипт инициализации. rootразрешено устанавливать любые ограничения, которые он хочет, так что вам не нужно беспокоиться о pam для этого случая.
Вездесущность
1
Благодарю. Используется --chuid redis:redisна start-stop-daemon. Теперь я добавил ulimit в скрипт запуска.
UpTheCreek