Назад | Перейти на главную страницу

sudo: невозможно создать сокеты: невозможно выделить память

На VPS под управлением OVH (очевидно, на основе OpenVZ, учитывая /proc/user_beancounters существует) с относительно небольшим количеством запущенных процессов, пытающихся sudo дает мне ошибку в заголовке.

Вот образец стенограммы:

ekleog@ekleog:~$ sudo echo a
[sudo] password for ekleog:
sudo: unable to create sockets: Cannot allocate memory
ekleog@ekleog:~$ free -h
             total       used       free     shared    buffers     cached
Mem:          8.0G       212M       7.8G         0B         0B        43M
-/+ buffers/cache:       168M       7.8G
Swap:         128M         0B       128M
ekleog@ekleog:~$ sudo echo a
sudo: unable to create sockets: Cannot allocate memory

Как видите, разветвление не вызывает никаких проблем, так как оболочка запускается. free, но sudo кажется, не может открыть сокет. В том же домене thunderbird не может открыть соединение SMTP, но ssh продолжает без проблем туннелировать новые запросы.

Тот факт, что проблема возникает из-за слишком большого количества открытых сокетов, подтверждается тем фактом, что при закрытии Thunderbird (который сохраняет около 50 подключений для мониторинга всех моих папок IMAP) проблема исчезает. Кроме того, при повторном открытии проблема не возвращается, значит, где-то должна быть утечка ресурсов?

В настоящее время у меня есть один пользователь (я), поэтому я надеюсь, что ограничения OVH не такие серьезные.

Наконец, во время «кризиса» я пробовал бегать netstat (особо не привык к его использованию, поэтому могу ошибаться):

ekleog@ekleog:~$ netstat -a | wc -l
608
ekleog@ekleog:~$ cat /proc/sys/fs/file-max
1627524

Мне кажется странным, что sudo заблокировал бы.

Ты хоть представляешь, как это перестать? Он появляется время от времени (примерно раз в два дня) и становится изрядно надоедливым.

Видимо проблема исходит из настроек OpenVZ, как в /proc/user_beancounters у меня есть numothersock с огромным failcnt.

Пытаясь уменьшить количество открытых сокетов, зависящих от каждой отдельной программы, я задам отдельные вопросы.

Я собираюсь поделиться своими выводами в этом ответе, надеясь, что это поможет кому-то в будущем. Эти результаты были бы невозможны без оперативного наблюдения в комментарии @ EEAA.

Действительно, ограничение исходит от программного обеспечения OpenVZ. В numothersock ограничение можно увидеть в /proc/user_beancounters и согласно документации: 'Ресурсы UBC в Parallels Virtuozzo Containers для Linux':

номер - максимальное количество сокетов не-TCP (локальные сокеты, UDP и другие типы сокетов).

Вы можете проверить количество розеток с помощью ss:

сс используется для вывода статистики сокетов.

ss -xa | wc -l

Чтобы определить, какой процесс связывает каждый сокет:

sudo ss -xap

В моем конкретном случае оказалось, что более 25% моих ограничений в сокетах было связано с постфиксом, поэтому я сократил default_process_limit параметр в /etc/postfix/main.cf (соответствующий вопрос Вот).

(Синонимический ответ, но с добавлением некоторой диагностической информации и ключевых слов для поиска.)

Симптомы

Проблема заключается в том, что новые сокеты, отличные от TCP, не могут быть созданы, что означает, что в основном сокеты домена Unix используются для межпроцессного взаимодействия в системе. Это может быть не всегда воспроизводимо, так как иногда удаляются несколько сокетов, открывая несколько вариантов для создания новых сокетов ниже предела.

Симптомы не ограничиваются sudo использовать, но повлияет на большинство или все веб-сайты, работающие на вашем сервере и использующие MySQL через сокет. Сообщения об ошибках могут быть такими:

PDOException: SQLSTATE[HY000] [2001] Can't create UNIX socket (12) in […]
PDOException: SQLSTATE[HY000] [2002] Can't connect to local MySQL server 
    through socket '/var/run/mysqld/mysqld.sock' (12) in […]
PHP Warning:  mysqli_connect(): (HY000/2001): Can't create UNIX socket 
    (12) in […]
PHP Warning:  mysqli_connect(): (HY000/2002): Can't connect to local MySQL 
    server through socket '/var/run/mysqld/mysqld.sock' (12) in […]

Кроме того, отправка и получение сообщений электронной почты через postfix соотв. dovecot сервер, вероятно, также выйдет из строя на этапе входа в систему. Сообщения об ошибках включают:

mailq: fatal: inet_addr_local[getifaddrs]: getifaddrs: Cannot allocate memory

Типичным элементом этих ошибок является код ошибки 12, что означает «Код ошибки ОС 12: невозможно выделить память» согласно perror 12 [источник].

Решение

Посмотрите на вывод cat /proc/user_beancounters, который показывает ограничения среды виртуализации OpenVZ вашего VPS. По всей вероятности, вы увидите огромное количество отказов для numothersock лимит ресурсов там (> 10 000 для меня). Это означает, что программа пыталась создать сокет, но OpenVZ запретил это делать, потому что максимальное количество сокетов, отличных от TCP, уже существует.

Чтобы увидеть количество и использование всех сокетов, учтенных в этом numothersock ограничение ресурсов, посмотрите выходной файл, созданный:

ss --processes --all --socket=udp,unix,unix_dgram,unix_stream > results.txt 

В моем случае он показал, что около 80% сокетов были связаны с процессами postfix и dovecot. Количество сокетов, связанных с Postfix, можно уменьшить примерно до 10%, ограничив количество одновременных подключений со 100 по умолчанию до разумных 10 - см. инструкции. После применения этого решения к postfix (default_process_limit = 10) и перезапустив его, количество используемых сокетов сразу изменилось с ~ 1020 до ~ 520. Проблема решена на данный момент.