块是一个字节序列,例如 512 字节的数据块。基于块的存储接口是使用旋转媒体(例如硬盘、CD、软盘)存储数据最常见的方式。块设备接口的普及,也使得虚拟块设备成为与大量数据存储系统(例如 Ceph)进行交互的理想选择。
Ceph 块设备允许共享物理资源,并且可以调整大小。它们会在 Ceph 集群中的多个 OSD 上等量存储数据。Ceph 块设备会利用 RADOS 功能,例如创建快照、复制和一致性。Ceph 的 RADOS 块设备 (RBD) 使用内核模块或 librbd
库与 OSD 交互。
Ceph 的块设备为内核模块提供高性能及无限的可扩展性。它们支持虚拟化解决方案(例如 QEMU)或依赖于 libvirt
的基于云的计算系统(例如 OpenStack)。您可以使用同一个集群来同时操作对象网关、CephFS 和 RADOS 块设备。
rbd
命令可让您创建、列出、内省和删除块设备映像。您还可以使用它来执行其他操作,例如,克隆映像、创建快照、将映像回滚到快照或查看快照。
要使用 RADOS 块设备命令,您必须拥有对运行中 Ceph 集群的访问权限。
您必须先在集群中为块设备创建映像,然后才能将其添加到节点。要创建块设备映像,请执行以下命令:
root #
rbd create --size megabytes pool-name/image-name
例如,要创建名为“bar”的 1GB 映像,并将信息存储在名为“swimmingpool”的存储池中,请执行以下命令:
root #
rbd create --size 1024 swimmingpool/bar
如果您在创建映像时不指定存储池,映像将存储在默认存储池“rbd”中。
自 SUSE Enterprise Storage 5 起,可以将块设备映像的数据存储在纠删码池中。只能将 RBD 映像的“数据”部分存储在纠删码池中。另外,纠删码池必须将“overwrite”标志设置为 true,而只有在所有 OSD 都使用 BlueStore 的情况下,才能将此标志设置为 true。
映像元数据不能驻留在纠删码池中。元数据可以驻留在默认的“rbd”池中,或用户使用参数 --pool= 在 rbd create
命令中明确指定的存储池中。
所有节点都需要 BlueStore 才能使用纠删码池存储块设备映像。
使用以下步骤可在纠删码池中创建 RBD 映像:
root #
ceph
osd pool create POOL_NAME 12 12 erasureroot #
ceph
osd pool set POOL_NAME allow_ec_overwrites true # Metadata will reside in pool "rbd", and data in pool "POOL_NAME"root #
rbd
create IMAGE_NAME --size=1G --data-pool POOL_NAME #Metadata will reside in pool "OTHER_POOL", and data in pool "POOL_NAME"root #
rbd
create IMAGE_NAME --size=1G --data-pool POOL_NAME --pool=OTHER_POOL
要列出“rbd”池中的块设备,请执行以下命令(“rbd”是默认池名称):
root #
rbd ls
要列出名为“swimmingpool”的存储池中的块设备,请执行以下命令:
root #
rbd ls swimmingpool
RADOS 块设备映像是瘦配置 — 在您开始将数据保存到这些映像之前,它们实际上并不会使用任何物理存储。但是,这些映像具有您使用 --size
选项设置的最大容量。如果您要增大(或减小)映像的最大大小,请运行以下命令:
root #
rbd resize --size 2048 foo # to increase
rbd resize --size 2048 foo --allow-shrink # to decrease
创建 RADOS 块设备之后,便可以格式化并挂载它以便能够交换文件,然后在完成时将其卸载。
确保您的 Ceph 集群包括要挂载的磁盘映像所在的存储池。假设存储池名为 mypool
,映像名为 myimage
。
rbd list mypool
将映像映射到新的块设备。
root #
rbd map --pool mypool myimage
要指定用户名,请使用 --id 用户名
。此外,如果您使用了 cephx
身份验证,则还必须指定机密。该机密可能来自密钥环,或某个包含机密的文件:
root #
rbd map --pool rbd myimage --id admin --keyring /path/to/keyring
或者
root #
rbd map --pool rbd myimage --id admin --keyfile /path/to/file
列出所有映射的设备:
root #
rbd showmapped
id pool image snap device
0 mypool myimage - /dev/rbd0
我们要使用的设备是 /dev/rbd0
。
在 /dev/rbd0
设备上创建 XFS 文件系统。
root #
mkfs.xfs /dev/rbd0
log stripe unit (4194304 bytes) is too large (maximum is 256KiB)
log stripe unit adjusted to 32KiB
meta-data=/dev/rbd0 isize=256 agcount=9, agsize=261120 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=2097152, imaxpct=25
= sunit=1024 swidth=1024 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=8 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
挂载设备并检查它是否已正确挂载。将 /mnt
替换为您的挂载点。
root #
mount /dev/rbd0 /mntroot #
mount | grep rbd0 /dev/rbd0 on /mnt type xfs (rw,relatime,attr2,inode64,sunit=8192,...
现在,您便可以将数据移入/移出设备,就如同它是本地目录一样。
如果您发现 RBD 设备的大小不再够用,可以轻松增大大小。
增大 RBD 映像的大小,例如增大到 10GB。
root #
rbd resize --size 10000 mypool/myimage
Resizing image: 100% complete...done.
扩大文件系统以填入设备的新大小。
root #
xfs_growfs /mnt
[...]
data blocks changed from 2097152 to 2560000
当您访问过设备后,可以将其卸载。
root #
unmount /mnt
因为在引导之后手动映射和挂载 RBD 映像以及在关机之前卸载和取消映射会非常麻烦,我们提供了 rbdmap
脚本和 systemd
单元。请参考第 8.4 节 “rbdmap:在引导时映射 RBD 设备”。
RBD 快照是 RADOS 块设备映像的快照。通过快照,您可以保留映像状态的历史。Ceph 还支持快照分层,这可让您轻松快速地克隆 VM 映像。Ceph 使用 rbd
命令和许多高级接口(包括 QEMU、libvirt
、OpenStack 和 CloudStack)支持块设备快照。
在创建映像快照之前,请停止输入和输出操作。如果映像包含文件系统,则在创建快照之前,文件系统必须处于一致状态。
如果 cephx
处于启用状态(有关更多信息,请参见http://ceph.com/docs/master/rados/configuration/auth-config-ref/),您必须指定用户名或 ID 以及包含用户的相应密钥的密钥环路径。有关更多详细信息,请参见用户管理。您还可以添加 CEPH_ARGS
环境变量,以免重新输入以下参数。
root #
rbd --id user-ID --keyring=/path/to/secret commandsroot #
rbd --name username --keyring=/path/to/secret commands
例如:
root #
rbd --id admin --keyring=/etc/ceph/ceph.keyring commandsroot #
rbd --name client.admin --keyring=/etc/ceph/ceph.keyring commands
将用户和机密添加到 CEPH_ARGS
环境变量,如此您便无需每次都输入它们。
下面的过程说明如何在命令行上使用 rbd
命令创建、列出和删除快照。
要使用 rbd
创建快照,请指定 snap create
选项、存储池名称和映像名称。
root #
rbd --pool pool-name snap create --snap snap-name image-nameroot #
rbd snap create pool-name/image-name@snap-name
例如:
root #
rbd --pool rbd snap create --snap snapshot1 image1root #
rbd snap create rbd/image1@snapshot1
要列出映像的快照,请指定存储池名称和映像名称。
root #
rbd --pool pool-name snap ls image-nameroot #
rbd snap ls pool-name/image-name
例如:
root #
rbd --pool rbd snap ls image1root #
rbd snap ls rbd/image1
要使用 rbd
回滚快照,请指定 snap rollback
选项、存储池名称、映像名称和快照名称。
root #
rbd --pool pool-name snap rollback --snap snap-name image-nameroot #
rbd snap rollback pool-name/image-name@snap-name
例如:
root #
rbd --pool pool1 snap rollback --snap snapshot1 image1root #
rbd snap rollback pool1/image1@snapshot1
将映像回滚到快照意味着会使用快照中的数据重写当前版本的映像。执行回滚所需的时间将随映像大小的增加而延长。从快照克隆较快,而从映像到快照的回滚较慢,因此克隆是返回先前存在状态的首选方法。
要使用 rbd
删除快照,请指定 snap rm
选项、存储池名称、映像名称和用户名。
root #
rbd --pool pool-name snap rm --snap snap-name image-nameroot #
rbd snap rm pool-name/image-name@snap-name
例如:
root #
rbd --pool pool1 snap rm --snap snapshot1 image1root #
rbd snap rm pool1/image1@snapshot1
Ceph OSD 会以异步方式删除数据,因此删除快照不能立即释放磁盘空间。
要使用 rbd
删除映像的所有快照,请指定 snap purge
选项和映像名称。
root #
rbd --pool pool-name snap purge image-nameroot #
rbd snap purge pool-name/image-name
例如:
root #
rbd --pool pool1 snap purge image1root #
rbd snap purge pool1/image1
Ceph 支持创建许多块设备快照的写入时复制 (COW) 克隆的能力。快照分层可让 Ceph 块设备客户端能够极快地创建映像。例如,您可以创建块设备映像并将 Linux VM 写入其中,然后创建映像的快照、保护快照,并创建您所需数量的“写入时复制”克隆。快照是只读的,因此克隆快照简化了语义,如此可快速创建克隆。
下面的命令行示例中提到的“父”和“子”这两个术语是指 Ceph 块设备快照(父)和从快照克隆的相应映像(子)。
每个克隆的映像(子)都存储了对其父映像的引用,这可让克隆的映像打开父快照并读取其内容。
快照的 COW 克隆的行为方式与任何其他 Ceph 块设备映像完全相同。可针对克隆的映像执行读取、写入、克隆和调整大小操作。系统对克隆的映像没有特殊限制。但是,快照的写入时复制克隆会引用快照,因此您必须在克隆快照之前保护快照。
Ceph 只支持克隆格式 2 映像(即使用 rbd create --image-format 2
创建的映像)。
Ceph 块设备分层是一个简单的过程。您必须有一个映像。您必须创建映像的快照。您必须保护快照。在您执行这些步骤之后,就可以开始克隆快照了。
克隆的映像具有对父快照的引用,并且包含存储池 ID、映像 ID 和快照 ID。包含存储池 ID 意味着您可以将快照从一个存储池克隆到另一个存储池中的映像。
映像模板:一种常见的块设备分层用例是创建主映像和用作克隆模板的快照。例如,用户可为 Linux 发行套件(如 SUSE Linux Enterprise Server)创建映像并为它创建快照。用户可以定期更新映像和创建新的快照(例如,先执行 zypper ref && zypper patch
,接着执行 rbd snap create
)。随着映像日趋成熟,用户可以克隆任何一个快照。
扩展模板:更高级的用例包括扩展比基本映像提供的信息更多的模板映像。例如,用户可以克隆映像(VM 模板)并安装其他软件(例如,数据库、内容管理系统或分析系统),然后创建扩展映像的快照,这个扩展映像可以如基本映像一样更新。
模板池:使用块设备分层的一种方法是创建包含主映像(用作模板)的池,然后创建这些模板的快照。之后,您便可以扩大用户的只读特权,使他们可以克隆快照,却不能写入存储池或在存储池中执行。
映像迁移/恢复:使用块设备分层的一种方法是将数据从一个存储池迁移或恢复到另一个存储池。
克隆会访问父快照。如果用户意外删除了父快照,则所有克隆都会损坏。为了防止数据丢失,您需要先保护快照,然后才能克隆它。
root #
rbd --pool pool-name snap protect \ --image image-name --snap snapshot-nameroot #
rbd snap protect pool-name/image-name@snapshot-name
例如:
root #
rbd --pool pool1 snap protect --image image1 --snap snapshot1root #
rbd snap protect pool1/image1@snapshot1
您无法删除受保护的快照。
要克隆快照,您需要指定父存储池、映像、快照、子存储池和映像名称。您需要先保护快照,然后才能克隆它。
root #
rbd --pool pool-name --image parent-image \ --snap snap-name --dest-pool pool-name \ --dest child-imageroot #
rbd clone pool-name/parent-image@snap-name \ pool-name/child-image-name
例如:
root #
rbd clone pool1/image1@snapshot1 pool1/image2
您可以将快照从一个存储池克隆到另一个存储池中的映像。例如,可以在一个存储池中将只读映像和快照作为模板维护,而在另一个存储池中维护可写入克隆。
必须先取消保护快照,然后才能删除它。另外,您无法删除克隆所引用的快照。您需要先平展快照的每个克隆,然后才能删除快照。
root #
rbd --pool pool-name snap unprotect --image image-name \ --snap snapshot-nameroot #
rbd snap unprotect pool-name/image-name@snapshot-name
例如:
root #
rbd --pool pool1 snap unprotect --image image1 --snap snapshot1root #
rbd snap unprotect pool1/image1@snapshot1
要列出快照的子项,请执行以下命令:
root #
rbd --pool pool-name children --image image-name --snap snap-nameroot #
rbd children pool-name/image-name@snapshot-name
例如:
root #
rbd --pool pool1 children --image image1 --snap snapshot1root #
rbd children pool1/image1@snapshot1
克隆的映像会保留对父快照的引用。删除子克隆对父快照的引用时,可通过将信息从快照复制到克隆,高效“平展”映像。平展克隆所需的时间随着映像大小的增加而延长。要删除快照,必须先平展子映像。
root #
rbd --pool pool-name flatten --image image-nameroot #
rbd flatten pool-name/image-name
例如:
root #
rbd --pool pool1 flatten --image image1root #
rbd flatten pool1/image1
由于平展的映像包含快照中的所有信息,平展的映像占用的存储空间将比分层克隆多。
rbdmap
是一个外壳脚本,可针对一个或多个 RADOS 块设备映像自动执行 rbd map
和 rbd unmap
操作。虽然您随时都可以手动运行该脚本,但其主要用来在引导时自动映射和挂载 RBD 映像(以及在关机时卸载和取消映射),此操作由 Init 系统触发。ceph-common
包中随附了一个 systemd
单元文件 rbdmap.service
用于执行此操作。
该脚本使用单个自变量,可以是 map
或 unmap
。使用任一自变量时,该脚本都会分析配置文件。它默认为 /etc/ceph/rbdmap
,但可通过环境变量 rbdmapFILE
覆盖。该配置文件的每一行相当于一个要映射或取消映射的 RBD 映像。
配置文件采用以下格式:
image_specification rbd_options
存储池中映像的路径。以 pool_name/image_name 格式指定。如果您省略 pool_name,则假设使用默认名称“rbd”。
要传递给底层 rbd map
命令的参数的可选列表。这些参数及其值应该以逗号分隔的字符串形式指定,例如:
PARAM1=VAL1,PARAM2=VAL2,...
该示例让 rbdmap
脚本运行以下命令:
rbd map pool_name/image_name --PARAM1 VAL1 --PARAM2 VAL2
以 rbdmap map
形式运行时,该脚本会分析配置文件,并且对于每个指定的 RBD 映像,它会尝试先映射映像(使用 rbd map
命令),再挂载映像。
以 rbdmap unmap
形式运行时,配置文件中列出的映像将卸载并取消映射。
rbdmap unmap-all
会尝试卸载然后取消映射所有当前已映射的 RBD 映像,而不论它们是否列在配置文件中。
如果成功,rbd map 操作会将映像映射到 /dev/rbdX 设备,此时会触发 udev 规则,以创建易记设备名称符号链接 /dev/rbd/pool_name/image_name
,该链接指向实际映射的设备。
为了挂载和卸载成功,易记设备名称在 /etc/fstab
中需有对应项。写入 RBD 映像的 /etc/fstab
项时,指定“noauto”(或“nofail”)挂载选项。这可防止 Init 系统过早(尚未出现有问题的设备时)尝试挂载设备,因为 rbdmap.service
通常是在引导序列中相当靠后的时间触发。
有关 rbd
选项的完整列表,请参见 rbd
手册页 (man 8 rbd
)。
有关 rbdmap
用法的示例,请参见 rbdmap
手册页 (man 8 rbdmap
)。
RBD 映像可以在两个 Ceph 集群之间异步镜像。此功能使用 RBD 日记映像功能来确保集群之间的复制在崩溃时保持一致。镜像在对等集群中逐池配置,并且可以配置为自动镜像池中的所有映像或仅镜像特定的映像子集。镜像使用 rbd
命令进行配置。rbd-mirror
守护进程负责从远程对等集群提取映像更新,并将它们应用于本地集群中的映像。
要使用 RBD 镜像,您需要有两个 Ceph 集群,每个集群都运行 rbd-mirror
守护进程。
两个 rbd-mirror
守护进程负责检查远程对等集群上的映像日记并针对本地集群重放日记事件。RBD 映像日记功能会按发生的顺序记录对映像进行的所有修改。如此可确保远程映像崩溃状态一致的镜像可在本地使用。
rbd-mirror
守护进程在 rbd-mirror
包中提供。在其中一个集群节点上安装、启用并启动它:
root@minion >
zypper install rbd-mirrorroot@minion >
systemctl enable ceph-rbd-mirror@server_name.serviceroot@minion >
systemctl start ceph-rbd-mirror@server_name.service
每个 rbd-mirror
守护进程都必须能够同时连接到两个集群。
以下过程说明如何使用 rbd
命令来执行配置镜像的基本管理任务。镜像在 Ceph 集群中逐池进行配置。
您需要在两个对等集群上执行存储池配置步骤。为清楚起见,这些过程假设名为“local”和“remote”的两个集群可从单台主机访问。
有关如何连接到不同的 Ceph 集群的更多详细信息,请参见 rbd
手册页 (man 8 rbd
)。
要针对存储池启用镜像,请指定 mirror pool enable
子命令、存储池名称和镜像模式。镜像模式可以是存储池或映像:
将会镜像启用了日记功能的存储池中的所有映像。
需要针对每个映像明确启用镜像。有关详细信息,请参见第 8.5.3.2 节 “启用映像镜像”。
例如:
root #
rbd --cluster local mirror pool enable image-pool poolroot #
rbd --cluster remote mirror pool enable image-pool pool
要对存储池禁用镜像,请指定 mirror pool disable
子命令和存储池名称。使用这种方法对存储池禁用镜像时,还会对已为其明确启用镜像的所有映像(该存储池中)禁用镜像。
root #
rbd --cluster local mirror pool disable image-poolroot #
rbd --cluster remote mirror pool disable image-pool
为了让 rbd-mirror
守护进程发现它的对等集群,需要向存储池注册该对等集群。要添加镜像对等集群,请指定 mirror pool peer add
子命令、存储池名称和集群规格:
root #
rbd --cluster local mirror pool peer add image-pool client.remote@remoteroot #
rbd --cluster remote mirror pool peer add image-pool client.local@local
要删除镜像对等集群,请指定 mirror pool peer remove
子命令、存储池名称和对等 UUID(可通过 rbd mirror pool info
命令获得):
root #
rbd --cluster local mirror pool peer remove image-pool \ 55672766-c02b-4729-8567-f13a66893445root #
rbd --cluster remote mirror pool peer remove image-pool \ 60c0e299-b38f-4234-91f6-eed0a367be08
与存储池配置不同,映像配置只需要针对单个镜像对等 Ceph 集群执行。
系统会将镜像的 RBD 映像指定为主要或非主要。这是映像的属性,而不是存储池的属性。不能修改指定为非主要的映像。
当首次对某个映像启用镜像时(如果存储池镜像模式是“存储池”并且映像已启用日记映像功能,则为隐式启用,或可通过 rbd
命令显式启用(请参见第 8.5.3.2 节 “启用映像镜像”)),映像会自动升级为主要映像。
RBD 镜像使用 RBD 日记功能来确保复制的映像始终在崩溃时保持一致状态。在将映像镜像到对等集群之前,必须启用日记功能。可以在创建映像时通过将 --image-feature exclusive-lock,journaling
选项提供给 rbd
命令来启用该功能。
或者,日志功能可以针对预先存在的 RBD 映像动态启用。要启用日记,请指定 feature enable
子命令、存储池和映像名称以及功能名称:
root #
rbd --cluster local feature enable image-pool/image-1 journaling
journaling
功能依赖于 exclusive-lock
功能。如果 exclusive-lock
功能尚未启用,则您需要先启用它,再启用 journaling
功能。
默认情况下,可通过将下面一行添加到 Ceph 配置文件来针对所有新映像启用日记:
rbd default features = 125
如果以“映像”模式对映像的存储池配置镜像,则需要为存储池中的每个映像明确启用镜像。要为特定映像启用镜像,请指定 mirror image enable
子命令以及存储池和映像名称:
root #
rbd --cluster local mirror image enable image-pool/image-1
要为特定映像禁用镜像,请指定 mirror image disable
子命令以及存储池和映像名称:
root #
rbd --cluster local mirror image disable image-pool/image-1
在需要将主要指定移动到对等集群中映像的故障转移情况下,您需要停止访问主要映像、降级当前主要映像、升级新的主要映像,然后继续访问替代集群上的映像。
要将特定映像降级为非主要映像,请指定 mirror image demote
子命令以及存储池和映像名称:
root #
rbd --cluster local mirror image demote image-pool/image-1
要将存储池中的所有主要映像都降级为非主要映像,请指定 mirror pool demote
子命令以及存储池名称:
root #
rbd --cluster local mirror pool demote image-pool
要将特定映像升级为主要映像,请指定 mirror image promote
子命令以及存储池和映像名称:
root #
rbd --cluster remote mirror image promote image-pool/image-1
要将存储池中的所有非主要映像都升级为主要映像,请指定 mirror pool promote
子命令以及存储池名称:
root #
rbd --cluster local mirror pool promote image-pool
因为主要或非主要状态都是针对每个映像指定的,所以可以将两个集群拆分为 IO 负载和阶段故障转移或故障回复。
可以使用 --force
选项强制升级。降级不能传播到对等集群时(例如,当集群发生故障或通讯中断时),就需要强制升级。这将导致两个对等集群之间出现节点分裂情况,并且映像不再同步,直到发出了 resync
子命令。
如果 rbd-mirror
守护进程检测到分区事件,则在该情况解决之前,它不会尝试镜像受影响的映像。要继续镜像映像,请先降级确定过期的映像,然后请求与主要映像重新同步。要请求映像重新同步,请指定 mirror image resync
子命令以及存储池和映像名称:
root #
rbd mirror image resync image-pool/image-1
系统会存储每个主要镜像映像的对等集群复制状态。此状态可使用 mirror image status
和 mirror pool status
子命令检索:
要请求镜像映像状态,请指定 mirror image status
子命令以及存储池和映像名称:
root #
rbd mirror image status image-pool/image-1
要请求镜像存储池摘要状态,请指定 mirror pool status
子命令以及存储池名称:
root #
rbd mirror pool status image-pool
将 --verbose
选项添加到 mirror pool status
子命令会额外地输出存储池中每个镜像映像的状态详细信息。