ZFS - 动态文件系统

一、ZFS介绍

1、ZFS文件系统

英文名称为ZettabyteFileSystem,也叫动态文件系统(DynamicFileSystem),是第一个128位文件系统。最初是由Sun公司为Solaris10操作系统开发的文件系统。
作为OpenSolaris开源计划的一部分,ZFS于2005年11月发布,被Sun称为是终极文件系统,经历了10年的活跃开发,而最新的开发将全面开放,并重新命名为OpenZFS。

2、ZFS 与 openZFS

甲骨文收购Sun后不久,OpenSolaris成为了密切的来源。 ZFS的所有进一步开发也成为封闭源。 ZFS的许多开发人员对此感到不满。
由于这一决定,三分之二的核心ZFS开发者,包括Ahrens和Bonwick,离开了Oracle。他们与其他公司一起在2013年9月创建了OpenZFS项目。该项目率先开展了ZFS的开源开发。

让我们回到上面提到的许可证问题。由于OpenZFS项目与Oracle是分开的,因此有些人可能想知道为什么他们不会将许可证更改为与GPL兼容的东西,因此它可以包含在Linux内核中。

根据OpenZFS网站的说法,更改许可证将涉及将任何贡献代码的人联系到当前的OpenZFS实施(包括初始的,常见的ZFS代码,直到OpenSolaris)并获得他们更改许可证的许可。

由于这项工作几乎不可能(因为一些贡献者可能已经死亡或很难找到),他们决定保留他们拥有的许可证。

3、特性

ZFS是一种先进的、高度可扩展的文件系统,最初是由Sun公司开发的,现在OpenZFS是项目的一部分。不同于其它文件系统,它不仅是一个文件系统逻辑卷管理器。ZFS使其受欢迎的特性是:

数据完整性:数据一致性和完整性通过即写即拷和校验技术保证。

存储空间池:可用存储驱动器一起放入称为zpool的单个池。

软件RAID :像发出一个命令一样,建立一个raidz数组。

内置的卷管理器:ZFS充当卷管理器。

Snapshots、克隆、压缩:这些都是一些ZFS提供的高级功能。

最大单个文件大小为: 16 EB(1 EB = 1024 PB)

最大 256 千万亿(256*1015 )的 ZB(1 ZB = 1024 EB)的存储

4、专业术语

Pool:存储驱动器的逻辑分组,它是ZFS的基本构建块,从这里将存储空间分配给数据集。

Datasets:ZFS文件系统的组件即文件系统、克隆、快照和卷被称为数据集。

Mirror:一个虚拟设备存储相同的两个或两个以上的磁盘上的数据副本,在一个磁盘失败的情况下,相同的数据是可以用其他磁盘上的镜子。

Resilvering:在恢复设备时将数据从一个磁盘复制到另一个磁盘的过程。

Scrub:擦除用于一致性检验在ZFS像在其他文件系统如何使用fsck。

 

二、Centos7下安装ZFS

1、安装EPEL仓库

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

2、安装内核开发包

先升级kernel:yum update -y kernel

再安装kernel开发包:yum install -y kernel-devel

更新内核后最好重启系统。

3、安装zfs源

yum localinstall --nogpgcheck http://download.zfsonlinux.org/epel/zfs-release.el7_6.noarch.rpm -y

4、安装zfs

yum install -y zfs

 

 5、zfs模块插入到内核

验证zfs模块是否插入到内核:lsmod | grep zfs

zfs模块插入内核命令:modprobe zfs

6、检查是否可以使用zfs命令

zfs list

 

 三、ZFS池

 1、创建四个虚拟磁盘,每个大小1G

dd if=/dev/zero of=disk1.img bs=1G count=1;losetup /dev/loop1 ./disk1.img
dd if=/dev/zero of=disk2.img bs=1G count=1;losetup /dev/loop2 ./disk2.img
dd if=/dev/zero of=disk3.img bs=1G count=1;losetup /dev/loop3 ./disk3.img
dd if=/dev/zero of=disk4.img bs=1G count=1;losetup /dev/loop4 ./disk4.img

 

查看磁盘信息:fdisk -l

 

注意:我这里测试的时候用的是虚拟磁盘,机器重启的时候失效。在生产环境时,需要添加新硬盘来创建zfs池

linux虚拟机添加磁盘:https://www.cnblogs.com/zhangguosheng1121/p/13535982.html

在这里创建好磁盘、分区完成之后,下面的步骤就不用做了,直接用ZFS创建文件系统:zpool create tank /dev/sdb

 

 2、创建ZFS池

zpool create mypool raidz /dev/loop0 /dev/loop1 /dev/loop2 /dev/loop3

查看:zpool list

