Docker 数据目录迁移到新分区 (解决根目录空间不足)

概述

/ 根目录空间不足,而 Docker 占用大量空间时,将 Docker 的数据目录 (/var/lib/docker) 迁移到另一个有足够空间的分区(例如 /www)是一个有效的解决方案。本指南将详细说明如何安全地执行此操作。

⚠️ 极度重要警告 ⚠️

  • 完整备份!完整备份!完整备份! 在执行任何操作之前,请务必对 /var/lib/docker 目录和 /etc/docker 目录进行完整备份。
  • 操作风险: 尽管使用 cp 命令比 mv 更安全,但任何对系统关键服务的操作都存在风险。请务必仔细阅读并遵循每一步。
  • 电源稳定: 确保服务器在操作过程中不会断电。

步骤一:预迁移清理 Docker 未使用资源

在迁移数据之前,清理掉不必要的 Docker 容器、网络、镜像和卷可以大大减少需要移动的数据量,从而加快迁移速度并降低潜在风险。

  1. 清理所有停止的容器、未使用的网络、悬空镜像和构建缓存:

    sudo docker system prune
    • 此命令会提示您确认。它会删除停止的容器、未使用的网络、悬空镜像和构建缓存。
    • 注意: 如果您想删除所有未被任何容器使用的镜像(不仅仅是悬空镜像),可以使用 sudo docker system prune -a。但请谨慎使用,因为它会删除所有未使用的镜像,包括那些您可能想保留但目前没有运行的镜像。
  2. 清理未使用的卷 (Volumes):

    sudo docker volume prune
    • 此命令会提示您确认。它会删除所有未被任何容器使用的本地卷。
    • 请务必确认您不需要这些卷中的数据,因为卷可能包含重要数据。
  3. (可选)清理未使用的构建缓存:

    sudo docker builder prune
    • 如果您经常构建 Docker 镜像,可能会积累大量的构建缓存。docker system prune 已经包含了这个,但如果您只想清理构建缓存,可以使用此命令。

清理完成后,运行 df -h 检查 / 根目录的空间使用情况,确认已释放足够空间。


步骤二:Docker 数据目录迁移

此阶段将 Docker 数据从 /var/lib/docker 复制到 /www/docker-data 并配置 Docker 使用新路径。

  1. 【重要】备份 Docker 配置和数据 (再次强调):

    sudo tar -czvf /root/docker_backup_$(date +%Y%m%d).tar.gz /var/lib/docker /etc/docker
  2. 停止 Docker 服务:

    • 这是最关键的第一步,确保 Docker 不在运行时进行数据移动。
    sudo systemctl stop docker
    • 确认服务已停止:
    sudo systemctl status docker

    (应显示 inactive (dead)

  3. 创建新的 Docker 数据目录:

    • /www 分区上创建一个新的目录来存放 Docker 数据。
    sudo mkdir -p /www/docker-data
  4. 复制现有 Docker 数据到新位置:

    • 使用 cp -av 命令。-a (archive) 选项会保留文件权限、所有者、时间戳等属性,并递归复制目录。-v (verbose) 选项会显示复制的进度。
    sudo cp -av /var/lib/docker/. /www/docker-data/
    • 注意: /var/lib/docker/. 中的 . 表示复制 /var/lib/docker 目录下的所有内容,而不是复制 /var/lib/docker 这个目录本身。
  5. 验证数据是否成功复制:

    • 比较两个目录的大小和内容,确保复制完整。
    sudo du -sh /var/lib/docker
    sudo du -sh /www/docker-data
    • 这两个命令的输出大小应该非常接近。
  6. 配置 Docker 使用新目录:

    • 编辑或创建 Docker 配置文件 /etc/docker/daemon.json
    sudo nano /etc/docker/daemon.json
    • 在文件中添加或修改 data-root 字段,并确保 JSON 格式正确。如果文件已存在其他配置(例如 registry-mirrors),请将它们合并到一个 JSON 对象中。
    • 正确示例 (合并配置):

      {
        "registry-mirrors": ["https://docker.1ms.run"],
        "data-root": "/www/docker-data"
      }
    • 错误示例 (两个独立的 JSON 对象):

      {
        "registry-mirrors": ["https://docker.1ms.run"]
      }
      {
        "data-root": "/www/docker-data"
      }
    • 保存并关闭文件 (在 nano 中是 Ctrl+X, Y, Enter)。
  7. 启动 Docker 服务:

    sudo systemctl start docker
    • 确认服务已启动:
    sudo systemctl status docker

    (应显示 active (running)


步骤三:验证

  1. 检查 Docker 数据根目录:

    docker info | grep "Data Root"
    • 输出应该显示 Data Root: /www/docker-data
  2. 验证 Docker 功能:

    • 运行一些 Docker 命令,例如 docker psdocker images,确保您的容器和镜像都能正常显示。
    • 尝试启动一个容器,确保其能正常运行。
  3. 检查磁盘空间使用情况:

    df -h
    • 您应该会看到 / (挂载在 /dev/sda2) 的 Use% 显著下降,而 /www (挂载在 /dev/sda3) 的 Use% 会相应上升。

步骤四:删除旧的 Docker 数据 (确认无误后执行)

在确认 Docker 已经完全正常运行,并且所有容器和数据都无误后,您可以安全地删除旧的 /var/lib/docker 目录。

sudo rm -rf /var/lib/docker