引言

如果您的应用程序日志(例如,Nginx的访问日志、Web应用的调试信息等)被配置为输出到控制台,Docker会忠实地将它们全部记录下来。若不加以控制,这个 *-json.log 文件会随着时间的推移无限增长,达到数十甚至数百GB的规模。 而在容器内扫描时,并不会包含这个由Docker服务自身管理的日志文件。

Docker常用的 overlay2存储驱动采用的是写时复制(Copy-on-Write, CoW)机制。当容器需要修改镜像中的某个文件时,它不会直接修改只读的镜像层,而是在一个可写的容器层(upperdir)中创建一个副本进行修改。

这意味着:

  • 首次写入: 会复制一份原始文件,产生双倍的空间占用。
  • 文件删除: 在容器内删除一个文件,实际上是在可写层创建了一个标记该文件已删除的“白化文件”(whiteout file),而原始文件仍然存在于下层的镜像中。

因此,频繁的文件写入和删除操作,即使最终文件被删除了,也可能在 overlay2的各层中留下历史数据,导致宿主机上的目录比容器内看起来要大。

清理日志

检查容器日志文件大小

首先,在宿主机上执行以下命令,查看哪个容器的日志文件最大:

ls -lh /var/lib/docker/containers/*/*-json.log | sort -hr | head -n 5

这条命令会列出最大的5个容器日志文件。找到占用空间异常的容器ID。

清理现有日志

如果急需释放空间,可以直接清空日志文件(注意:这会丢失现有日志):

# 将<容器ID>替换为实际的容器ID
truncate -s 0 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log

配置日志轮转

为避免问题再次发生,强烈建议配置Docker的日志驱动进行自动轮转。您可以修改Docker的守护进程配置文件 /etc/docker/daemon.json,为所有新创建的容器设置默认的日志选项:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}

上述配置表示,每个容器的日志文件最大为100MB,最多保留3个轮转的日志文件。修改后需要重启Docker服务:

sudo systemctl restart docker

对于已存在的容器,您需要在 docker-compose.ymldocker run命令中单独指定日志选项。

文章作者: oohmygosh
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Blog
喜欢就支持一下吧