.. _using_btrfs_in_studio: ============================== 在Studio中使用btrfs文件系统 ============================== .. note:: 请注意,本文是最初我构想通过btrfs的文件系统,通过划分btrfs子卷结合启用文件系统压缩来实现KVM和docker的镜像存储。一方面btrfs的卷管理可以隔离各个应用,另一方面btrfs的高级特性具有类似ZFS的共享卷实际存储空间同时具备透明压缩功能,特别适合大量的数据存储。 Docker官方文档 `Use the BTRFS storage driver `_ 提供的解决方案是将完整磁盘设备划归Docker管理,不能和KVM共享使用。这和我最初规划以及实践有所不同,但是我的解决方案依然是通用的方法,适合多种应用共享磁盘,只不过需要更多的人工介入,和docker完全独占磁盘设备有所差异。 本文记录了我最初的操作实践,对于需要在相同磁盘设备上支持不同应用运行有参考价值。 在 :ref:`btrfs_in_studio` 中,我们划分了独立的磁盘设备 ``/dev/sda3`` 用于Btrfs,以下是构建KVM和docker以及用户目录共享btrfs文件系统存储的方案。 Btrfs工具 ============= 安装Btrfs工具 ``btrfs-progs`` (在RHEL/CentOS中名为 ``btrfs-tools`` 软件包):: apt install btrfs-progs 加载btrfs模块:: modprobe btrfs 磁盘分区 ============= 使用 ``parted`` 创建 ``/dev/sda3`` 来构建btrfs:: parted -a optimal .. note:: ``parted`` 提供了4k对齐优化(参考 `Create partition aligned using parted `_ ),使用参数 ``--align`` 或 ``-a`` 指定优化,一般可以使用 ``optimal`` 由parted自动处理对齐功能。 显示磁盘分区:: (parted) print Model: ATA INTEL SSDSC2KW51 (scsi) Disk /dev/sda: 512GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 512MB 511MB fat16 boot, esp 2 512MB 51.7GB 51.2GB ext4 增加分区3:: mkpart primary btrfs 51.7GB 351.7GB 对新增分区命名:: name 3 docker 增加分区4:: mkpart primary btrfs 351.7GB 100% name 4 data 磁盘分区完成后,检查结果:: (parted) print Model: ATA INTEL SSDSC2KW51 (scsi) Disk /dev/sda: 512GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 512MB 511MB fat16 boot, esp 2 512MB 51.7GB 51.2GB ext4 3 51.7GB 352GB 300GB btrfs docker 4 352GB 512GB 160GB btrfs data Btrfs部署 ================ - 采用的btrfs非常简单的卷,单盘。首先创建根卷 ``docker`` 和 ``data`` :: mkfs.btrfs -L docker /dev/sda3 mkfs.btrfs -L data /dev/sda4 - 挂载btrfs的分区 设置 ``/etc/fstab`` :: /dev/sda3 /var/lib/docker btrfs defaults,compress=zstd 0 1 /dev/sda4 /data btrfs defaults,compress=zstd 0 1 然后挂载磁盘分区:: mkdir /var/lib/docker mount /var/lib/docker mkdir /data mount /data .. note:: 参考 `Btrfs Zstd Compression Benchmarks On Linux 4.14 `_ 采用 ``Zstd`` 压缩方式挂载btrfs,可以获得性能和压缩率的较好平衡。 libvirt和docker数据迁移到btrfs(可选) ======================================= .. note:: 根据Docker官方文档,在使用btrfs卷的时候,有自己独特的卷管理方式,是可以直接操作btrfs子卷的。我最初是采用本段落的手工迁移卷方法,但是从官方文档来看,似乎用官方方法直接让docker来管理后端卷比较好。所以本段落仅供参考,后续将修改成采用官方btrfs方法来管理docker卷。 另外,我准备部署 :ref:`ceph_docker_in_studio` ,并且将Ceph存储输出给libvirt使用,作为底层存储,这样就不再使用本段落的btrfs子卷对应libvirt存储,本段落仅供参考。 - 创建btrfs的子卷,分别对应libvirt和home 创建子卷:: btrfs subvolume create /data/libvirt btrfs subvolume create /data/home 检查子卷:: btrfs subvolume list /data 显示输出:: ID 257 gen 7 top level 5 path libvirt ID 258 gen 8 top level 5 path home .. note:: 如果已经安装了libvirt软件包,在将btrfs子卷挂载前需要先停止libvirtd服务,并且需要要做数据迁移 .. note:: 详细可以参考 `使用Btrfs部署KVM `_ - 停止libvirt服务:: systemctl stop libvirtd systemctl stop libvirtd-admin.socket systemctl stop libvirtd-ro.socket systemctl stop libvirtd.socket systemctl stop virtlogd.socket systemctl stop virtlogd-admin.socket systemctl stop virtlockd-admin.socket systemctl stop virtlockd.socket # 停止libvirt使用的dnsmasq ps aux | grep dnsmasq | grep -v grep | awk '{print $2}' | sudo xargs kill .. note:: 在做数据迁移之前,务必确保没有任何进程在访问 ``/var/lib/libvirt`` 目录,以便能够移动和重新挂载这两个目录:: lsof | grep libvirt - 将源目录重命名:: cd /var/lib mv libvirt libvirt.bak 注意检查目录的属主和权限:: drwxr-xr-x 7 root root 4.0K 2月 26 17:38 libvirt.bak - 将btrfs子卷挂载到目标目录 创建目录:: mkdir /var/lib/libvirt chmod 755 /var/lib/libvirt 修改 ``/etc/fstab`` 添加:: /dev/sda4 /var/lib/libvirt btrfs subvol=libvirt,defaults,noatime,compress=zstd 0 1 挂载目录:: mount /var/lib/libvirt - 数据迁移:: rsync -a /var/lib/libvirt.bak/ /var/lib/libvirt/ - 恢复服务:: systemctl start libvirtd Home目录迁移 ============== Home目录迁移比较麻烦一些,首先要退出所有使用 ``/home`` 目录的普通用户帐号,然后切换到root用户才可以进行目录挂载和数据迁移。 - 在 ``/etc/fstab`` 中添加:: /dev/sda4 /home btrfs subvol=home,defaults,noatime,compress=zstd 0 1 - 退出所有普通用户帐号,切换到root用户执行以下命令:: mv /home /home.bak mkdir /home mount /home rsync -a /home.bak/ /home/ .. note:: 按照上述操作步骤,完整的 ``/etc/fstab`` 内容如下:: /dev/sda3 /data btrfs defaults,compress=zstd 0 1 /dev/sda3 /var/lib/libvirt btrfs subvol=libvirt,defaults,noatime 0 1 /dev/sda3 /var/lib/docker btrfs subvol=docker,defaults,noatime 0 1 最后挂载的 btrfs 文件系统内容如下:: /dev/sda3 186G 17M 185G 1% /data /dev/sda3 186G 17M 185G 1% /var/lib/libvirt /dev/sda3 186G 17M 185G 1% /var/lib/docker 可以看到btrfs的最大特点:存储容量是一个完整的"池"被各个存储卷共享,所以不需要担心某些卷预分配过多或锅烧。 .. note:: 可以重启一次操作系统验证是否都工作正常。 其他btrfs卷(可选) =================== 由于常用的用户目录会存储较多的文件,也可以考虑迁移到btrfs中。这里把 ``/home`` 目录迁移 - 创建btrfs子卷home:: btrfs subvolume create /data/home 检查创建的子卷:: btrfs subvolume list /data - 将 ``/home`` 目录重命名成 ``/home.bak`` :: mv /home /home.bak - 修改 ``/etc/fstab`` 添加:: /dev/sda3 /home btrfs subvol=home,defaults,noatime 0 1 - 创建并挂载 ``/home`` 目录:: mkdir /home mount /home - 同步和恢复 ``/home`` 目录内容:: rsync -a /home.bak/ /home/ 参考 ========== - `ArchLinux Parted `_ - `ArchLinux Btrfs `_ - `Create partition aligned using parted `_