Oracle Solaris ZFS 管理指南

第 10 章 Oracle Solaris ZFS 高级主题

本章介绍 ZFS 卷、在安装了区域的 Solaris 系统中使用 ZFS、ZFS 备用根池以及 ZFS 权限配置文件。

本章包含以下各节:

ZFS 卷

ZFS 卷是表示块设备的数据集。ZFS 卷被标识为 /dev/zvol/{dsk,rdsk}/pool 目录中的设备。

以下示例将创建 5 GB 的 ZFS 卷 tank/vol


# zfs create -V 5gb tank/vol

创建卷时,会自动设置卷初始大小的预留空间,以防发生意外行为。例如,如果卷大小减小,则可能导致数据受损。更改卷大小时请务必小心。

此外,如果对大小发生更改的卷创建快照,并且尝试回滚该快照或从该快照中创建克隆,则可能会引入不一致性。

有关可应用于卷的文件系统属性的信息,请参见表 6–1

如果使用安装了区域的 Solaris 系统,则不能在非全局区域中创建或克隆 ZFS 卷。试图这样做必定会失败。有关在全局区域中使用 ZFS 卷的信息,请参见向非全局区域中添加 ZFS 卷

使用 ZFS 卷作为交换设备或转储设备

安装 ZFS 根文件系统或从 UFS 根文件系统迁移期间,会在 ZFS 根池中的 ZFS 卷上创建交换设备。例如:


# swap -l
swapfile                  dev    swaplo   blocks     free
/dev/zvol/dsk/rpool/swap 253,3        16  8257520  8257520

安装 ZFS 根文件系统或从 UFS 根文件系统迁移期间,会在 ZFS 根池中的 ZFS 卷上创建转储设备。转储设备在设置后便无需管理。例如:


# dumpadm
      Dump content: kernel pages
       Dump device: /dev/zvol/dsk/rpool/dump (dedicated)
Savecore directory: /var/crash/t2000
  Savecore enabled: yes

如果在安装或升级系统后需要更改交换区域或转储设备,请像在先前的 Solaris 发行版中那样使用 swapdumpadm 命令。如果需要创建其他交换卷,请创建一个特定大小的 ZFS 卷,然后在该设备中启用交换。例如:


# 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 交换文件配置。

有关调整交换和转储卷大小的信息,请参见调整 ZFS 交换设备和转储设备的大小

使用 ZFS 卷作为 Solaris iSCSI 目标

通过设置卷的 shareiscsi 属性,可以轻松创建 ZFS 卷作为 iSCSI 目标。例如:


# zfs create -V 2g tank/volumes/v2
# zfs set shareiscsi=on tank/volumes/v2
# iscsitadm list target
Target: tank/volumes/v2
    iSCSI Name: iqn.1986-03.com.sun:02:984fe301-c412-ccc1-cc80-cf9a72aa062a
    Connections: 0

创建 iSCSI 目标后,应设置 iSCSI 启动器。有关 Solaris iSCSI 目标和启动器的更多信息,请参见《系统管理指南:设备和文件系统》中的第 15  章 “配置 Solaris iSCSI 启动器(任务)”


注 –

也可以使用 iscsitadm 命令来创建和管理 Solaris iSCSI 目标。如果对 ZFS 卷设置 shareiscsi 属性,请勿使用 iscsitadm 命令再创建同一目标设备。否则将为同一设备创建重复的目标信息。


可以像管理其他 ZFS 数据集一样来管理作为 iSCSI 目标的 ZFS 卷。不过,对于 iSCSI 目标而言,renameexportimport 操作的工作方式略有不同。

所有 iSCSI 目标配置信息都存储在数据集内。与 NFS 共享文件系统相似,在其他系统中导入的 iSCSI 目标也会相应进行共享。

在安装了区域的 Solaris 系统中使用 ZFS

以下各节介绍如何在具有 Oracle Solaris 区域的系统中使用 ZFS。

有关在具有 ZFS 根文件系统(将使用 Oracle Solaris Live Upgrade 进行迁移或修补)的系统上配置区域的信息,请参见使用 Oracle Solaris Live Upgrade 迁移或升级具有区域的系统 (Solaris 10 10/08)使用 Oracle Solaris Live Upgrade 迁移或升级具有区域的系统(最低Solaris 10 5/09)

将 ZFS 数据集与区域关联时,请牢记以下要点:

在以下各节中,ZFS 数据集是指文件系统或克隆。

通过添加数据集,非全局区域可与全局区域共享磁盘空间,但区域管理员不能在底层文件系统分层结构中控制属性或创建新文件系统。该操作与向区域中添加其他任何类型的文件系统相同,应该在主要目的只是为了共享公用磁盘空间时才这样做。

