Как узнать причину выхода из контейнера докеров?

110

У меня есть контейнер Docker, работающий на хосте с 1 ГБ оперативной памяти (на том же хосте работают и другие контейнеры). Приложение в этом контейнере Docker будет декодировать некоторые изображения, которые могут потреблять много памяти.

Время от времени этот контейнер будет выходить. Я сомневаюсь, что это связано с нехваткой памяти, но не очень уверен. Мне нужен способ найти первопричину. Итак, есть ли способ узнать, что произошло в связи со смертью этого контейнера?

Ли Бин
источник
6
Вы можете проверить журналы для этого контейнера через docker logs <container-id>.
techtabu
2
но контейнер вышел, я думаю, я больше не могу его регистрировать?
Ли Бин
Только что попробовал на своей машине. Вы все еще можете получить доступ к журналам, даже когда контейнер вышел.
Samuel Toh
Вы хоть пробовали?
techtabu
techtabu, да я сделал. Это все равно не помогает,
Ли Бин

Ответы:

127

Другие упомянули docker logs $container_idо просмотре вывода приложения. Это всегда было моей первой проверкой.

Затем вы можете запустить, docker inspect $container_idчтобы просмотреть подробную информацию о состоянии, например:

    "State": {
        "Status": "exited",
        "Running": false,
        "Paused": false,
        "Restarting": false,
        "OOMKilled": false,
        "Dead": false,
        "Pid": 0,
        "ExitCode": 2,
        "Error": "",
        "StartedAt": "2016-06-28T21:26:53.477229071Z",
        "FinishedAt": "2016-06-28T21:26:53.478066987Z"
    },

Важная строка - «OOMKilled», которая будет истинной, если вы превысите ограничения памяти контейнера и Docker убьет ваше приложение. Вы также можете найти код выхода, чтобы узнать, определяет ли он причину выхода вашего приложения.

Обратите внимание, это только указывает, убивает ли сам докер ваш процесс, и требует, чтобы вы установили ограничение памяти для вашего контейнера. Вне докера ядро ​​Linux может обмануть ваш процесс, если на самом хосте не хватает памяти. Linux часто записывает в журнал / var / log, когда это происходит. С помощью Docker Desktop в Windows и Mac вы можете настроить память, выделенную для встроенной виртуальной машины Linux, в настройках докера.

BMitch
источник
9
Я не понимаю, так как мой контейнер исчез, как «проверить» будет работать? Из обсуждения выше, как только приложение умирает, умирает и контейнер. Вы имеете в виду перезапустить тот же образ, а затем проверить?
Ли Бин
10
@LiB в контейнере не стирается, когда он умирает, он просто переходит в состояние остановки, такое как статус = остановлен или завершен. 'docker ps -a' и убедитесь сами
Самуэль То
Я получал выход 0 каждый раз, когда выполнял операцию с интенсивным использованием памяти, и OOMKilled было ложным. Увеличение памяти заставило его снова заработать.
Андрей
1
Это может произойти, если ядро ​​Linux, а не движок докера, убивает процессы в контейнере. Вы часто будете видеть это в журналах ОС в / var / log на хосте.
BMitch
6

Вы можете узнать, был ли процесс внутри контейнера OOMkilled, прочитав логи. OOMkills инициируются ядром, поэтому каждый раз, когда это происходит, есть несколько строк /var/log/kern.log, например:

python invoked oom-killer: gfp_mask=0x14000c0(GFP_KERNEL), nodemask=(null), order=0, oom_score_adj=995
oom_kill_process+0x22e/0x450
Memory cgroup out of memory: Kill process 31204 (python) score 1994 or sacrifice child
Killed process 31204 (python) total-vm:7350860kB, anon-rss:4182920kB, file-rss:2356kB, shmem-rss:0kB
пенополистирол
источник
Этот ответ помог мне найти, что не так с контейнером, который докер перезапускает при выходе (проверка докеров здесь не очень помогает).
m90,
0

Хотя принятый ответ - лучший вариант, иногда может быть полезно проверить с хоста и содержимое журнала (в Linux).

Вы можете сделать это, набрав:

sudo journalctl -u docker

или следить за ним

sudo journalctl -u docker -f

или уменьшите вывод, если он слишком длинный для вашего терминального буфера

journalctl -xn -u docker | less
Роберто Манфреда
источник