遗憾的是,默认情况下不会列出快照,但我们可以通过一个属性启用该特性:zpool list snapshot=on mypool

 

查看pool池的状态:zpool status

查看池的属性:zfs get all mypool

NAME    PROPERTY              VALUE                  SOURCE
mypool  type                  filesystem             -
mypool  creation              Tue Jul 28 11:28 2020  -
mypool  used                  105K                   -
mypool  available             83.7M                  -
mypool  referenced            32.9K                  -
mypool  compressratio         1.00x                  -
mypool  mounted               yes                    -
mypool  quota                 none                   default
mypool  reservation           none                   default
mypool  recordsize            128K                   default
mypool  mountpoint            /mypool                default
mypool  sharenfs              off                    default
mypool  checksum              on                     default
mypool  compression           off                    default
mypool  atime                 on                     default
mypool  devices               on                     default
mypool  exec                  on                     default
mypool  setuid                on                     default
mypool  readonly              off                    default
mypool  zoned                 off                    default
mypool  snapdir               hidden                 default
mypool  aclinherit            restricted             default
mypool  createtxg             1                      -
mypool  canmount              on                     default
mypool  xattr                 on                     default
mypool  copies                1                      default
mypool  version               5                      -
mypool  utf8only              off                    -
mypool  normalization         none                   -
mypool  casesensitivity       sensitive              -
mypool  vscan                 off                    default
mypool  nbmand                off                    default
mypool  sharesmb              off                    default
mypool  refquota              none                   default
mypool  refreservation        none                   default
mypool  guid                  13854854478416292289   -
mypool  primarycache          all                    default
mypool  secondarycache        all                    default
mypool  usedbysnapshots       0B                     -
mypool  usedbydataset         32.9K                  -
mypool  usedbychildren        71.8K                  -
mypool  usedbyrefreservation  0B                     -
mypool  logbias               latency                default
mypool  dedup                 off                    default
mypool  mlslabel              none                   default
mypool  sync                  standard               default
mypool  dnodesize             legacy                 default
mypool  refcompressratio      1.00x                  -
mypool  written               32.9K                  -
mypool  logicalused           31.5K                  -
mypool  logicalreferenced     12K                    -
mypool  volmode               default                default
mypool  filesystem_limit      none                   default
mypool  snapshot_limit        none                   default
mypool  filesystem_count      none                   default
mypool  snapshot_count        none                   default
mypool  snapdev               hidden                 default
mypool  acltype               off                    default
mypool  context               none                   default
mypool  fscontext             none                   default
mypool  defcontext            none                   default
mypool  rootcontext           none                   default
mypool  relatime              off                    default
mypool  redundant_metadata    all                    default
mypool  overlay               off                    default
储存池属性

查看池健康状况:zpool status -x

 

 

 

3、为pool池添加新磁盘:

首先创建虚拟磁盘:dd if=/dev/zero of=disk4.img bs=64M count=1;losetup /dev/loop4 ./disk4.img

添加新磁盘:zpool add mypool spare /dev/loop4

添加日志盘:zpool add mypool log /dev/loop5

4、移除pool池中的磁盘: zpool remove命令只能用来删除热备件(spares)、高速缓存设备和日志设备(logs)

zpool remove mypool /dev/loop5

5、销毁池

zpool destroy mypool

 

6、附加和移除储存池中的设备

附加:zpool attach mypool loop5 loop4

移除:zpool detach mypool loop4

7、查看储存池IO统计信息

zpool iostat -v mypool

 

四、文件系统

1、创建文件系统

zfs create mypool/data

2、查看文件系统的属性

zfs get all mypool/data

3、设置属性

文件系统关闭数据校验功能:zfs set checksum=off mypool/data

查看文件系统单一属性:zfs get checksum mypool/data

文件系统开启zfs压缩功能: zfs set compression=on mypool/data

 

4、销毁文件系统

zfs destroy mypool/data

5、挂载文件系统

查看默认的挂载:zfs get mountpoint mypool/data

更改默认挂载点:zfs set mountpoint=/gzpool/data mypool/data