使用 ZFS,还可将数据集委托给非全局区域,从而授予区域管理员对数据集及其所有子级的完全控制。区域管理员可以在此数据集中创建和销毁文件系统或克隆,并可修改数据集的属性。区域管理员无法影响尚未添加到区域中的数据集,包括不能超过对委托数据集设置的任何顶层配额。

在安装了 Oracle Solaris 区域的系统中使用 ZFS 时,请考虑以下事项:

向非全局区域中添加 ZFS 文件系统

如果目标只是与全局区域共享空间,则可添加 ZFS 文件系统作为通用文件系统。添加到非全局区域的 ZFS 文件系统必须将其 mountpoint 属性设置为 legacy

可以使用 zonecfg 命令的 add fs 子命令将 ZFS 文件系统添加到非全局区域中。

在以下示例中,全局区域中的全局区域管理员会向非全局区域中添加一个 ZFS 文件系统:


# zonecfg -z zion
zonecfg:zion> add fs
zonecfg:zion:fs> set type=zfs
zonecfg:zion:fs> set special=tank/zone/zion
zonecfg:zion:fs> set dir=/export/shared
zonecfg:zion:fs> end

此语法可向挂载在 /export/shared 且已配置的 zion 区域中添加 ZFS 文件系统 tank/zone/zion。文件系统的 mountpoint 属性必须设置为 legacy,并且该文件系统不能已在其他位置挂载。区域管理员可在文件系统中创建和销毁文件。不能在其他位置重新挂载文件系统,区域管理员也不能更改该文件系统的属性,如 atimereadonlycompression 等。全局区域管理员负责设置和控制文件系统的属性。

有关 zonecfg 命令以及使用 zonecfg 配置资源类型的更多信息,请参见《系统管理指南:Oracle Solaris Containers-资源管理和 Oracle Solaris Zones》中的第 II 部分, “Zones”

将数据集委托给非全局区域

为实现将存储管理委托给区域的主要目标,ZFS 支持通过使用 zonecfg 命令的 add dataset 子命令向非全局区域中添加数据集。

在以下示例中,全局区域中的全局区域管理员会将一个 ZFS 文件系统委托给非全局区域。


# zonecfg -z zion
zonecfg:zion> add dataset
zonecfg:zion:dataset> set name=tank/zone/zion
zonecfg:zion:dataset> end

与添加文件系统不同,此语法会使 ZFS 文件系统 tank/zone/zion 在已配置的 zion 区域中可见。区域管理员可以设置文件系统属性,也可以创建后代文件系统。此外,区域管理员还可以创建快照和克隆,或者控制整个文件系统分层结构。

如果使用 Oracle Solaris Live Upgrade 升级带有非全局区域的 ZFS BE,首先请删除所有委托数据集。否则,Oracle Solaris Live Upgrade 会因只读文件系统错误而失败。例如:


zonecfg:zion>
zonecfg:zion> remove dataset name=tank/zone/zion
zonecfg:zion1> exit

有关区域内所允许的操作的更多信息,请参见在区域内管理 ZFS 属性

向非全局区域中添加 ZFS 卷

不能使用 zonecfg 命令的 add dataset 子命令向非全局区域中添加 ZFS 卷。但是,可以使用 zonecfg 命令的 add device 子命令向区域中添加卷。

在以下示例中,全局区域中的全局区域管理员会向非全局区域中添加一个 ZFS 卷:


# zonecfg -z zion
zion: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zion> create
zonecfg:zion> add device
zonecfg:zion:device> set match=/dev/zvol/dsk/tank/vol
zonecfg:zion:device> end

此语法将 tank/vol 卷添加到 zion 区域中。请注意,即使卷不与物理设备对应,向区域中添加原始卷仍然可能存在安全风险。具体来说,区域管理员可能会创建格式错误的文件系统,这在尝试挂载时会使系统发出警告音。有关向区域中添加设备以及相关的安全风险的更多信息,请参见了解 zoned 属性

有关向区域添加设备的更多信息,请参见《系统管理指南:Oracle Solaris Containers-资源管理和 Oracle Solaris Zones》中的第 II 部分, “Zones”

在区域中使用 ZFS 存储池

不能在区域中创建或修改 ZFS 存储池。委托的管理模型可将对全局区域内的物理存储设备的控制以及对虚拟存储的控制集中到非全局区域。尽管可向区域中添加池级别数据集,但区域内不允许使用用于修改该池的物理特征的任何命令,如创建、添加或删除设备。即使使用 zonecfg 命令的 add device 子命令向区域中添加物理设备或是已使用了文件,zpool 命令也不允许在该区域内创建任何池。

在区域内管理 ZFS 属性

将数据集委托给区域后,区域管理员便可控制特定的数据集属性。将数据集委托给区域后,该数据集的所有祖先都显示为只读数据集,而该数据集本身则与其所有后代一样是可写的。例如,请参考以下配置:


