一台测试机跑了半年,根分区只剩 300M,登录就提示磁盘空间不足。df -h 一看,/var/lib/docker 占了 46G,全是镜像层和日志。系统盘才 40G,根本不够用,只能把这个目录挪到挂载的数据盘上。

改之前先看清现在的位置

运行 docker info,输出里有一行 Docker Root Dir,指向当前实际目录。老版本叫 graph,新版本叫 data-root,两者在配置里的字段名不同,写错不生效,重启后照旧。

标准操作流程

systemctl stop docker docker.socket
mkdir -p /data/docker
rsync -aP /var/lib/docker/ /data/docker/

然后用 vi 编辑 /etc/docker/daemon.json,把 data-root 指向新路径,内容是 data-root 加冒号加目录字符串。文件里如果已经有 registry-mirrors 之类的配置,注意保持逗号层级正确,写坏了 docker 起不来。

systemctl daemon-reload
systemctl start docker
docker info

确认 Docker Root Dir 已经变成新目录,再挑一个镜像跑 docker run 验证,最后才删旧目录。顺序反了,镜像全丢,只能重新拉。

几个容易踩的坑

  • rsync 结尾的斜杠。源目录带斜杠复制的是内容,不带则会把 docker 整个目录套进去,路径就多了一层。
  • SELinux 开启的机器要给新目录打标签,用 chcon 或 semanage,否则容器启动报权限拒绝。
  • 只改 daemon.json 不迁移数据,等于让 docker 认为一个空目录就是全部家当,容器和镜像全显示不存在。
  • Docker Desktop 是另一套逻辑,磁盘映像在设置里的 Resources 页面,改不了路径就先备份再迁移。

顺手把日志压一压

光搬家治标不治本,日志不限制还会继续涨。daemon.json 里加 log-driver 和 log-opts,把 max-size 设成 50m,max-file 设成 3,容器重启后单容器日志封顶 150M。已经在跑的容器不会自动生效,得重建。

生产环境更稳妥的做法是开始就把 /var/lib/docker 挂成独立分区或独立云盘,扩容时只动那块盘,不碰系统分区。