Есть ли способ снова спасти печать в файл журнала, не уничтожая (перезагружая) контейнеры?
Да, но это скорее уловка, чем реальное решение. Вы никогда не должны напрямую взаимодействовать с /var/lib/docker
данными . Согласно Docker docs :
часть файловой системы хоста [которая] управляется Docker (/var/lib/docker/volumes/
на Linux). Процессы, отличные от Docker, не должны изменять эту часть файловой системы.
Чтобы этот трюк сработал, вам необходимо настроить демона Docker, чтобы контейнеры оставались живыми во время простоя перед первым запуском нашего контейнера. Например, установив свой /etc/docker/daemon.json
с помощью:
{
"live-restore": true
}
Это требует перезапуска демона, такого как sudo systemctl restart docker
.
Затем создайте контейнер и удалите его .log
файл:
$ docker run --name myhttpd -d httpd:alpine
$ sudo rm $(docker inspect myhttpd -f '{{ .LogPath }}')
# Docker is not happy
$ docker logs myhttpd
error from daemon in stream: Error grabbing logs: open /var/lib/docker/containers/xxx-json.log: no such file or directory
Restart Daemon (с живым восстановлением), это заставит Docker каким-то образом повторно взять управление нашим контейнером и создать наш файл журнала. Однако любые журналы, созданные до удаления файла журнала, будут потеряны.
$ sudo systemctl restart docker
$ docker logs myhttpd # works! and log file is created back
Примечание: это не документированная или официальная функция Docker, это просто поведение, которое я наблюдал в моих собственных экспериментах с использованием Docker 19.03
. Он может не работать с другими Docker версиями
При включенном восстановлении в реальном времени наш процесс контейнера продолжает работать, даже если Docker демон остановлен. При перезапуске демона Docker он, вероятно, каким-то образом попытается перечитать из еще живого процесса stdout
и stderr
и перенаправить вывод в наш файл журнала (следовательно, воссоздать его)