Один из проектов, над которым я работаю, - это перемещение некоторых кукольных ulimit
настройки от "это звучит примерно правильно" до динамически выделяемых в зависимости от среды. Это для сред с одним приложением, поэтому я больше всего беспокоюсь о том, чтобы предотвратить нехватку ресурсов для приложения, сохраняя при этом ядро и служебные пространства в достаточном количестве дескрипторов и еще много чего, чтобы делать то, что они должны.
Мы получаем постоянные запросы от app-команд на напильником моар ручками! поэтому я пытаюсь найти способ справиться с этим. Итак, я сделал марионеточный факт:
Facter.add('app2_nofile') do
confine :kernel => 'Linux'
setcode do
kernel_nofile = `/bin/cat /proc/sys/fs/file-max`.chomp
app2_limit = (kernel_nofile.to_i * 0.85).round
app2_limit
end
end
Что делает то, что написано на банке. Принимает значение ядра, определенное в /proc/sys/fs/file-max
и возьмите 85%, оставив 15% на использование системы. Установите мягкий и жесткий nofile ulimit с помощью этого ::app2_nofile
на самом деле в другом марионеточном ресурсе, поэтому /etc/security/limits.conf обновляется, и тада! Просто! Если им нужно больше файловых дескрипторов, им нужно будет умнее писать приложение.
Только вот это не сработало. При попытке открыть сеанс пользователя (su app2_user -
) с пользователем с этим nofile
ulimit, получаем сообщение об ошибке:
Не удалось открыть сеанс
Что плохо.
Ясно, что где-то есть верхняя граница, не зависящая от простых ulimits. Или, может быть, я понимаю, как они работают. Как nofile
пределы взаимодействуют друг с другом, и что может привести к невозможности создания сеанса?
Дальнейшее тестирование предполагает, что верхняя граница может быть статической границей или более сложной, чем простые проценты. В системе с малым ОЗУ и максимальным размером файла 797 567 этот ulimit может быть установлен очень высоко, и я не получу воспроизведения. В более крупной системе с 1 619 938 я могу установить этот ulimit примерно на 63%, прежде чем я получу сообщение «не удалось открыть сеанс». У меня сейчас нет ничего большего, чтобы проверить, перемещается ли этот процент с большей оперативной памятью.
Я получаю запись audit.log:
type=USER_START msg=audit(1416420909.479:511331): user pid=5022 uid=0 auid=1194876420 ses=44826
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:session_open
acct="app2" exe="/bin/su" hostname=? addr=? terminal=pts/0 res=failed'
Операция была операцией PAM.
Похоже, это особенность PAM:
https://bugzilla.redhat.com/show_bug.cgi?id=485955
Хотя это не окончательно, источник - это то место, куда можно пойти, это сильно наводит на мысль, что PAM устанавливает какой-то потолок для определенных ресурсов. Прорыв случился, когда я использовал strace на su
команда, чтобы увидеть, что она пыталась сделать, что было отклонено, и я увидел эту строку:
setrlimit (RLIMIT_NOFILE, {rlim_cur = 1049000, rlim_max = 1049000}) = -1 EPERM (операция запрещена)
В audit.log ничего не записывается, кроме сбоя PAM, syslog ничего не показывает, это просто сбой.
Для своих целей я напишу этот факт, чтобы взять меньшее из статического значения или 85% от максимального количества файлов ядра. Мне нужно провести дополнительное тестирование, чтобы выяснить, каким будет это статическое значение, но похоже, что этот гибридный метод будет лучше поддерживаться инструментами.