一、ZFS介紹
1、ZFS文件系統
2、ZFS 與 openZFS
甲骨文收購Sun后不久,OpenSolaris成為了密切的來源。 ZFS的所有進一步開發也成為封閉源。 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