Вопрос или проблема
У меня есть сервер Ampere ARM64, и я запускаю на нем кучу контейнеров Docker (Frigate, Immich, InfluxDB, HomeAssistant).
Однако, похоже, у меня возникла проблема с Frigate, который использует несколько ядер на 100% – и это также сделало сервер неотзывчивым:
https://github.com/blakeblackshear/frigate/discussions/15298
Мне хотелось бы узнать, есть ли способ безопасно
остановить некорректный контейнер или, если это необходимо, перезагрузить сервер. (В идеале я хотел бы избежать резкого отключения питания и также избежать потери данных/очистки других контейнеров)
Попытка обычной перезагрузки, похоже, потерпела неудачу:
victorhooi@ampere-01 ~/homeassistant-docker> sudo shutdown -r now
[sudo] пароль для victorhooi:
Не удалось установить сообщение на стене, игнорируется: Время соединения истекло
Вызов перезагрузки не удался: Время соединения истекло
Я попытался остановить проблемный контейнер Frigate – и эта команда в основном зависла там на несколько часов:
victorhooi@ampere-01 ~/frigate-docker> docker compose stop
WARN[0000] /home/victorhooi/frigate-docker/compose.yml: атрибут `version` устарел, он будет проигнорирован, пожалуйста, удалите его, чтобы избежать потенциальной путаницы
[+] Остановка 0/1
⠋ Контейнер frigate Остановка 32232.1s
nB
Команды Docker, похоже, не работают должным образом – docker stop
, docker kill
не работают (они просто зависают) – также не работают, скажем, docker top
, docker inspect
и т.д.
Даже попытка остановить другие контейнеры Docker на сервере, не связанные с Frigate, кажется, зависает.
Я даже попытался отправить SIGKILL некоторым из проблемных процессов в этом контейнере – команда вернулась, но процессы продолжали работать.
Вывод из top:
Но я попробовал htop
, и он завис.
У меня есть некоторые выводы из ps/pstree с сервера:
- https://gist.github.com/victorhooi/18926f95bb1adf3c31461691c63dadfb
- https://gist.github.com/victorhooi/5335f6b86c10242c04bcae5ac7992ba6
- https://gist.github.com/victorhooi/b3eb16c85e9077db66320f324f1cd2b4
Из поисков в Google кажется, что systemctl --force --force reboot
может сработать – однако это может вызвать потерю данных и т.д. – я хотел бы немного больше понять, прежде чем слепо выполнять эту команду.
В любом случае – мои вопросы:
- Контейнеры не изолированы, как ВМ – но какие вещи могут вызвать зависание хост-машины таким образом?
- Есть ли какие-либо проверки, которые я мог бы провести над контейнером, его текущим состоянием? Или временные данные, которые следует собрать?
- Какой самый безопасный способ убить некорректный контейнер? Или, если это невозможно, перезагрузить сервер?
- Есть ли ограничения, которые могут помочь предотвратить это? (Я полагаю, это во многом зависит от причины проблемы. Странная вещь в том, что у меня осталось много ядер – Frigate использует только несколько из них на 100% – так почему Docker в целом неотзывчив?)
Правка: Попытка использовать systemctl
, чтобы получить статус службы docker, также терпит неудачу:
sudo systemctl status docker
[sudo] пароль для victorhooi:
Не удалось получить свойства: Транспортный конечный пункт не подключен```
Ответ или решение
Ваша ситуация с запущенными контейнерами Docker на сервере ARM64 достаточно сложна и требует внимательного рассмотрения различных аспектов. Давайте подробно разберем каждый ваш вопрос и предложим возможные шаги для решения проблемы.
1. Причины, по которым контейнеры могут зависнуть и повлиять на работоспособность хоста
Контейнеры Docker изолированы друг от друга и от самого хост-системного уровня, но существуют множество факторов, которые могут привести к блокировке системы. Вот некоторые из них:
-
Перегрузка процессора: Некоторые контейнерные приложения, такие как Frigate, могут потреблять слишком много ресурсов CPU, что ведет к деградации производительности всей системы. Если потребление ядер слишком высоко, это может заблокировать системные процессы, отвечающие за управление контейнерами и сетью.
-
Недостаток ресурсов памяти: Если контейнер использует всю доступную оперативную память, система может начать использовать своп, что делает все операции медленными и даже приводит к зависанию.
-
Блокировки на уровне файловой системы: Если процесс внутри контейнера обращается к файлам, которые заблокированы из-за неправильного использования или конфликта, это может привести к зависанию.
-
Сетевые конфликты: Если контейнеры интенсивно используют сетевые ресурсы, это может привести к конфликтам, особенно в условиях высокой нагрузки.
2. Исследования текущего состояния контейнера и сбор данных
В условиях, когда Docker-команды не отвечают, можно провести следующие действия:
-
Просмотр активных процессов: Используйте команду
ps aux
для мониторинга процессов, связанных с Docker и контейнерами. Это может помочь найти процессы, вызывающие блокировки. -
Сбор журналов Docker: Если журналирование включено, попробуйте получить журналы контейнера через
docker logs <container-id>
. Это может дать представление о том, что именно происходит. -
Использование командных инструментов: Иногда инструменты, такие как
lsof
иstrace
, могут помочь выявить блокировки и длительные операции, если система позволяет это сделать.
3. Безопасные способы остановки контейнера или перезагрузка системы
Поскольку команда shutdown
и стандартные команды для остановки контейнеров зависли, рассмотрите следующие подходы:
-
Использование
kill
: Если вы видите идентификаторы процесса контейнера черезps
, вы можете безопасно попробовать отправить сигналSIGKILL
конкретному процессу Docker, связанному с вашим контейнером, используя командуkill -9 <pid>
. Будьте осторожны, это может привести к потере данных, особенно если приложение сохраняет состояние. -
Использование команды
systemctl
: Еслиsystemctl reboot
также зависает, попробуйте выполнить командуsystemctl isolate rescue.target
, чтобы перевести систему в режим обслуживания. Это может помочь освободить ресурсы и позволить вам нормально перезагрузить систему. -
Аппаратная перезагрузка: Если другие варианты не сработают, возможно, потребуется выполнить аппаратную перезагрузку. Убедитесь, что вы сделали резервные копии важных данных, если это возможно.
4. Предотвращение подобных ситуаций в будущем
Чтобы избежать перегрева системы из-за контейнеров, выполните следующие шаги:
-
Ограничение ресурсов контейнера: Используйте параметры
--memory
,--cpus
и другие для ограничения использования ресурсов каждым контейнером, особенно для Frigate, если он нестабилен. -
Мониторинг ресурсов: Настройте мониторинг системы с помощью инструментов, таких как Prometheus или Grafana, чтобы отслеживать использование ресурсов и получать уведомления о высоких нагрузках.
-
Регулярные обновления: Убедитесь, что все ваши контейнерные приложения и сам Docker обновлены до последних стабильных версий, что может помочь избежать известных проблем.
Следуя этим рекомендациям, вы сможете уменьшить вероятность возникновения вопросов производительности и стабильности в будущем.