Btrfs 优化与 Docker 存储迁移
在 Linux 系统中,Docker 默认将所有数据存储在 /var/lib/docker。如果你使用 Btrfs 文件系统,随着容器运行时间的增加,写时复制(CoW)机制会导致严重的磁盘碎片化,从而拖慢系统。
本章节将带你通过创建独立子卷并禁用 CoW 的方式,实现 Docker 存储的完美优化。
1. 核心目标:为什么要禁用 CoW?
Btrfs 的写时复制(CoW)虽然安全,但对于频繁随机写入的文件(如数据库、日志、容器镜像层)来说是灾难。它会导致文件物理分布极度不连续(碎片化)。
通过对 Docker 目录设置 NOCOW (+C) 属性,我们可以让 Docker 像在原生 ext4 上一样流畅运行,同时享受 Btrfs 的子卷管理便利。
2. 第一阶段:创建子卷与属性配置
我们假设你的 Btrfs 硬盘挂载在 /backup 目录下。
在 /backup 下创建一个专门用于存放 Docker 数据的子卷,方便独立管理和统计空间:
sudo btrfs subvolume create /backup/docker-data至关重要:必须在目录为空时设置 +C 属性。
sudo chattr +C /backup/docker-data检查输出中是否包含 C 字母:
lsattr -d /backup/docker-data
# 预期结果: ---------------C-- /backup/docker-data3. 第二阶段:配置 Docker 引擎
我们需要引导 Docker 使用这个性能更高的新路径。
3.1 停止 Docker 服务
sudo systemctl stop docker.socket
sudo systemctl stop docker3.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 docker5. 验证与排障
运行以下命令确认 Docker 已成功切换路径:
docker info | grep "Docker Root Dir"预期输出:Docker Root Dir: /backup/docker-data
6. 结业练习
运行 sudo btrfs subvolume list /backup,确认子卷已在列表中。
在迁移后的路径下启动一个数据库容器,观察 IO 等待时间是否明显降低。
由于使用了独立子卷,你可以通过 sudo btrfs subvolume show /backup/docker-data 精确查看 Docker 占用的物理空间。
设置 NOCOW 后,虽然该目录失去了 Btrfs 的增量快照和校验和保护,但换来了极高的 IO 稳定性和极低的碎片率。这对于生产环境中的 Docker 宿主机来说是标准的优化手段。