[root@localhost ~]# df
Filesystem              1K-blocks    Used Available Use% Mounted on
/dev/mapper/centos-root  17811456 1828584  15982872  11% /
devtmpfs                  1918800       0   1918800   0% /dev
tmpfs                     1930760       0   1930760   0% /dev/shm
tmpfs                     1930760   11956   1918804   1% /run
tmpfs                     1930760       0   1930760   0% /sys/fs/cgroup
/dev/sda1                 1038336  193792    844544  19% /boot
tmpfs                      386152       0    386152   0% /run/user/0
mypool                      74112       0     74112   0% /mypool
mypool/myzdev1              85632   11520     74112  14% /mypool/myzdev1
[root@localhost ~]# zfs umount -a
[root@localhost ~]# zfs set mountpoint=/testpoint/myzdev1 mypool/myzdev1
[root@localhost ~]# zfs mount -a
[root@localhost ~]# df
Filesystem              1K-blocks    Used Available Use% Mounted on
/dev/mapper/centos-root  17811456 1828584  15982872  11% /
devtmpfs                  1918800       0   1918800   0% /dev
tmpfs                     1930760       0   1930760   0% /dev/shm
tmpfs                     1930760   11956   1918804   1% /run
tmpfs                     1930760       0   1930760   0% /sys/fs/cgroup
/dev/sda1                 1038336  193792    844544  19% /boot
tmpfs                      386152       0    386152   0% /run/user/0
mypool                      74112       0     74112   0% /mypool
mypool/myzdev1              85632   11520     74112  14% /testpoint/myzdev1
[root@localhost ~]# 
实例

mountpoint属性更改时,文件系统将自动从旧挂载点取消挂载,并重新挂载到新挂载点,挂载点目录根据需要进行创建。

如果 ZFS 由于文件系统正处于活动状态而无法将其取消挂载,则会报告错误,并需要强制进行手动取消挂载。

查看当前已挂载的所有文件系统:zfs mount

可以使用 -a 选项挂载 ZFS 管理的所有文件系统:zfs mount -a

6、取消挂载文件系统

通过使用 zfs unmount 子命令可以取消挂载 ZFS 文件系统。unmount 命令可以采用挂载点或文件系统名称作为参数。

按文件系统名称取消挂载一个文件系统:zfs unmount mypool/data

按挂载点取消挂载一个文件系统:zfs unmount /mypool/data

如果文件系统处于繁忙状态,则 unmount 命令将失败。要强行取消挂载文件系统,可以使用 -f 选项。

 

四、ZFS快照

1、创建快照

zfs snapshot mypool/data@2020-07-28

2、查看所有快照

zfs list -t snapshot

3、查看指定文件系统快照

zfs list -t snapshot -r mypool/data

4、回滚快照

zfs rollback mypool/data@2020-07-28

5、删除快照:如果已从快照创建克隆,则必须先销毁克隆,才能销毁快照。

zfs destroy mypool/data@2020-07-28

6、查看2个快照的差异

zfs diff mypool/data@2020-07-28 mypool/data@2020-07-27

7、保持快照:保持快照可以防止它被销毁

zfs hold keep mypool/data@2020-07-28

使用zfs holds 命令显示受保持的快照列表:zfs holds mypool/data@2020-07-28

8、释放保持

zfs release -r keep mypool/data@2020-07-28

9、销毁保持的快照:加上-d参数

zfs destroy -d mypool/data@2020-07-28

10、重命名快照

zfs rename mypool/data@2020-07-28 mypool/data@2020-07-27

11、发送 ZFS 快照

同一主机:zfs send mypool/data@2020-07-27 | zfs recv ourpool/data

不同主机:zfs send mypool/data@2020-07-27 | ssh sys2 zfs recv ourpool/data

将快照流发送到不同主机 (sys2) 之前,必须在第二台主机上创建一个名为ourpool的池,目标文件系统(ourpool/data)必须不存在

使用文件系统的快照 (mypool/data@2020-07-27) 生成文件系统mypool/data的备份,将其发送到另一个ourpool中。快照存在于mypool池中也存在ourpool池中。

使用zfs send -i 选项可以发送增量数据:

zfs send -i mypool/data@2020-07-27 mypool/data@2020-07-28 | zfs recv ourpool/data

请注意,第一个参数 (2020-07-27) 是较早的快照,第二个参数 (2020-07-28) 是较晚的快照。这种情况下,ourpool/data文件系统必须已存在,增量接收才能成功。

12、接受ZFS快照

以增量方式发送 mypool/data@2020-07-28,要接收新的增量快照,首先必须回滚接收文件系统。或者,使用 -F 选项可以取消回滚步骤:

zfs send -i mypool/data@2020-07-27 mypool/data@2020-07-28 | zfs recv -F ourpool/data

接收增量快照时,目标文件系统(ourpool/data)必须已存在。

13、远程复制 ZFS 数据

可以使用zfs send和zfs recv命令,将快照流表示从一个系统远程复制到另一个系统:

zfs send mypool/data@2020-07-27 | ssh newsys zfs recv ourpool/data@2020-07-27

此命令发送 mypool/data@2020-07-27快照数据,并在ourpool/data文件系统中予以接收。该命令还会在newsys系统上创建data@2020-07-27快照

 

五、ZFS克隆

1、创建克隆

