Docker容器磁盘满的排查与解决
Mr.Lee 2026-04-14 11:53:27 Docker
新接手一个项目,服务部署在 Docker 容器中。磁盘突然打满导致服务挂掉,本文记录问题排查与解决过程。
# 问题分析
# 1. 查看磁盘占用
# 查看服务器磁盘占用情况
du -h / -d 1 2>/dev/null
1
2
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
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
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
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
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
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 内存 |
# 总结
通过本次问题排查:
- 日志滚动必须纳入容器部署规范,避免单文件无限增长
- runlike 工具可以快速还原未知容器的启动命令,便于重建
- JVM 参数需要显式声明资源限制,配合容器资源限制实现更精确的资源管控