global# zfs list -Ho name
tank
tank/home
tank/data
tank/data/matrix
tank/data/zion
tank/data/zion/home

如果将 tank/data/zion 添加到区域中,则每个数据集都将具有以下属性。

数据集 

可见 

可写 

不变属性 

tank

是 

否 

tank/home

否 

tank/data

是 

否 

tank/data/matrix

否 

tank/data/zion

是 

是 

sharenfszonedquotareservation

tank/data/zion/home

是 

是 

sharenfszoned

请注意,tank/zone/zion 的每个父级都会显示为只读,所有后代都可写,不属于父级分层结构的数据集完全不可见。由于非全局区域不能充当 NFS 服务器,因此区域管理员无法更改 sharenfs 属性。区域管理员也不能更改 zoned 属性,否则将产生下节介绍的安全风险。

区域中的特权用户可以更改除 quotareservation 之外的任何属性。全局区域管理员借助此行为可以控制非全局区域所使用的所有数据集的磁盘空间占用情况。

此外,将数据集委托给非全局区域后,全局区域管理员便无法更改 sharenfsmountpoint 属性。

了解 zoned 属性

将数据集委托给非全局区域时,必须对该数据集进行特殊标记,以便不在全局区域的上下文中解释特定属性。将数据集委托给受区域管理员控制的非全局区域之后,便不能再信任其内容。与任何文件系统一样,可能存在 setuid 二进制命令、符号链接或可能对全局区域的安全性造成不利影响的可疑内容。此外,不能在全局区域的上下文中解释 mountpoint 属性。否则,区域管理员可能会影响全局区域的名称空间。为解决后一个问题,ZFS 使用 zoned 属性来指示已在某一时刻将数据集委托给非全局区域。

zoned 属性是在首次引导包含 ZFS 数据集的区域时自动启用的布尔值。区域管理员将无需手动启用此属性。如果设置了 zoned 属性,则无法在全局区域中挂载或共享数据集。以下示例将 tank/zone/zion 委托给一个区域,tank/zone/global 则没有委托:


# zfs list -o name,zoned,mountpoint -r tank/zone
NAME                  ZONED  MOUNTPOINT
tank/zone/global        off  /tank/zone/global
tank/zone/zion           on  /tank/zone/zion
# zfs mount
tank/zone/global           /tank/zone/global
tank/zone/zion             /export/zone/zion/root/tank/zone/zion

请注意 mountpoint 属性与当前挂载 tank/zone/zion 数据集的目录之间的差异。mountpoint 属性反映的是磁盘上存储的属性,而不是数据集当前在系统中的挂载位置。

从区域中删除数据集或销毁区域时,不会自动清除 zoned 属性。此行为是由与这些任务关联的固有安全风险引起的。由于不受信任的用户已取得对数据集及其后代的完全访问权限,因此 mountpoint 属性可能会设置为错误值,或者文件系统中可能存在 setuid 二进制命令。

为了防止意外的安全风险,要通过任何方式重用数据集时,必须由全局区域管理员手动清除 zoned 属性。将 zoned 属性设置为 off 之前,请确保数据集及其所有后代的 mountpoint 属性已设置为合理值并且不存在 setuid 二进制命令,或禁用 setuid 属性。

确定没有任何安全漏洞后,即可使用 zfs setzfs inherit 命令禁用 zoned 属性。如果在区域正在使用数据集时禁用 zoned 属性,则系统的行为方式可能无法预测。仅当确定非全局区域不再使用数据集时,才能更改该属性。

使用 ZFS 备用根池

创建池时,该池将固定绑定到主机系统。主机系统一直掌握着池的状况信息,以便可以检测到池何时不可用。此信息虽然对于正常操作很有用,但在从备用介质引导或在可移除介质上创建池时则会成为障碍。为解决此问题,ZFS 提供了备用根池功能。系统重新引导之后备用根池不会保留,并且所有挂载点都会被修改以与该池的根相关。

创建 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 备用根值语法在不同系统的任意备用根池下导出和导入该文件系统。


# 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

导入备用根池

也可以使用备用根来导入池。如果挂载点不是在当前根的上下文中而是在可以执行修复的某个临时目录下解释的,则可以使用此功能进行恢复。在挂载可移除介质时,也可以使用此功能,如上一节所述。

在以下示例中,名为 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

ZFS 权限配置文件

如果要在不使用超级用户 (root) 帐户的情况下执行 ZFS 管理任务,则可采用具有以下任一配置文件的角色来执行 ZFS 管理任务:

有关创建或分配角色的更多信息,请参见《系统管理指南:安全性服务》

除了使用 RBAC 角色来管理 ZFS 文件系统之外,还可以考虑使用 ZFS 委托管理来进行分布式 ZFS 管理任务。有关更多信息,请参见第 9 章