719*_*016 5 logging amazon-web-services docker
我有一个在磁盘空间有限的小型 AWS 实例中运行的 docker 容器。日志越来越大,所以我使用下面的命令来删除不断增长的日志文件:
sudo -s -H
find /var -name "*json.log" | grep docker | xargs -r rm
journalctl --vacuum-size=50M
Run Code Online (Sandbox Code Playgroud)
现在我想看看正在运行的 docker 容器之一的行为是什么,但它声称日志文件已经消失(来自rm上面的命令):
ubuntu@x-y-z:~$ docker logs --follow name_of_running_docker_1
error from daemon in stream: Error grabbing logs: open /var/lib/docker/containers/d9562d25787aaf3af2a2bb7fd4bf00994f2fa1a4904979972adf817ea8fa57c3/d9562d25787aaf3af2a2bb7fd4bf00994f2fa1a4904979972adf817ea8fa57c3-json.log: no such file or directory
Run Code Online (Sandbox Code Playgroud)
我希望能够再次看到正在运行的容器中发生了什么,所以我尝试了:
sudo touch /var/lib/docker/containers/d9562d25787aaf3af2a2bb7fd4bf00994f2fa1a4904979972adf817ea8fa57c3/d9562d25787aaf3af2a2bb7fd4bf00994f2fa1a4904979972adf817ea8fa57c3-json.log
Run Code Online (Sandbox Code Playgroud)
再一次docker follow,但是在与应该生成日志的软件进行交互时,我可以看到什么也没有发生。
有没有办法在不杀死(重新启动)容器的情况下再次将打印保存到日志文件中?
有什么方法可以在不杀死(重新启动)容器的情况下再次将打印保存到日志文件中?
是的,但这更像是一个技巧,而不是真正的解决方案。您永远不应该/var/lib/docker直接与数据交互。根据Docker 文档:
主机文件系统的一部分由 Docker 管理(
/var/lib/docker/volumes/在 Linux 上)。非 Docker 进程不应修改文件系统的这一部分。
为了使这个技巧发挥作用,您需要在首次运行容器之前配置Docker 守护进程以在停机期间保持容器处于活动状态。例如,通过设置/etc/docker/daemon.json:
{
"live-restore": true
}
Run Code Online (Sandbox Code Playgroud)
这需要守护进程重新启动,例如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
Run Code Online (Sandbox Code Playgroud)
重新启动守护进程(使用实时恢复),这将导致 Docker 以某种方式重新管理我们的容器并创建我们的日志文件。但是,删除日志文件之前生成的所有日志都会丢失。
$ sudo systemctl restart docker
$ docker logs myhttpd # works! and log file is created back
Run Code Online (Sandbox Code Playgroud)
注意:这不是文档化或官方的 Docker 功能,只是我在使用 Docker 的实验中观察到的行为19.03。它可能不适用于其他 Docker 版本
启用实时恢复后,即使 Docker Daemon 停止,我们的容器进程也会继续运行。在 Docker 守护进程重新启动时,它可能会以某种方式尝试从仍然活动的进程中重新读取stdout并将stderr输出重定向到我们的日志文件(因此重新创建它)