zfs clone mypool/data@2020-07-27 mypool/@2020-07-27_clone1

创建一个名为mypool/clone1的新克隆,其初始内容与快照 mypool/data@2020-07-27的内容相同

 

2、销毁克隆

zfs destroy mypool/clone1

3、使用 ZFS 克隆替换 ZFS 文件系统

借助 zfs promote 命令可以使用ZFS 文件系统的克隆来替换该文件系统。利用此功能可以克隆并替换文件系统,使源文件系统变为指定文件系统的克隆。

此外,通过此功能还可以销毁最初创建克隆所基于的文件系统。如果没有克隆提升 (clone promotion) 功能,就无法销毁活动克隆的源文件系统。

在以下示例中,对 yourpool/test/A 文件系统进行了克隆,然后克隆文件系统 yourpool/test/B 成为原始 yourpool/test/A 文件系统。

在此 zfs list 输出中,注意源A文件系统的磁盘空间记帐信息已被B文件系统取代。

 

 

六、通过ZFS定义KVM虚拟机

环境

查看kvm虚拟机:virsh list --all

查看虚拟机的文件系统:ll /tank

查看kvm虚拟机的磁盘文件:

 

需求:通过zfs快照拉起一个kvm虚拟机的副本

1、对CentOSkvm虚拟机的磁盘文件CentOS-7.qcow2做个快照

zfs snapshot tank/CentOS-7@test1

2、通过克隆重新生成新的磁盘文件

zfs clone tank/CentOS-7@test1 tank/CentOS-7-test1  # 注意:这里克隆出来的 tank/CentOS-7-test1是一个新的文件系统,名称不能使用@符号

3、 复制CentOS-7.xml文件,修改name、disk_path,删除uuid、mac

复制:cp CentOS-7.xml CentOS-7@test1.xml

修改:

 

    def create_kvm_xml(self, kvm_machine, snapshotname, copyname, copycpu, copymemory):
        """
        读取文件,修改文件,追加到新文件
        kvm_name = 'Test-1                                 老虚拟机
        kvm_name_new = 'kvm_1                              新虚拟机
        kvm_disk_path = '/tank/kvm_1@kvm_1/Test-1.qcow2'   新虚拟机磁盘
        """
        try:
            exe_cmd = r'cat /etc/libvirt/qemu/{0}.xml'.format(kvm_machine)
            snapshot_clone_name = snapshotname.replace('@', '-')
            kvm_disk_path = '/' + snapshot_clone_name + '/' + kvm_machine + '.qcow2'
            result = self.remote_linux(exe_cmd)
            # 解析xml文件找出要修改的name、uuid、disk_path、mac、cpu、memory
            config = etree.XML(result['data'])
            kvm_name = config.xpath("//name")[0]
            kvm_diskpath = config.xpath("//disk/source")[0]
            kvm_uuid = config.xpath("//uuid")[0]
            kvm_interface = config.xpath("//interface")[0]
            kvm_mac = config.xpath("//mac")[0]
            if copycpu != '' and copymemory != '':
                copymemory = int(copymemory) * 1024
                kvm_cpu = config.xpath("//vcpu")[0]
                kvm_cpu.text = copycpu
                kvm_memory = config.xpath("//memory")[0]
                kvm_currentmemory = config.xpath("//currentMemory")[0]
                kvm_memory.text = str(copymemory)
                kvm_currentmemory.text = str(copymemory)
            elif copycpu != '' and copymemory == '':
                kvm_cpu = config.xpath("//vcpu")[0]
                kvm_cpu.text = copycpu
            elif copycpu == '' and copymemory != '':
                copymemory = int(copymemory) * 1024
                kvm_memory = config.xpath("//memory")[0]
                kvm_currentmemory = config.xpath("//currentMemory")[0]
                kvm_memory.text = str(copymemory)
                kvm_currentmemory.text = str(copymemory)
            # 修改名字、修改磁盘路径、删除uuid、删除mac

            kvm_name.text = copyname
            kvm_diskpath.attrib['file'] = kvm_disk_path
            config.remove(kvm_uuid)
            kvm_interface.remove(kvm_mac)
            xml_content = etree.tounicode(config)
            xml_path = '/etc/libvirt/qemu/{0}.xml'.format(copyname)
            exe_cmd = r'cat > {0} << \EOH'.format(xml_path) + '\n' + xml_content + '\nEOH'
            self.remote_linux(exe_cmd)
            info = '生成成功。'
        except:
            info = '生成失败。'

        return info
代码实现

4、定义虚拟机

virsh define /etc/libvirt/qemu/CentOS-7@test1.xml

 

posted @ 2020-07-28 17:10  TianShu  Views(2928)  Comments(0Edit  收藏  举报