Striveonger

vuePress-theme-reco Mr.Lee    2015 - 2026
Striveonger Striveonger
主页
分类
  • 笔记
  • 文章
  • 工具
  • 读书/工具
标签
时间轴
简历
author-avatar

Mr.Lee

274

Article

145

Tag

主页
分类
  • 笔记
  • 文章
  • 工具
  • 读书/工具
标签
时间轴
简历

Docker容器磁盘满的排查与解决

vuePress-theme-reco Mr.Lee    2015 - 2026

Docker容器磁盘满的排查与解决

Mr.Lee 2026-04-14 11:53:27 Docker

新接手一个项目,服务部署在 Docker 容器中。磁盘突然打满导致服务挂掉,本文记录问题排查与解决过程。

# 问题分析

# 1. 查看磁盘占用

# 查看服务器磁盘占用情况
du -h / -d 1 2>/dev/null
1
2

典型输出显示 /var 目录占用过大,进一步定位到 Docker 相关目录:

du -h /var/lib/docker/containers/ -d 1 2>/dev/null
1

# 2. 定位问题目录

发现某个容器的日志文件高达 44GB:

# Σ(°ロ°)...一个日志文件44G
❯ ls -lah /var/lib/docker/containers/7e554b6634fa97afefb1a95667496822db601af56bdb6ddd6e625ca7281c87d0
total 44G
drwx--x---  4 root root 4.0K Apr 10 11:00 .
drwx--x--- 10 root root 4.0K Sep 27  2025 ..
-rw-r-----  1 root root  44G Apr 13 16:55 7e554b6634fa97afefb1a95667496822db601af56bdb6ddd6e625ca7281c87d0-json.log
drwx------  2 root root 4.0K Sep 27  2025 checkpoints
-rw-------  1 root root 4.2K Apr 10 11:00 config.v2.json
-rw-------  1 root root 1.6K Apr 10 11:00 hostconfig.json
-rw-r--r--  1 root root   13 Apr 10 11:00 hostname
-rw-r--r--  1 root root  172 Apr 10 11:00 hosts
drwx--x---  2 root root 4.0K Sep 27  2025 mounts
-rw-r--r--  1 root root  334 Apr 10 11:00 resolv.conf
-rw-r--r--  1 root root   71 Apr 10 11:00 resolv.conf.hash
1
2
3
4
5
6
7
8
9
10
11
12
13
14

问题根因:容器的 JSON 日志文件没有滚动策略,不断追加导致磁盘占满。

# 解决思路

为容器日志加入滚动策略:

docker run -d \
  --name my-app \
  --log-driver local \         # 指定驱动 (可省略,默认为json-file)
  --log-opt max-size=100m \    # 单文件限制 100MB
  --log-opt max-file=3 \       # 最多保留 3 个文件
  --log-opt compress=true \    # (可选) 启用压缩
  your-image
1
2
3
4
5
6
7

# 使用 runlike 还原容器启动命令

前人没有留下启动脚本,Jenkins 部署只做了 jar 包替换和 restart。使用 runlike 工具从现有容器还原启动命令:

pipx install runlike

~/.local/share/pipx/venvs/runlike/bin/runlike java
1
2
3

输出示例:

docker run --name=java --hostname=52e915b9ab4e \
  --volume /var/fs/cgroup:/sys/fs/cgroup:ro \
  --volume /var/local/docker/java/data:/java \
  --volume /var/local/docker/java/logs:/logs \
  --env=TZ=Asia/Shanghai \
  --env='JAVA_OPTS=-Xms512m -Xmx800m ...' \
  --network=bridge -p 8880:8080 \
  --restart=always --runtime=runc --detach=true \
  bellsoft/liberica-openjdk-debian:17.0.11-cds \
  java -Djdk.internal.platform.CgroupMetrics.enabled=false -jar /java/ruoyi-admin.jar
1
2
3
4
5
6
7
8
9
10

原理:runlike 分析的是 docker inspect java 中的内容。

# 最终部署脚本

#!/bin/bash

docker stop java && docker rm java

JAVA_OPTS=" \
-XX:InitialRAMPercentage=75.0 \
-XX:MaxRAMPercentage=75.0 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/logs/heapdump.hprof \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+UseStringDeduplication \
-XX:+AlwaysPreTouch \
-XX:+ExitOnOutOfMemoryError \
-XX:MetaspaceSize=512m \
-XX:MaxMetaspaceSize=512m \
-Xlog:gc*:file=/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=100m \
-Dlogging.file.path=/logs \
-Dfile.encoding=UTF-8 \
-Dprofile=dev"

docker run \
       --name=java \
       --cpus=4 \
       --memory=8g \
       --volume /var/local/docker/java/data:/java \
       --volume /var/local/docker/java/logs:/logs \
       --env=TZ=Asia/Shanghai \
       --env="JAVA_OPTS=$JAVA_OPTS" \
       --network=bridge \
       -p 8880:8080 \
       --restart=always \
       --runtime=runc \
       --detach=true \
       --log-driver local \
       --log-opt max-size=100m \
       --log-opt max-file=5 \
       --log-opt compress=true \
       bellsoft/liberica-openjdk-debian:17.0.11-cds \
       sh -c "java \$JAVA_OPTS -jar /java/ruoyi-admin.jar"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 关键优化点

# 1. JVM 启动参数优化

参数 说明
-XX:InitialRAMPercentage=75.0 初始 RAM 百分比
-XX:MaxRAMPercentage=75.0 最大 RAM 百分比
-XX:+HeapDumpOnOutOfMemoryError OOM 时生成堆转储
-XX:HeapDumpPath=/logs/heapdump.hprof 堆转储文件路径
-XX:+UseG1GC 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis=200 最大 GC 暂停时间
-XX:+UseStringDeduplication 启用字符串去重
-XX:+AlwaysPreTouch 预触碰内存
-XX:+ExitOnOutOfMemoryError OOM 时退出进程
-XX:MetaspaceSize=512m 初始元空间大小
-XX:MaxMetaspaceSize=512m 最大元空间大小
-Xlog:gc*:file=/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=100m GC 日志滚动

# 2. Docker 日志滚动策略

参数 说明
--log-driver local 使用本地日志驱动
--log-opt max-size=100m 单个日志文件最大 100MB
--log-opt max-file=5 最多保留 5 个日志文件
--log-opt compress=true 启用日志压缩

# 3. 容器资源限制

参数 说明
--cpus=4 限制容器最多使用 4 个 CPU
--memory=8g 限制容器最多使用 8GB 内存

# 总结

通过本次问题排查:

  1. 日志滚动必须纳入容器部署规范,避免单文件无限增长
  2. runlike 工具可以快速还原未知容器的启动命令,便于重建
  3. JVM 参数需要显式声明资源限制,配合容器资源限制实现更精确的资源管控