从 200G 到 20G:我的 Docker 清理实战经验

从 200G 到 20G:我的 Docker 清理实战经验

你有没有经历过这种事——服务器磁盘突然报警,一查原因:Docker 把磁盘吃了几十个 G,服务全挂。这就是 Docker 的隐藏黑洞:日志无限写 + overlay2 堆积,等到发现时已经晚了。

这篇文章说清楚两件事:怎么提前防住,以及真的爆了怎么救。


一、日志:那个一直在写的文件

Docker 默认用 json-file 日志驱动,没有轮转、没有限制、一直写到底。

日志位置:/var/lib/docker/containers/<container-id>/<container-id>-json.log

# 查看所有容器日志大小
find /var/lib/docker/containers -name "*-json.log" -exec ls -lh {} \; 2>/dev/null

我见过最夸张的案例:一个测试容器跑了三个月,日志文件 47GB。

方案 1:跑容器时就设好轮转(推荐)

docker run -d \
  --name myapp \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  myapp:latest
  • max-size=10m:单个日志文件最大 10MB
  • max-file=3:最多保留 3 个轮转文件

即容器总日志控制在 30MB 内。

方案 2:改全局配置(所有容器生效)

编辑 /etc/docker/daemon.json

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

如果想把 Docker 数据目录迁移到挂载盘(更大数据盘):

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  },
  "data-root": "/data/docker"
}

针对经常 docker build 的服务器,可以限制 BuildKit 缓存:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  },
  "data-root": "/data/docker",
  "builder": {
    "gc": {
      "defaultKeepStorage": "10GB",
      "enabled": true
    }
  }
}

改完记得重启:systemctl restart docker

方案 3:正在运行的容器

快速清理(生产环境慎用):

echo "" > $(docker inspect --format='{{.LogPath}}' <container-id>)

规范做法:stop → rm → 重新 run 带轮转参数。

方案 4:紧急清理(磁盘告急时)

find /var/lib/docker/containers -name "*-json.log" -exec truncate -s 0 {} \;

场景推荐配置

| 场景 | 推荐参数 | |------|---------| | 开发环境 | max-size=5m max-file=3 | | 测试环境 | max-size=10m max-file=5 | | 生产环境 | max-size=50m max-file=10 |

注意:配置只对之后新建的容器生效。老容器要么清理日志,要么重建。

二、overlay2 存储:镜像、容器、卷

/var/lib/docker/overlay2 是 Docker 存储镜像和容器数据的默认目录,占用过大的常见原因:

  1. 镜像残留 — 删除容器后镜像还在
  2. 停止的容器 — Exited 状态的容器仍占空间
  3. 日志堆积 — 数据库等容器日志大
  4. Volumes 未清理 — 容器删了,卷还在
  5. Build 缓存 — 构建产生的中间层

先诊断

docker system df

这个命令告诉你镜像、容器、卷、缓存各占多少。

清理步骤

Step 1:删停止的容器

docker container prune -f

Step 2:删无用镜像

docker image prune -a   # -a 删所有未被容器引用的镜像

Step 3:删无用卷

docker volume prune

Step 4:所有无用资源(推荐定期跑)

docker system prune -a --volumes
⚠️ -a --volumes 会删除所有未运行的容器、未使用的镜像、卷和网络,跑之前确认没有需要保留的数据。

极端情况:重置 Docker

# 停服务 + 删数据 + 重启(会删除所有容器、镜像、卷)
sudo systemctl stop docker
sudo rm -rf /var/lib/docker/*
sudo systemctl start docker

三、防再次膨胀

  1. 定期清理docker system prune -f(加 -f 自动执行,不用敲确认)
  2. 限制日志大小:在 docker-compose.yml 或 docker run 中配置 max-size + max-file
  3. 用 docker volume 管理数据,避免容器直接写 overlay2

加监控告警

watch "df -h / && du -sh /var/lib/docker/*"

总结

Docker 磁盘爆炸就两个主因:日志无限写 + overlay2 堆积

预防靠两点:新建容器配日志轮转 + daemon.json 设全局默认。急救先 docker system df 看谁在吃空间,再对症清理。根治靠定期 docker system prune + 加监控告警。

不要等到磁盘红了才来处理,日常巡检才是正解。

阅读更多

InfluxDB 性能优化:从配置到客户端,我趟过的坑

InfluxDB 性能优化:从配置到客户端,我趟过的坑

前几年搭建了一套轻量级的ELK服务,中间用到了influxdb作为底层存储服务,在遇到InfluxDB写入量大的时候,各种奇怪的性能问题就冒出来了。这篇总结一下我这几年调优 InfluxDB 1.8 的经验,覆盖配置、Telegraf、客户端和运维四个层面,有不少坑是看了日志才找到根因的。 环境说明:本文基于 InfluxDB 1.8,单机部署,数据写入量约 50 万点/秒,CentOS 7 + SSD 硬盘。不同版本或部署方式下,部分参数行为可能略有差异。 一、InfluxDB 配置优化 官方配置文档:https://docs.influxdata.com/influxdb/v1/administration/config/ 1. 打开请求日志,方便排查问题 [http] access-log-path = "/var/log/influxdb/

By chenjg
降本增效-自建轻量级网关trafik总结

降本增效-自建轻量级网关trafik总结

前段时间发现自己搭建的阿里云网站的每月费用有个上升趋势,后来仔细排查了一下账单数据,发现是SLB这块费用见涨,原来是SLB这边已经改了计费规则。按目前的账单来看,算了下一年下来要支付差不多小1千块钱啊,也是一笔不小的支出。决定果断放弃阿里云的负载均衡方案,通过购买一台1H1G服务器,自建网关服务器;         自建网关方案,相比来说 要省钱很多,风险主要是把网关的公网IP暴露出来,会引起一些不必要的麻烦和攻击;但目前主要搭建了一套个人自用的服务,被攻击概率不大,而且即使被攻击的话,必要的时候可以通过切换服务器方式来避免; 同时针对 对外开放的服务域名,可通过cloudflare 代理的方式,隐藏掉网关真实IP地址(目前cloudflare 在国内没有节点,所以相对来说访问速度会慢些,做一下必要的取舍吧);         调研了一些主流网关服务, nginx、haproxy 、traefik产品。          其实应该首选nginx及相关产品应用,nginx本身只支持七层代理,但可以通过插件化安装,实现 四层管理。毕竟nginx用的太多,生态确实可以

By chenjg
SQL Server 2008 迁移至 2022 容器化部署技术总结

SQL Server 2008 迁移至 2022 容器化部署 技术总结

一、 迁移背景与架构    最近在一套测试验证环境的时候,因为原有测试环境使用的还是阿里云2008版sqlserver数据库,查阅了一下资料,打算迁移到2022版Liunx环境的Docker容器中,这中间遇到了一些问题,打算记录并总结下,以避免以后犯重复的问题。 二、 完整迁移实战命令与全流程清单 步骤 1:宿主机在大空间目录规划与赋权 因为sqlserver数据库有40多G,原有的系统的默认挂接盘空间不足,需要在新加的挂接盘 /data 分区下建立挂载目录,并赋予最高读写权限,防止容器内外出现用户权限冲突: # 创建新的数据目录与备份存放目录 mkdir -p /data/mssql/main/data mkdir -p /data/mssql/backup # 赋予最高级别读写与执行权限(非常关键,防止 Error 31 及权限被拒) chmod -R 777 /data/mssql 步骤 2:安全迁移备份文件 使用 rsync 工具将从阿里云下载并解压出来的

By chenjg
敬请同名微信公众号