Docker 是一款强大的容器化工具,可以帮助我们快速搭建和运行各种应用。作为一名技术宅,如果你还没用上 Docker,出门都不好意思跟人打招呼🤭。然而,在日常使用中,我们往往会忽略一个关键问题——容器日志的持续增长。
我最近就碰到了一个典型的例子:家里 HomeLab 的一台服务器突然磁盘空间告急,原本分配给 Docker 的 30GB 磁盘空间快要被撑爆。经过排查才发现,光是容器日志就占用了近 20GB。这种日志暴涨的情况,还真是让人猝不及防💔。
为了帮大家避坑,本文将详细讲解如何有效管理 Docker 容器日志,包括查看日志大小、清理现有日志,以及合理设置日志大小限制等。
Docker 容器重启和重建的关键区别
在深入讨论之前,让我们先明确一个重要概念:虽然 Docker 容器是无状态的,在重建容器时就会清除日志,但实际情况可能跟你的预期会不太一样。
还是结合我的亲身经历来现身说法:尽管过去一年中服务器多次重启,Docker 容器也随之停止和启动,但日志文件却一直在持续增长。这是为什么呢?
原因在于「重启」和「重建」是两个完全不同的操作:
- 当你在使用
systemctl restart docker
重启 Docker 服务或重启服务器时,Docker 守护进程会先停止运行中的容器,然后再根据配置自动拉起。但这一过程中,日志文件并不会被清除。 - 只有当容器被完全删除并重新创建时,日志才会被重置。
比如,你在使用像 lobe-chat 这种经常逛刷版本👍的容器,多半不会遇到日志持续增长的问题。但如果你使用的容器万年不更新,就可能会遇到跟我一样的日志翻车🚗情况。
推荐使用 Portainer 来管理 Docker 容器。
检查 Docker 日志大小
抛开使用集成系统日志(如 syslog、journald)和集中式日志管理工具(如 gelf、fluentd、awslogs 和 gcplogs 等),Docker 的本地轻量级日志存储主要使用了json-file
和db
二进制日志格式。
Docker 默认配置
通常,Docker 容器的日志文件默认存放在以下路径:
/var/lib/docker/containers/<容器ID>/<容器ID>-json.log
- 在
/var/lib/docker/containers/
目录下,每个容器都有独立的文件夹,里面存放着以json.log
结尾的文本文件,这些就是容器的日志文件。 - 这些日志文件采用 JSON 格式,记录了容器的
stdout
(标准输出)和stderr
(标准错误)信息。 - 要快速查看所有容器日志的大小并按降序排列,可以使用以下命令:
find /var/lib/docker/containers/ -name "*json.log" | xargs du -h | sort -hr
群晖 DSM 7.x
如果你使用的是群晖 DSM 7.x 系统中的 Container Manager,默认会使用db
二进制日志格式。相比json-file
,db
格式可以减少存储空间占用和日志解析的开销。
- 日志存储位置如下:
/var/packages/ContainerManager/var/docker/containers/<容器ID>/log.db
- 要快速查看所有容器日志的大小并按降序排列,可以使用以下命令:
find /var/packages/ContainerManager/var/docker/containers/ -name "log.db" | xargs du -h | sort -hr
通过 ID 找出 Docker 容器名称
1现在,按日志大小排序的容器 ID 已经拿到手,你可以执行以下命令,来查看容器的对应名称:
docker inspect --format='{{.Name}}' <容器ID>
2要进一步确认容器信息,或查看该容器的更多详细信息,可以使用:
docker inspect <容器名称>
3(可选)如果你只想查看容器日志文件的具体位置,可以使用更精确的命令:
docker inspect --format='{{.LogPath}}' <容器名称>
清理 Docker 容器日志
truncate
命令不能直接用来清理db
二进制日志。
在确定了需要处理的日志文件后,我们就可以开始着手清理工作了。这里我要介绍两种方法:
- 单个容器的精准清理:你可以使用 Linux 的
truncate
命令来快速清空日志文件的内容,而不删除文件本身:
truncate -s 0 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log
该操作会清空日志文件中的所有内容,但不会影响容器的正常运行,Docker 可以继续向这个文件写入新的日志。
- 批量清理所有容器日志:如果要一次性清理所有容器的日志,可以使用以下命令:
truncate -s 0 /var/lib/docker/containers/*/*-json.log
批量清理虽然方便,但会清空所有容器的历史日志,请根据实际情况谨慎使用。
限制 Docker 容器日志大小
虽然前面的方法可以暂时解决日志增长问题,但需要经常手动执行命令,不太符合「懒人」的需求。要更优雅且一劳永逸地管理日志文件大小,可以通过配置 Docker 守护进程来自动管理。
1根据你的实际情况,编辑 Docker 守护进程的配置文件,如果文件不存在,就手动创建:
- 标准 Docker:
sudo vi /etc/docker/daemon.json
- 群晖 DSM 7.x 系统中的 Container Manager:
sudo vi /var/packages/ContainerManager/etc/dockerd.json
2在文件中添加以下配置(这里设置单个日志文件最大为 10MB,只保留 3 个历史文件):
{
"log-driver": "json-file", // 使用 json-file 文本格式或 db 二进制日志
"log-opts": {
"max-size": "10m", // 单个日志文件最大为 10MB
"max-file": "3" // 最多保留 3 个历史日志文件
}
}
3保存文件后,重启 Docker 服务让配置生效:
- 标准 Docker:
sudo systemctl restart docker
- 群晖 DSM 7.x 系统中的 Container Manager:
sudo synosystemctl restart pkgctl-ContainerManager
新的设置仅对新创建的容器生效,已经在运行的容器不会自动应用新配置。要让现有容器使用新的日志配置,你需要重建这些容器。
4配置完成后,你可以通过以下命令检查容器是否已应用新的日志设置:
docker inspect <容器名称>
最新评论
目前没有这个功能,只能每次启动应用程序后,手动将其拖动到目标虚拟桌面。
另外,多桌面好像经常有bug,最底下的任务栏会锁死,比如图标失效,时间静止,怎么破?
搭车,win11能否设定某个app在固定桌面启动?我是按照功能分桌面的,比如:浏览,聊天,工作1,工作2,游戏。。。
1.需要无线网卡支持 AP 模式;2.无线网卡通常不能同时作为客户端和热点工作(可以使用有线网络作为热点的互联网来源);3.可以使用 nmcli 或其他工具创建虚拟无线网卡接口,这样就可以同时连接 Wi-Fi 和创建热点。4.使用双无线网卡,一个联网,一个当热点。