Btrfs 优化与 Docker 存储迁移

在 Linux 系统中,Docker 默认将所有数据存储在 /var/lib/docker。如果你使用 Btrfs 文件系统,随着容器运行时间的增加,写时复制(CoW)机制会导致严重的磁盘碎片化,从而拖慢系统。

本章节将带你通过创建独立子卷禁用 CoW 的方式,实现 Docker 存储的完美优化。


1. 核心目标:为什么要禁用 CoW?

ℹ️ 性能瓶颈

Btrfs 的写时复制(CoW)虽然安全,但对于频繁随机写入的文件(如数据库、日志、容器镜像层)来说是灾难。它会导致文件物理分布极度不连续(碎片化)。

通过对 Docker 目录设置 NOCOW (+C) 属性,我们可以让 Docker 像在原生 ext4 上一样流畅运行,同时享受 Btrfs 的子卷管理便利。


2. 第一阶段:创建子卷与属性配置

我们假设你的 Btrfs 硬盘挂载在 /backup 目录下。

步骤 1 创建专用子卷

/backup 下创建一个专门用于存放 Docker 数据的子卷,方便独立管理和统计空间:

sudo btrfs subvolume create /backup/docker-data
步骤 2 禁用写时复制 (NOCOW)

至关重要:必须在目录为空时设置 +C 属性。

sudo chattr +C /backup/docker-data
步骤 3 验证属性生效

检查输出中是否包含 C 字母:

lsattr -d /backup/docker-data
# 预期结果: ---------------C-- /backup/docker-data

3. 第二阶段:配置 Docker 引擎

我们需要引导 Docker 使用这个性能更高的新路径。

3.1 停止 Docker 服务

sudo systemctl stop docker.socket
sudo systemctl stop docker

3.2 更改存储根目录

编辑(或创建)/etc/docker/daemon.json 文件,仅需指定 data-root

查看 /etc/docker/daemon.json 配置
{
  "data-root": "/backup/docker-data"
}

4. 第三阶段:数据迁移与启动

如果你希望保留现有的容器和镜像:

# 使用 rsync 保持权限与元数据同步
sudo rsync -aqxP /var/lib/docker/ /backup/docker-data/

如果你不需要旧数据,直接清理旧目录即可:

sudo rm -rf /var/lib/docker/*

重启 Docker

sudo systemctl start docker

5. 验证与排障

运行以下命令确认 Docker 已成功切换路径:

docker info | grep "Docker Root Dir"

预期输出Docker Root Dir: /backup/docker-data


6. 结业练习

任务 1 子卷确认

运行 sudo btrfs subvolume list /backup,确认子卷已在列表中。

练习 2 性能对比

在迁移后的路径下启动一个数据库容器,观察 IO 等待时间是否明显降低。

练习 3 空间监控

由于使用了独立子卷,你可以通过 sudo btrfs subvolume show /backup/docker-data 精确查看 Docker 占用的物理空间。

💡 Tip

设置 NOCOW 后,虽然该目录失去了 Btrfs 的增量快照和校验和保护,但换来了极高的 IO 稳定性和极低的碎片率。这对于生产环境中的 Docker 宿主机来说是标准的优化手段。

Navigation