Случилась одна непонятная ситуация с контейнером и разбирательства ушли в исследование лимитов.
Проблема была связана с java. Через какое-то время в логах появлялись ошибки:
java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached
Если гуглить эту ошибку, то везде советую проверить и изменить лимиты, если такое требуется. Однако, у меня вроде всё было безлимитно (что надо), а какие-либо манипуляции не особо помогали.
Отмечу, что ошибка выше как пишут в интернете, не всегда относится именно к нехватки памяти.
Информация в интернете оказалась для мня очень разрозненной и совсем не собранной, а зачастую и копированной от статьи к статье. Делаю выдержку со всем, что накопал и что пригодилось.
nano /etc/systemd/user.conf
Ссылку на этот файл при установки лимитов нашёл далеко не срезу. Ниже пояснения к содержанию файла и установки лимитов.
Directive ulimit equivalent Unit LimitCPU= ulimit -t Seconds LimitFSIZE= ulimit -f Bytes LimitDATA= ulimit -d Bytes LimitSTACK= ulimit -s Bytes LimitCORE= ulimit -c Bytes LimitRSS= ulimit -m Bytes LimitNOFILE= ulimit -n Number of File Descriptors LimitAS= ulimit -v Bytes LimitNPROC= ulimit -u Number of Processes LimitMEMLOCK= ulimit -l Bytes LimitLOCKS= ulimit -x Number of Locks LimitSIGPENDING= ulimit -i Number of Queued Signals LimitMSGQUEUE= ulimit -q Bytes LimitNICE= ulimit -e Nice Level LimitRTPRIO= ulimit -r Realtime Priority LimitRTTIME= No equivalent
Сервисы запущенны при помощи systemd игнорируют файл /etc/security/limits.conf. Очень много вопросов по форумам, почему установка лимитов в этом файле не приводит к желаемому результатов и про systemd там никто не пишет. Для таких сервисов надо указывать лимиты в конфиге /etc/systemd/system.conf или их файле запуска:
[Unit] Description=Some Daemon After=syslog.target network.target [Service] Type=notify LimitNOFILE=20000 ExecStart=/usr/sbin/somedaemon [Install] WantedBy=multi-user.target
Посмотреть лимит на конкретный сервис по PID: cat /proc/PID/limits.
ulimit -c 0 # Запрещаем создавать core файлы ulimit -d 48000 # Ограничиваем максимальный размер сегмента данных в 48 MB ulimit -s 8192 # Ограничиваем максимальный размер стэка в 8 MB ulimit -m 48000 # Ограничиваем максимальный размер резидентной части процесса (находящейся в ОЗУ) в 48 MB ulimit -u 64 # Ограничиваем максимальное число запущенных этим пользователем процессов. ulimit -n 128 # Ограничиваем максимальное число открытых файлов. ulimit -f 100000 # Ограничиваем максимальный размер создаваемого файла в 100 MB ulimit -v 100000 # Ограничиваем максимальный размер используемой виртуальной памяти в 100 MB
Посмотреть общее кол-во тредов в системе:
ps -elfT | wc -l
А вот скрипт, который показывает использование некоторых лимитов в процентах.
#!/bin/bash paste <(grep 'open files\|processes\|pending signals' /proc/self/limits | cut -c27-38) <(i=`whoami` ; lsof -n -u $i 2> /dev/null | tail -n +2 | awk {'print $9'} | wc -l; ps --no-headers -U $i -u $i u | wc -l ; ps -u $i -o pid= | xargs printf "/proc/%s/status\n" | xargs grep -s 'SigPnd' | sed 's/.*\t//' | paste -sd+ | bc ; ) <(grep 'open files\|processes\|pending signals' /proc/self/limits | cut -c1-19) | while read a b name ; do printf '%3i%% %s\n' $((${b}00/a)) "$name" ; done
Вот результат его работы:
0% Max processes 14% Max open files 0% Max pending signals
# cat /proc/sys/fs/file-nr
Пример вывода:
2208 0 13061774
Первое число — общее количество занятых/используемых на данный момент времени файловых дескрипторов.
Второе число — количество выделенных процессам, но не используемых в данный момент дескрипторов.
Третье число — максимальное количество открытых дескрипторов
Open files
посмотреть hard и soft лимиты
ulimit -Hn
ulimit -Sn
Это лимиты для КАЖДОГО пользователя.
/proc/sys/fs/file-max — это лимит открытых файлов для ВСЕХ пользовалей
cat /proc/sys/kernel/pid_max — This is the maximum number of unique process identifiers your system can support
В системе есть параметр DefaultTask или DefaultTasksMax (в зависимости от версии systemd). Проверить чему он равен можно следующей командой:
systemctl show --property=DefaultTasksMax
Так на Debian 9 он у меня был равен DefaultTasksMax=4915 (и в некоторых случая это может привести к ошибкам работы программ, если это prodaction решения). На CentOS7 (OpenVZ), например, результат был DefaultTasksMax=18446744073709551615.
Чтобы изменить этот параметр или сделать его безлимитным, надо в файле /etc/systemd/system.conf найти строчку DefaultTasksMax и привести к виду:
DefaultTasksMax=infinity
После чего выполнить:
systemctl daemon-reload
Ссылки на использованный материал:
linoxide.com/limit-processes-user-level-linux/
wiki.it-kb.ru/unix-linux/linux-cli-tools/how-to-check-all-open-files-by-process-or-user-in-linux