Docker 容器磁盘清理
·
Docker 容器磁盘清理
问题: /var/lib/docker/containers/ 文件过大
# Docker 容器磁盘清理指南
问题分析
/var/lib/docker/containers 目录中有容器占用了大量空间:
- 181G:
5ae1c9345a6e6da0ece25698f6214a90b874417ba61b2e61f2af0413a844bb02 - 15G:
e433a85edaaea86855c6518397c388f88493714ee073f370d270e4e3b118f7f0
这些大文件通常是容器的日志文件(*-json.log)导致的。
快速解决方案
方法 1: 使用清理脚本(推荐)
- cleanup_docker_containers.sh - 交互式清理脚本
提供菜单选择不同清理选项
可查看占用空间最大的容器
支持清理日志、已停止容器、未使用数据等
#!/bin/bash
# Docker 容器清理脚本
# 用于降低 /var/lib/docker/containers 目录的磁盘使用量
set -e
echo "=========================================="
echo "Docker 容器磁盘清理脚本"
echo "=========================================="
echo ""
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 检查是否为 root 用户
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}错误: 请使用 root 权限运行此脚本${NC}"
exit 1
fi
# 显示当前磁盘使用情况
echo -e "${YELLOW}当前容器目录磁盘使用情况:${NC}"
du -sh /var/lib/docker/containers/* 2>/dev/null | sort -hr | head -10
echo ""
# 函数:显示磁盘使用前 N 个容器
show_top_containers() {
echo -e "${YELLOW}占用空间最大的容器:${NC}"
du -sh /var/lib/docker/containers/* 2>/dev/null | sort -hr | head -5
echo ""
}
# 函数:清理容器日志文件
cleanup_logs() {
echo -e "${YELLOW}开始清理容器日志文件...${NC}"
# 查找所有容器的日志文件
find /var/lib/docker/containers/ -name "*-json.log" -type f | while read logfile; do
container_id=$(basename $(dirname $logfile))
log_size=$(du -sh "$logfile" | cut -f1)
echo " 清理日志: $container_id ($log_size)"
# 清空日志文件(保留文件但清空内容)
> "$logfile"
done
echo -e "${GREEN}日志文件清理完成${NC}"
echo ""
}
# 函数:清理已停止的容器
cleanup_stopped_containers() {
echo -e "${YELLOW}开始清理已停止的容器...${NC}"
# 获取已停止的容器
stopped_containers=$(docker ps -a -q -f status=exited)
if [ -z "$stopped_containers" ]; then
echo " 没有已停止的容器"
else
echo " 找到已停止的容器: $(echo $stopped_containers | wc -w) 个"
read -p " 是否删除这些已停止的容器? (y/N): " confirm
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
docker rm $stopped_containers
echo -e "${GREEN}已停止的容器已删除${NC}"
else
echo " 跳过删除已停止的容器"
fi
fi
echo ""
}
# 函数:清理未使用的数据
cleanup_unused_data() {
echo -e "${YELLOW}开始清理未使用的 Docker 数据...${NC}"
read -p " 是否执行 docker system prune? 这将删除未使用的容器、网络、镜像和构建缓存 (y/N): " confirm
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
docker system prune -f
echo -e "${GREEN}未使用的数据已清理${NC}"
else
echo " 跳过清理未使用的数据"
fi
echo ""
}
# 函数:清理特定容器的日志(针对大文件)
cleanup_large_logs() {
echo -e "${YELLOW}查找并清理大日志文件 (>100M)...${NC}"
find /var/lib/docker/containers/ -name "*-json.log" -type f -size +100M | while read logfile; do
container_id=$(basename $(dirname $logfile))
log_size=$(du -sh "$logfile" | cut -f1)
echo " 发现大日志文件: $container_id ($log_size)"
read -p " 是否清空此日志文件? (y/N): " confirm
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
> "$logfile"
echo -e " ${GREEN}已清空: $container_id${NC}"
fi
done
echo ""
}
# 函数:配置日志轮转(daemon.json)
configure_log_rotation() {
echo -e "${YELLOW}配置 Docker 日志轮转...${NC}"
DOCKER_DAEMON_JSON="/etc/docker/daemon.json"
# 备份现有配置
if [ -f "$DOCKER_DAEMON_JSON" ]; then
cp "$DOCKER_DAEMON_JSON" "${DOCKER_DAEMON_JSON}.bak.$(date +%Y%m%d_%H%M%S)"
echo " 已备份现有配置到 ${DOCKER_DAEMON_JSON}.bak.*"
fi
# 创建或更新 daemon.json
cat > "$DOCKER_DAEMON_JSON" <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
echo -e "${GREEN}日志轮转配置已更新:${NC}"
echo " - 单个日志文件最大: 10MB"
echo " - 保留日志文件数: 3"
echo " 需要重启 Docker 服务使配置生效: systemctl restart docker"
echo ""
}
# 主菜单
show_menu() {
echo "请选择操作:"
echo "1) 显示占用空间最大的容器"
echo "2) 清理所有容器日志文件(清空内容)"
echo "3) 清理大日志文件 (>100M)"
echo "4) 清理已停止的容器"
echo "5) 清理未使用的 Docker 数据"
echo "6) 配置日志轮转(防止未来日志过大)"
echo "7) 执行完整清理(选项 2 + 4 + 5)"
echo "8) 退出"
echo ""
}
# 主循环
while true; do
show_menu
read -p "请输入选项 [1-8]: " choice
case $choice in
1)
show_top_containers
;;
2)
cleanup_logs
;;
3)
cleanup_large_logs
;;
4)
cleanup_stopped_containers
;;
5)
cleanup_unused_data
;;
6)
configure_log_rotation
;;
7)
cleanup_logs
cleanup_stopped_containers
cleanup_unused_data
echo -e "${GREEN}完整清理完成!${NC}"
echo ""
show_top_containers
;;
8)
echo "退出"
exit 0
;;
*)
echo -e "${RED}无效选项,请重新选择${NC}"
echo ""
;;
esac
done
# 1. 下载脚本并赋予执行权限
chmod +x cleanup_docker_containers.sh
# 2. 以 root 权限运行
sudo ./cleanup_docker_containers.sh
运行结果



- 快速清理脚本
quick_cleanup.sh - 快速一键清理脚本
自动执行:清空日志 → 删除已停止容器 → 清理未使用数据
适合紧急情况快速释放空间
#!/bin/bash
# 快速清理脚本 - 一键降低 Docker 容器磁盘使用
set -e
echo "=========================================="
echo "Docker 容器快速清理"
echo "=========================================="
echo ""
# 检查是否为 root 用户
if [ "$EUID" -ne 0 ]; then
echo "错误: 请使用 root 权限运行此脚本"
exit 1
fi
# 显示清理前状态
echo "清理前磁盘使用情况:"
du -sh /var/lib/docker/containers/* 2>/dev/null | sort -hr | head -5
echo ""
# 1. 清空所有容器日志
echo "步骤 1/3: 清空所有容器日志文件..."
find /var/lib/docker/containers/ -name "*-json.log" -type f -exec truncate -s 0 {} \; 2>/dev/null
echo "✓ 日志文件已清空"
echo ""
# 2. 清理已停止的容器
echo "步骤 2/3: 清理已停止的容器..."
stopped_count=$(docker ps -a -q -f status=exited 2>/dev/null | wc -l)
if [ "$stopped_count" -gt 0 ]; then
docker rm $(docker ps -a -q -f status=exited) 2>/dev/null || true
echo "✓ 已删除 $stopped_count 个已停止的容器"
else
echo "✓ 没有已停止的容器"
fi
echo ""
# 3. 清理未使用的数据(不删除镜像)
echo "步骤 3/3: 清理未使用的 Docker 数据..."
docker system prune -f 2>/dev/null || true
echo "✓ 未使用的数据已清理"
echo ""
# 显示清理后状态
echo "清理后磁盘使用情况:"
du -sh /var/lib/docker/containers/* 2>/dev/null | sort -hr | head -5
echo ""
echo "=========================================="
echo "清理完成!"
echo "=========================================="
方法 2: 手动清理命令
2.1 清理所有容器日志(最常用,立即见效)
# 查找并清空所有日志文件
find /var/lib/docker/containers/ -name "*-json.log" -exec truncate -s 0 {} \;
# 或者使用更安全的方式(保留文件但清空内容)
find /var/lib/docker/containers/ -name "*-json.log" -type f | while read logfile; do
> "$logfile"
done
2.2 清理特定大容器的日志
# 针对占用 181G 的容器
> /var/lib/docker/containers/5ae1c9345a6e6da0ece25698f6214a90b874417ba61b2e61f2af0413a844bb02/5ae1c9345a6e6da0ece25698f6214a90b874417ba61b2e61f2af0413a844bb02-json.log
# 针对占用 15G 的容器
> /var/lib/docker/containers/e433a85edaaea86855c6518397c388f88493714ee073f370d270e4e3b118f7f0/e433a85edaaea86855c6518397c388f88493714ee073f370d270e4e3b118f7f0-json.log
2.3 清理已停止的容器
# 查看已停止的容器
docker ps -a -f status=exited
# 删除所有已停止的容器
docker rm $(docker ps -a -q -f status=exited)
2.4 清理未使用的 Docker 数据
# 清理未使用的容器、网络、镜像和构建缓存
docker system prune -a -f
# 仅清理未使用的容器和网络(保留镜像)
docker system prune -f
预防措施:配置日志轮转
为了防止未来日志文件再次过大,需要配置 Docker 日志轮转:
1. 编辑 Docker daemon 配置
# 编辑或创建配置文件
vi /etc/docker/daemon.json
2. 添加以下内容
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
配置说明:
max-size: 单个日志文件最大 10MBmax-file: 保留 3 个日志文件(总共最多 30MB)
3. 重启 Docker 服务
systemctl restart docker
4. 验证配置
docker info | grep -i logging
针对运行中容器的日志清理
如果容器正在运行,不能直接删除日志文件,但可以:
方法 A: 临时清空日志(容器继续运行)
# 找到容器的日志文件
CONTAINER_ID="5ae1c9345a6e6da0ece25698f6214a90b874417ba61b2e61f2af0413a844bb02"
LOG_FILE="/var/lib/docker/containers/${CONTAINER_ID}/${CONTAINER_ID}-json.log"
# 清空日志(保留文件)
> "$LOG_FILE"
方法 B: 重启容器并配置日志限制
# 停止容器
docker stop <container_name_or_id>
# 启动时指定日志选项
docker run --log-opt max-size=10m --log-opt max-file=3 <other_options> <image>
检查清理效果
# 查看清理后的磁盘使用情况
du -sh /var/lib/docker/containers/* | sort -hr
# 查看整体 Docker 数据使用情况
docker system df
注意事项
-
备份重要日志: 清理前如果日志中有重要信息,先备份
cp /var/lib/docker/containers/<container_id>/*-json.log /backup/ -
容器状态: 清理日志不会影响正在运行的容器,但会丢失历史日志
-
定期清理: 建议设置定时任务定期清理
# 添加到 crontab(每周日凌晨 2 点清理) 0 2 * * 0 find /var/lib/docker/containers/ -name "*-json.log" -size +100M -exec truncate -s 0 {} \; -
监控磁盘: 设置磁盘使用率告警,及时发现问题
紧急情况快速处理
如果磁盘空间严重不足,立即执行:
# 1. 清空所有容器日志(最快)
find /var/lib/docker/containers/ -name "*-json.log" -exec truncate -s 0 {} \;
# 2. 清理未使用的 Docker 数据
docker system prune -a -f
# 3. 检查效果
df -h /var/lib/docker
常见问题
Q: 清理日志会影响正在运行的容器吗?
A: 不会。清空日志文件只是删除文件内容,不会影响容器运行。truncate -s 0 只清空内容,不删除文件
Q: 如何找到占用空间最大的容器?
A: 使用 du -sh /var/lib/docker/containers/* | sort -hr | head -10
Q: 日志轮转配置后需要重启容器吗?
A: 需要重启 Docker 服务,但现有容器需要重新创建才能应用新配置。
Q: 可以删除整个容器目录吗?
A: 不建议。应该使用 docker rm 命令删除容器,让 Docker 自动清理相关文件。
更多推荐

所有评论(0)