X86移动云ZFS¶
在我使用的 Apple ARM架构芯片M1 Pro MacBook Pro,我期望构建完全虚拟化的多服务器集群架构。对于底层存储,希望在一个 卷管理 上构建出存储给虚拟机使用。
有两种候选文件系统:
经过实践探索( 使用zfs-dkms在arch linux(ARM)编译安装ZFS ), Asahi Linux 内核激进采用v6.1,尚未得到 OpenZFS
支持,所以
在 Apple ARM架构芯片M1 Pro MacBook Pro 采用 Btrfs
在 X86_64 的 Macbook Pro 2013 采用 ZFS
存储构想¶
我考虑采用 ZFS 来构建物理主机的文件系统原因:
放弃 通过ZFS卷作为虚拟机的磁盘 ( Libvirt虚拟机管理器 已经支持ZFS卷 )
放弃 (由于X86 MacBook Pro 15" Late 2013 笔记本性能有限改为直接运行 kind(本地docker模拟k8s集群) 所以X86移动云不部署Ceph )采用3个虚拟机构建 Ceph Atlas (边缘云计算架构Linaro已经完全基于 OpenStack Atlas 和 Ceph Atlas )
放弃 (实践发现笔记本难以支持大量虚拟机和 KVM嵌套虚拟化 所以X86 MacBook Pro 15" Late 2013 笔记本放弃虚拟化,改为在 私有云架构 二手服务器构建 )在 Ceph Atlas 基础上构建 OpenStack Atlas 和 Kubernetes Atlas
在 ZFS 基础上采用 docker_zfs_driver 运行容器
构建 kind(本地docker模拟k8s集群) 来作为开发环境
准备工作¶
磁盘分区¶
按照 ZFS管理准备 完成文件系统分区:
空闲空间是
64.0GB~1024GB
,规划如下:创建分区3,完整分配
64.0GB~1024GB
,这个分区构建zpool-data
但是挂载到/var/lib/docker
,因为 Docker ZFS 存储驱动 是采用完整的 zfs pool来构建的在
zpool-data
存储池下构建存储docs
卷,用于存储个人数据在
zpool-data
存储池构建用于 kind(本地docker模拟k8s集群) 需要的 在Kubernetes中部署NFS / 在Kubernetes中部署iSCSI / 在Kubernetes中部署hostPath存储 等,来模拟 Kubernetes持久化存储卷
分区:
parted -a optimal /dev/nvme0n1 mkpart primary 64GB 1024GB
parted /dev/nvme0n1 name 3 zpool-data
完成后检查 parted /dev/nvme0n1 print
可以看到新增加的第3个分区:
Model: SAMSUNG MZVL21T0HCLR-00B00 (nvme)
Disk /dev/nvme0n1: 1024GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 256MB 255MB fat32 ESP boot, esp
2 256MB 64.0GB 63.7GB xfs primary
3 64.0GB 1024GB 960GB primary
Docker准备¶
X86移动云Docker环境 ,完成Docker初始安装
停止Docker:
sudo systemctl stop docker
sudo systemctl stop docker.socket
将
/var/lib/docker
备份并清理该目录下所有内容:
sudo cp -au /var/lib/docker /var/lib/docker.bk
sudo rm -rf /var/lib/docker
安装ZFS¶
受限于ZFS的CDDL license,需要额外的工作来完成 ZFS安装 。之前在 ARM移动云计算构建 中我采用 使用zfs-dkms在arch linux(ARM)编译安装ZFS ;而现在在 X86移动云计算构建 系统中,由于 archzfs repo 提供 x86_64
安装包,所以参考 OpenZFS Getting Started: Arch Linux 使用软件仓库安装。
使用 archzfs repo 安装
导入 archzfs 仓库key:
curl -L https://archzfs.com/archzfs.gpg | pacman-key -a -
pacman-key --lsign-key $(curl -L https://git.io/JsfVS)
curl -L https://git.io/Jsfw2 > /etc/pacman.d/mirrorlist-archzfs
添加 archzfs 软件仓库,并更新 Pacman 仓库:
tee -a /etc/pacman.conf <<- 'EOF'
#[archzfs-testing]
#Include = /etc/pacman.d/mirrorlist-archzfs
[archzfs]
Include = /etc/pacman.d/mirrorlist-archzfs
EOF
# 更新pacman仓库
pacman -Sy
archzfs 软件仓库提供了多种安装包组合,执行安装:
# pacman -S zfs
:: There are 16 providers available for zfs:
:: Repository archzfs
1) zfs-archiso-linux 2) zfs-dkms 3) zfs-dkms-git 4) zfs-dkms-rc 5) zfs-linux 6) zfs-linux-git 7) zfs-linux-hardened 8) zfs-linux-hardened-git
9) zfs-linux-lts 10) zfs-linux-lts-git 11) zfs-linux-lts-rc 12) zfs-linux-rc 13) zfs-linux-vfio 14) zfs-linux-vfio-git 15) zfs-linux-zen
16) zfs-linux-zen-git
Enter a number (default=1): 5
resolving dependencies...
looking for conflicting packages...
Packages (2) zfs-utils-2.1.7-1 zfs-linux-2.1.7_6.1.6.arch1.1-1
Total Download Size: 30.47 MiB
Total Installed Size: 41.92 MiB
:: Proceed with installation? [Y/n]
我选择 5 ( zfs-linux
)安装
配置ZFS¶
在分区
/dev/nvme0n1p
构建zpool
( 名为zpool-data
)并挂载到/var/lib/docker/
目录(开启 ZFS压缩 ):
# 在NVMe 分区3创建zpool,命名为zpool-data
sudo zpool create -f zpool-data -m /var/lib/docker /dev/nvme0n1p3
# 存储池开启压缩,2015年后openzfs默认压缩算法LZ4,这里明确设置lz4
sudo zfs set compression=lz4 zpool-data
此时检查zfs存储可以看到上述名为
zpool-data
的存储池:
sudo zfs list
输出显示如下:
NAME USED AVAIL REFER MOUNTPOINT
zpool-data 140K 860G 24K /var/lib/docker
此时zfs卷已经挂载,使用 df -h
可以看到:
Filesystem Size Used Avail Use% Mounted on
...
zpool-data 861G 128K 861G 1% /var/lib/docker
修改
/etc/docker/daemon.json
添加zfs配置项(如果该配置文件不存在则创建并添加如下内容):
{
"storage-driver": "zfs"
}
启动Docker并检查Docker配置:
sudo systemctl start docker
sudo docker info
docker info
输出显示如下:
Client:
Context: default
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 20.10.22
Storage Driver: zfs
Zpool: zpool-data
Zpool Health: ONLINE
Parent Dataset: zpool-data
Space Used By Parent: 163328
Space Available: 923954676224
Parent Quota: no
Compression: lz4
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
Default Runtime: runc
Init Binary: docker-init
containerd version: 9ba4b250366a5ddde94bb7c9d1def331423aa323.m
runc version:
init version: de40ad0
Security Options:
seccomp
Profile: default
cgroupns
Kernel Version: 6.1.6-arch1-1
Operating System: Arch Linux
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.54GiB
Name: xcloud
ID: IUMZ:2YIT:GWWW:7W73:OKSF:Q6OD:JXWN:NWZ5:IFBG:OKGY:YEIV:RL7V
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
配置ZFS自动启动¶
对于 Docker ZFS 存储驱动 需要通过 配置ZFS自动启动 确保操作系统启动时自动import zpool。并且由于 /var/lib/docker
是 /var
子目录,还必须采用 zfs-import-cache
+ zfs-mount-generator
:
针对
zpool-data
zpool存储池,采用zfs-mount-generator
自动启动ZFS:
ZPOOL=zpool-data
mkdir /etc/zfs/zfs-list.cache
systemctl enable zfs-import-cache
systemctl disable zfs-mount
systemctl enable zfs.target
systemctl enable zfs-zed.service
systemctl start zfs-zed.service
touch /etc/zfs/zfs-list.cache/${ZPOOL}
# 触发 /etc/zfs/zfs-list.cache/${ZPOOL} 更新
zfs set canmount=off zpool/${ZPOOL}
zfs set canmount=on zpool/${ZPOOL}
/home迁移到ZFS¶
采用 ZFS快速起步 构建存储目录并将/home迁移到ZFS
以
root
身份登陆,并确保/home
目录没有用户访问,将/home
目录重命名:
mv /home /home.bak
由于
zpool-data
存储池已构建,所以直接创建卷home
,并且创建home
卷下面的子(用户目录):
#zfs create zpool-data/home
#zfs set mountpoint=/home zpool-data/home
# 采用一条命令创建挂载好目录的ZFS卷
zfs create -o mountpoint=/home zpool-data/home
# 为每个用户创建独立的子卷,对于ZFS来说会自动形成层次结构的目录挂载
zfs create zpool-data/home/huatai
恢复
/home/huatai
目录数据:
chown huatai:staff /home/huatai
chmod 700 /home/huatai
su - huatai
(cd /home.bak/huatai && tar cf - .)|(cd /home/huatai && tar xf -)