高级主题
ZFS卷
ZFS卷是表示块设备的数据集。可以在/dev/zvol/{dsk,rdsk}/rpool目录中将ZFS卷定义为设备。
以下示例中,创建一个5GB的ZFS卷system1/vol:
$ zfs create -V 5gb system1/vol
改变卷的大小时需要小心:缩小卷可能会发生数据损坏;如果创建大小发生变化的卷的快照,当尝试回滚快照或从快照创建克隆,可能会导致不一致。
因此,在创建卷时,保留会自动设置为卷的初始大小,以确保数据完整性。
使用zfs get或zfs get all命令可以显示zfs卷的属性:
$ zfs get all system1/vol
如果输出结果中volsize后面跟了一个问号,则表示I/O错误造成无法获知正确值。例如:
$ zfs get -H volsize system1/vol
system1/vol volsize ? local
I/O错误通常表示池设备有问题。
如果使用安装了区域的Oracle Solaris系统,则无法在本机区域中创建或克隆ZFS卷。
用作交换或转储设备
在安装ZFS根文件系统或从UFS根文件系统迁移期间,将在ZFS根池中的ZFS卷上创建交换设备和转储设备。
以下例子展示如何显示交换设备和转储设备的信息:
$ swap -l
swapfile dev swaplo blocks free
/dev/zvol/dsk/rpool/swap 253,3 16 8257520 8257520
$ dumpadm
Dump content: kernel pages
Dump device: /dev/zvol/dsk/rpool/dump (dedicated)
Savecore directory: /var/crash/
Savecore enabled: yes
如果在安装系统后需要更改交换区域或转储设备,可使用swap和dumpadm命令(FreeBSD中没有这两个命令)。
如果需要创建其他交换卷,可创建特定大小的ZFS卷,然后在该设备上启用交换,并在新设备的stab/vfstab中添加对应的条目。
例如:
$ zfs create -V 2G rpool/swap2
$ swap -a /dev/zvol/dsk/rpool/swap2
$ swap -l
swapfile dev swaplo blocks free
/dev/zvol/dsk/rpool/swap 256,1 16 2097136 2097136
/dev/zvol/dsk/rpool/swap2 256,5 16 4194288 4194288
不要在ZFS文件系统上使用交换文件。ZFS交换文件配置不受支持。
用作iSCSI LUN
作为iSCSI目标的ZFS卷与任何其他ZFS数据集一样进行管理,只是在ZFS卷作为iSCSI LUN共享时,不能重命名数据集、回滚卷快照或导出池。
如果试图执行这些操作,会收到类似以下的消息:
$ zfs rename system1/volumes/v2 system1/volumes/v1
cannot rename 'system1/volumes/v2': dataset is busy
$ zpool export system1
cannot export 'system1': pool is busy
所有iSCSI目标配置信息都存储在数据集中。与NFS共享文件系统一样,在不同系统上导入的iSCSI目标也会相应地共享。
通用多协议SCSI目标(COMSTAR)软件框架使您能够将任何Oracle Solaris系统转换为可由启动器主机通过存储网络访问的SCSI目标设备。您可以创建和配置要作为iSCSI逻辑单元(LUN)共享的ZFS卷。
如何将ZFS卷用作iSCSI LUN
- 首先,安装COMSTAR包
$ pkg install group/feature/storage-server
- 创建一个ZFS卷用于iSCSI目标
$ zfs create -V 2g /system1/volumes/v2
- 创建SCSI-block-device-based LUN(基于SCSI块设备的逻辑单元号)
$ sbdadm create-lu /dev/zvol/rdsk/system1/volumes/v2
Created the following LU:
GUID DATA SIZE SOURCE
-------------------------------- ------------------- ----------------
600144f000144f1dafaa4c0faff20001 2147483648 /dev/zvol/rdsk/system1/volumes/v2
$ sbdadm list-lu
Found 1 LU(s)
GUID DATA SIZE SOURCE
-------------------------------- ------------------- ----------------
600144f000144f1dafaa4c0faff20001 2147483648 /dev/zvol/rdsk/system1/volumes/v2
- 向所有ZFS客户端或选定的ZFS客户端共享LUN视图
以下示例中,LUN视图共享给所有ZFS客户端:
- 定义LUN GUID
$ stmfadm list-lu
LU Name: 600144F000144F1DAFAA4C0FAFF20001
- 共享LUN视图
$ stmfadm add-view 600144F000144F1DAFAA4C0FAFF20001
$ stmfadm list-view -l 600144F000144F1DAFAA4C0FAFF20001
View Entry: 0
Host group : All
Target group : All
LUN : 0
- 创建iSCSI目标
详见使用COMSTAR配置存储设备
top
在已安装区域的Oracle Solaris系统上使用ZFS
Oracle Solaris操作系统中的Oracle Solaris区域功能提供了一个在系统上运行应用程序的隔离环境。
将ZFS数据集与区域关联时,应注意以下几点:
- 可以将ZFS文件系统或克隆添加到本机区域,无论是否委托管理控制
- 可以将ZFS卷当作设备添加到本地区域
- 现在还不能将ZFS快照和区域结合
Oracle Solaris内核区域使用存储的方式不同于本机Oracle Solaris区域。
通过使用fs资源添加ZFS文件系统,本机区域可以与全局或内核区域共享磁盘空间。
但是,区域管理员无法在基础文件系统层次结构中控制属性或创建新的文件系统。此操作与向区域添加任何其他类型的文件系统相同。
您应该将文件系统添加到本机区域,仅用于共享公共磁盘空间。
您还可以将ZFS数据集委托给本机区域,这样区域管理员就可以完全控制数据集及其所有子级。
区域管理员可以在该数据集中创建和销毁文件系统或克隆,以及修改数据集的属性。
区域管理员不能影响尚未添加到区域的数据集,包括超过在委派数据集上设置的任何顶级配额。
当源zonepath和目标zonepath都位于ZFS文件系统上且位于同一池中时,ZoneAdmin clone命令(而不是ZFS clone)将成为克隆分区的命令。
zoneadm clone命令创建源zonepath的ZFS快照并设置目标zonepath。
将ZFS文件系统添加到非全局区域
ZFS文件系统的mountpoint属性必须设置为legacy才能将其加入到本地区域。
例如:对于文件系统system1/zone/zion,可以在全局或内核区域使用以下命令:
global$ zfs set mountpoint=legacy system1/zone/zion
然后就可以使用zonecfg命令的add fs子命令将这个文件系统添加到本地区域。注意,要添加文件系统,要先确定它没有被挂载到其他地方
global$ zonecfg -z zion
zonecfg:zion> add fs
zonecfg:zion:fs> set type=zfs
zonecfg:zion:fs> set special=system1/zone/zion
zonecfg:zion:fs> set dir=/opt/data
zonecfg:zion:fs> end
以上操作将ZFS文件系统system1/zone/zion添加到已经配置过的zion区域,该区域挂载到/opt/data。
区域管理员可以在这个文件系统中创建和销毁文件。
文件系统不能被挂载到其他地方。同样,区域管理员也不能更改文件系统上的属性,如atime、readonly、compression等。
全局区域管理员负责设置和控制文件系统的属性。
top
向非全局区域委托数据集
ZFS支持通过zonecfg add dataset命令将数据集添加到本机区域,以实现将存储管理委托给区域的目标。
下面例子中,全局区域管理员从全局区域或内核区域将一个ZFS文件系统委托给本机区域:
global$ zonecfg -z zion
zonecfg:zion> add dataset
zonecfg:zion:dataset> set name=system1/zone/zion
zonecfg:zion:dataset> set alias=system1
zonecfg:zion:dataset> end
与添加文件系统不同,以上操作使ZFS文件系统system1/zone/zion在已配置的zion区域中可见。
在zion区域中,这个文件系统不能被当作system1/zone/zion访问,但是会被当作名为system1的虚拟池。
委托的文件系统别名将原始池的视图作为虚拟池提供给区域。如果未指定别名,将使用与文件系统名称的最后一个组件匹配的默认别名。此例中,默认别名为zion。
在委托的数据集中,区域管理员可以设置文件系统属性,以及创建子文件系统。
此外,区域管理员还可以创建快照和克隆,或者控制整个文件系统层次结构。
如果在委派的文件系统中创建ZFS卷,则这些卷可能与作为设备资源添加的ZFS卷冲突。
top
向非全局区域添加ZFS卷
可以向本地区域添加或创建ZFS卷,或者通过以下途径添加对本地区域卷中数据的访问:
- 在本地区域
特权区域管理员可以将ZFS卷创建为以前委托的文件系统的后代。
例如,可以为上面示例中委托的文件系统system1/zone/zion键入以下命令:
$ zfs create -V 2g system1/zone/zion/vil1
创建卷之后,区域管理员可以可以在本地区域管理卷的属性和数据,以及生成快照。
- 在全局或内核区域
使用zonecfg add device命令并指定一个可以被本地区域访问的ZFS卷。例如:
global$ zonecfg -z zion
zonecfg:zion> add device
zonecfg:zion:device> set match=/dev/zvol/dsk/system1/volumes/vol2
zonecfg:zion:device> end
本例中,本地区域只能访问卷中的数据。
top
在区域内使用ZFS存储池
不能在本地区域内创建或修改ZFS存储池。委托管理模型集中控制全局集内核区域内的物理存储设备,并控制本地区域的虚拟存储。
尽管可以将池级数据集添加到本地区域,但不允许从本地区域内执行任何修改池物理特性的命令,如创建、添加或删除设备。
即使使用zonecfg add device命令将物理设备添加到本地区域,或使用文件,zpool命令也不能在本地区域创建任何新池。
内核区域在数据存储管理方面更强大、更灵活。设备和卷可以委托给内核区域,就像全局区域一样。此外,还可以在内核区域中创建ZFS存储池。
top
在区域内管理ZFS属性
将数据集委托给区域后,区域管理员可以控制特定的数据集属性。
将数据集委托给区域后,其所有祖先都将作为只读数据集可见,而数据集本身以及其所有后代都是可写的。
例如,考虑以下配置:
global$ zfs list -Ho name
system1
system1/home
system1/data
system1/data/matrix
system1/data/zion
system1/data/zion/home
如果使用默认的zion别名将system1/data/zion添加到一个区域,每个数据集将拥有以下属性:
数据集 |
是否可见 |
是否可写 |
不变属性 |
system1 |
No |
- |
- |
system1/home |
No |
- |
- |
system1/data |
No |
- |
- |
system1/data/zion |
Yes |
Yes |
zoned, quota, reservation |
system1/data/zion/home |
Yes |
Yes |
zoned |
注意:system1/zone/zion的每个父级都是不可见的,所有子级都是可写的。区域管理员无法更改分区属性,因为这样会暴露下一节所述的安全风险。
区域中的特权用户可以更改任何其他可设置属性,quota和reservation除外。此行为允许全局区域管理员控制本地区域使用的所有数据集的磁盘空间消耗。
此外,该份额也有所下降。将数据集委托给本地区域后,全局区域管理员无法更改share.nfs和mountpoint属性。
top
了解被分区域的属性
将数据集委托给本地区域时,必须对数据集进行特殊标记,以便某些属性不会在全局区域或内核区域的上下文中进行解释。
将数据集委托给本地区域并由区域管理员控制后,其内容将不再受信任。
与任何文件系统一样,可能存在setuid二进制文件、符号链接或其他有问题的内容,这些内容可能会对全局或内核区域的安全性产生不利影响。
此外,不能在全局或内核区域的上下文中解释mountpoint属性。否则,区域管理员可能会影响全局或内核区域的命名空间。
为了解决后者,ZFS使用zoned属性指示数据集在某个时间点已委托给本地区域。
zoned属性是一个布尔值,在首次启动包含ZFS数据集的区域时自动启用。区域管理员不需要手动设置此属性。
如果设置了zoned属性,则无法在全局或内核区域中挂载或共享数据集。
以下示例中,system1/zone/zion已委托给某个区域,但system1/zone/global还没有委托:
$ zfs list -o name,zoned,mountpoint -r system1/zone
NAME ZONED MOUNTPOINT MOUNTED
system1/zone/global off /system1/zone/global yes
system1/zone/zion on /system1/zone/zion yes
$ zfs mount
system1/zone/global /system1/zone/global
system1/zone/zion /export/zone/zion/root/system1/zone/zion
root@kzx-05:~# zonecfg -z sol info dataset
dataset:
name: rpool/foo
alias: foo
root@kzx-05:~# zfs list -o name,zoned,mountpoint,mounted -r rpool/foo
NAME ZONED MOUNTPOINT MOUNTED
rpool/foo on /system/zones/sol/root/foo yes
root@kzx-05:~# zfs mount | grep /foo
rpool/foo /system/zones/sol/root/foo
从区域中删除数据集或销毁区域时,zoned属性不会自动清除。
此行为将避免与这些任务相关的固有安全风险。因为不受信任的用户可以完全访问数据集及其子体,所以mountpoint属性可能设置为错误值,或者文件系统上可能存在setuid二进制文件。
为了防止意外的安全风险,如果要以任何方式重用数据集,则必须由全局区域管理员手动清除分区属性。
在将zoned属性设置为off之前,请确保数据集及其所有子体的mountpoint属性设置为合理的值,并且不存在setuid二进制文件,或者关闭setuid属性。
验证没有留下任何安全漏洞后,可以使用zfs set或zfs inherit命令关闭分区属性。
如果在区域内使用数据集时关闭zoned属性,则系统可能会以不可预知的方式运行。
只有在确定数据集不再由本机区域使用时,才更改属性。
top
复制区域到其他系统
当需要将一个或多个区域迁移到另一个系统时,请使用Oracle Solaris Unified Archives,它管理操作系统中的所有克隆和恢复操作,并在全局、本机和内核区域上运行。
如果一个系统上的所有区域都需要移动到另一个系统上的另一个ZFS池,可以考虑使用复制流,因为它保留快照和克隆。
pkg update、beadm create、zoneadm clone命令广泛使用快照和克隆。
以下例子中,sysA的区域安装在rpool/zones文件系统中,需要复制到newpool/zones文件系统里的sysB。
以下命令创建快照并使用复制流复制数据去sysB:
sysA$ zfs snapshot -r rpool/zones@send-to-sysB
sysA$ zfs send -R rpool/zones@seand-to-sysB | ssh sysB zfs receive -d newpool
top
使用具有备用根位置的ZFS池
池本质上与主机系统相连。主机系统维护有关池的信息,以便在池不可用时进行检测。
虽然这些信息对正常操作很有用,但当您从备用介质引导或在可移动介质上创建池时,这些信息可能会成为一种障碍。
为了解决这个问题,ZFS提供了一个备用根位置(alternate root location)池功能。
备用根池位置不会在系统重新启动时保持不变,并且所有装载点都会修改为相对于池的根。
创建具有备用根位置的ZFS池
在备用位置创建池的最常见原因是用于可移动介质。在这些情况下,用户通常需要一个文件系统,并且希望将其装载到目标系统上他们选择的任何位置。
使用zpool create –R选项创建池时,根文件系统的装入点将自动设置为/,这相当于备用根值。
下面例子中,创建一个名为morpheus的池,挂载到/mnt上作为备用根位置:
$ zpool create -R /mnt morpheus c0t0d0
$ zfs list morpheus
NAME USED AVAIL REFER MOUNTPOINT
morpheus 32.5K 33.5G 8K /mnt
注意,单个文件系统morpheus,其挂载点时池的备用根位置/mnt。
存储在磁盘上的挂载点时/,并且/mnt的完整路径仅在池创建的初始上下文中解释。
然后,可以使用-R alternate-root-value语法在不同系统上的任意备用根位置下导出和导入此文件系统。
$ zpool export morpheus
$ zpool import morpheus
cannot mount '/': directory is not empty
$ zpool export morpheus
$ zpool import -R /mnt morpheus
$ zfs list morpheus
NAME USED AVAIL REFER MOUNTPOINT
morpheus 32.5K 33.5G 8K /mnt
top
导入具有备用根位置的池
也可以使用备用根位置导入池。
此功能允许恢复情况,其中不应在当前根装入点的上下文中解释装入点,而是在可以执行修复的某个临时目录下解释装入点。
如前一节所述,在安装可移动介质时,也可以使用此功能。
在下面的示例中,一个名为morpheus的池被导入,其中/mnt作为备用根装入点。本例假设morpheus以前已导出。
$ zpool import -R /a pool
$ zpool list morpheus
NAME SIZE ALLOC FREE CAP HEALTH ALTROOT
pool 44.8G 78K 44.7G 0% ONLINE /a
$ zfs list pool
NAME USED AVAIL REFER MOUNTPOINT
pool 73.5K 44.1G 21K /a/pool
top
导入具有临时名称的池
除了在备用根位置导入池外,还可以导入具有临时名称的池。
在某些共享存储或恢复情况下,此功能允许同时导入具有相同持久名称的两个池。必须使用临时名称导入其中一个池。
在以下示例中,rpool池在备用根位置导入,并使用临时名称。由于永久池名称与已导入的池冲突,因此必须通过池ID或指定设备导入。
$ zpool import
pool: rpool
id: 16760479674052375628
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
rpool ONLINE
c8d1s0 ONLINE
$ zpool import -R /a -t altrpool 16760479674052375628
$ zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
altrpool 97G 22.4G 74G 23% 1.00x ONLINE /a
rpool 465G 75.1G 390G 16% 1.00x ONLINE -
还可以使用zpool create -t选项使用临时名称创建池。
top