在Studio中使用btrfs文件系统¶
备注
请注意,本文是最初我构想通过btrfs的文件系统,通过划分btrfs子卷结合启用文件系统压缩来实现KVM和docker的镜像存储。一方面btrfs的卷管理可以隔离各个应用,另一方面btrfs的高级特性具有类似ZFS的共享卷实际存储空间同时具备透明压缩功能,特别适合大量的数据存储。
Docker官方文档 Use the BTRFS storage driver 提供的解决方案是将完整磁盘设备划归Docker管理,不能和KVM共享使用。这和我最初规划以及实践有所不同,但是我的解决方案依然是通用的方法,适合多种应用共享磁盘,只不过需要更多的人工介入,和docker完全独占磁盘设备有所差异。
本文记录了我最初的操作实践,对于需要在相同磁盘设备上支持不同应用运行有参考价值。
在 Studio环境的Btrfs存储 中,我们划分了独立的磁盘设备 /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
备注
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
备注
参考 Btrfs Zstd Compression Benchmarks On Linux 4.14 采用 Zstd
压缩方式挂载btrfs,可以获得性能和压缩率的较好平衡。
libvirt和docker数据迁移到btrfs(可选)¶
备注
根据Docker官方文档,在使用btrfs卷的时候,有自己独特的卷管理方式,是可以直接操作btrfs子卷的。我最初是采用本段落的手工迁移卷方法,但是从官方文档来看,似乎用官方方法直接让docker来管理后端卷比较好。所以本段落仅供参考,后续将修改成采用官方btrfs方法来管理docker卷。
另外,我准备部署 Stuido环境Docker容器运行Ceph ,并且将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
备注
如果已经安装了libvirt软件包,在将btrfs子卷挂载前需要先停止libvirtd服务,并且需要要做数据迁移
备注
详细可以参考 使用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
备注
在做数据迁移之前,务必确保没有任何进程在访问 /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/
备注
按照上述操作步骤,完整的 /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的最大特点:存储容量是一个完整的”池”被各个存储卷共享,所以不需要担心某些卷预分配过多或锅烧。
备注
可以重启一次操作系统验证是否都工作正常。
其他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/