Вопрос или проблема
Когда я пытаюсь запустить любой Docker контейнер с интерактивным терминалом, я получаю следующую ошибку:
$ docker run -it --rm my-container
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: open /dev/ptmx: no space left on device: unknown.
На моем текущем диске и на диске, где установлен Docker, по-прежнему много свободного места. Единственная ссылка на эту проблему, которую я нашел до сих пор, в этом посте на форуме, где предполагается, что количество псевдотерминалов превышает пороговое значение. Я протестировал это на своей системе:
$ ls /dev/pts | wc -l
756
$ sysctl kernel.pty.max
kernel.pty.max = 4096
и обнаружил, что количество псевдотерминалов все еще значительно ниже максимального значения. Удаление завершенных контейнеров и docker system prune
тоже не помогло. После docker system prune
количество файлов в /dev/pts
падает до 751, но проблема остается.
В чем проблема и как ее решить?
- Версия Docker: 20.10.17, сборка 100c701
- Система: Ubuntu 20.04
Увеличение максимального количества псевдотерминалов с помощью sudo sysctl -w kernel.pty.max=8192
действительно смягчает эту проблему, но, как мне кажется, это только отодвигает проблему в будущее. Нет ли более устойчивого решения этой проблемы?
Я не могу прокомментировать, так как только что создал аккаунт, но я думаю, что обсуждение выше идет в неправильном направлении. Столкнувшись с той же проблемой, я обнаружил, что в /dev в docker-инстансе содержатся три элемента: /dev/shm, /dev/pts и /dev/console.
Это не так, как должно быть. Я думаю, что обсуждение выше ошибочно сосредоточилось на /dev на хост-системе… Я предполагаю, что либо /dev должен быть смонтирован в контейнере, и это не так, либо устройства /dev должны существовать на файловой системе контейнера, и их нет.
Обновлю здесь, когда у меня будет больше информации.
Интересная заметка: недавно у меня возникла проблема с моим разделом /var/lib/docker, и мне пришлось его сбросить. Я думаю, что сделал это неправильно, и это причина проблемы.
Извините, что ответ неполный, постараюсь улучшить его со временем.
Ответ или решение
Теория
Ошибка, с которой вы столкнулись, связана с запуском контейнера Docker, когда он не может открыть устройство /dev/ptmx
из-за нехватки, как это ни парадоксально, "места на устройстве". Хотя может показаться, что это связано с недостаточным объемом хранения, фактически это о нехватке доступных псевдотерминалов (pty), используемых для интерактивных сеансов терминала. В системах на базе Unix/Linux псевдотерминалы обеспечивают интерфейс между процессами, позволяя взаимодействие, напоминающее взаимодействие с физическим терминалом.
В контексте Docker, взаимодействие контейнера с хостовой системой происходит через shim
— легкие процессы, которые связывают контейнеры с управляющим процессом докера. Если контейнеру не удается открыть ptmx
, как в вашем случае, это может указывать на проблему со слишком малым числом доступных псевдотерминалов или неправильной конфигурацией монтирования устройств /dev
в контейнере.
Пример
Вы упомянули, что количество созданных псевдотерминалов при проверке (ls /dev/pts | wc -l
) составляет 756, в то время как предел вашей системы (sysctl kernel.pty.max
) — 4096. Это говорит о том, что количественная проблема не относится непосредственно к нехватке псевдотерминалов на хостовом уровне. Тем не менее, поскольку увеличение kernel.pty.max
до 8192 смягчает проблему, указывает на потенциальное исчерпание ресурсов в определенных условиях использования.
Одним из пользователей также было отмечено, что /dev
в экземпляре Docker содержит только /dev/shm
, /dev/pts
и /dev/console
, но кажется, что каких-то других устройств может не хватать. Это еще больше указывает на возможные проблемы с конфигурацией монтирования.
Применение
1. Проверка и настройка монтирования /dev
Убедитесь, что ваше монтирование каталога /dev
в контейнере корректно настроено. Обычно Docker сам монтирует устройства, однако если была использована кастомная конфигурация или если произошла ошибка в конфигурации после изменений в файловой системе Docker, это может вызвать подобные проблемы.
-
Пересоздайте конфигурацию Docker: Если вы проводили манипуляции с разделом
/var/lib/docker
, как упоминалось в одном из комментариев, возможно, что восстановление или повторная инициализация этого раздела может помочь. Это обеспечит, чтоdocker
инициализирует раздел правильно. -
Проверка параметров монтирования: Убедитесь, что в конфигурации Docker нет опций или конфигураций, которые бы ограничивали или изменяли стандартное поведение контейнера при монтировании
/dev
.
2. Расширение лимитов псевдотерминалов
Увеличение kernel.pty.max
с текущих 4096 до более высокого значения действительно может уменьшить вероятность возникновения ошибки. Однако это временное решение, и может возникнуть снова, если система будет запускать многочисленные процессы, требующие создания множества псевдотерминалов.
- Системный мониторинг: Наблюдайте за системными ресурсами и частотой возникновения ошибки. Если вы проводите интенсивные операции в Docker, возможно, потребуется регулярная очистка или реструктуризация процессов.
3. Проверка на проблемы конкретной версии Docker
Как вариант, убедитесь, что у вас установлена последняя версия Docker для вашей системы. Могут существовать исправления или улучшения, касающиеся управления псевдотерминалами, не отраженные в текущей вашей версии 20.10.17.
- Плановое обновление: Периодическое обновление Docker может предотвратить устаревание и устранить проблемы с совместимостью, приводящие к ошибкам.
4. Логирование и диагностика
Создайте системный журнал для отслеживания появления ошибки. Это упростит обнаружение ситуации, при которой ресурсы исчерпываются, и может помочь в разработке стратегий по управлению загрузкой системы.
В заключение, данная проблема скорее связана с конкретной настройкой вашей среды Docker или действующими процессами, чем с явными проблемами в системе как таковой. Правильная настройка монтирования, управление ресурсами и систематическое обновление Docker могут сыграть ключевую роль в предотвращении подобных ошибок в будущем.