ceph 块设备

大番茄 2020年03月17日 1,509次浏览

v14.2.8

https://docs.ceph.com/docs/master/rbd/
rbd命令的一些详细信息:
https://docs.ceph.com/docs/master/man/8/rbd/

RBD(RADOS Block Device), 块设备可以跟磁盘一样格式化然后挂载。
虽然在系统里看是一块磁盘, 但是在CEPH里也是PG存储的,会分布在CEPH中的多个OSD。
特点:

  • 条带化数据存储与读取
  • 精简置备(thin-provisioned)
  • 可以调整大小

一、rbd命令

命令功能
rbd create创建块设备映像
rbd ls列出 rbd 存储池中的块设备
rbd info查看块设备信息
rbd diff可以统计 rbd 使用量
rbd map映射块设备
rbd showmapped查看已映射块设备
rbd remove删除块设备
rbd resize更改块设备的大小
rbd rm删除块设备

二、创建块设备

创建pool rbd1 64PG
[root@cephnode1 ~]# ceph osd pool create rbd1 64 64
pool 'rbd1' created
初始化pool

是为了把pool绑定到rbd这个应用上。 这个pool不是rbd中唯一的,可以绑定多个pool,然后为每个pool分别创建块设备之类的。

[root@cephnode1 ~]# rbd pool init rbd1

或者:

ceph osd pool application enable {pool-name} {application-name}

application-name 就是 rbd

创建块设备
rbd create --size {megabytes} {pool-name}/{image-name}

rbd create --size 20480 rbd1/image01

创建了20G的块设备。也支持单位 G/T。
如果pool的名字是rbd, 这里的pool-name可以省略。

查看块设备
rbd ls {poolname}
[root@cephnode1 ~]# rbd ls rbd1
image01

如果poos的名字是rbd,可以直接rbd ls

[root@cephnode1 ~]# rbd ls rbd2
image01
查看块设备信息
rbd info {pool-name}/{image-name}

or

rbd -p rbd1 info image01

-p 是rbd命令的参数,/info子命令的使用方法。 都可以。

[root@cephnode1 ~]# rbd info rbd1/image01
rbd image 'image01':
	size 20 GiB in 5120 objects
	order 22 (4 MiB objects)
	snapshot_count: 0
	id: 8760f5ae5ac3
	block_name_prefix: rbd_data.8760f5ae5ac3
	format: 2
	features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
	op_features:
	flags:
	create_timestamp: Tue Mar 17 16:44:18 2020
	access_timestamp: Tue Mar 17 16:44:18 2020
	modify_timestamp: Tue Mar 17 16:44:18 2020

这里可以看到format: 2, 这个是块设备的格式,有12
2 是新的格式,支持克隆。 但是有的内核可能会不支持。
比如我这里在把快设备map到系统的时候报错了:

[1121687.175363] libceph: client84294 fsid d5f060f7-3b0e-468e-857b-7cc592d3a94c
[1121687.178296] rbd: image image01: image uses unsupported features: 0x38

这时需要关闭一些不支持的features

features

表示一些特征。下面是 块格式id 2 支持的:

  • layering: layering support
  • striping: striping v2 support
  • exclusive-lock: exclusive locking support
  • object-map: object map support (requires exclusive-lock)
  • fast-diff: fast diff calculations (requires object-map)
  • deep-flatten: snapshot flatten support
  • journaling: journaled IO support (requires exclusive-lock)
  • data-pool: erasure coded pool support

分别是: 分层支持,条带化v2支持,独占锁支持,对象图支持,快速差异计算,快照展平化支持,journaled IO支持,rasure coded pool支持

三、映射到客户系统

客户端要做的。

安装ceph-common包,应该需要跟ceph集群版本一致把。
然后需要用户来连接集群,我这里先使用集群管理员的key了ceph.client.admin.keyring。 用户管理还不是很了解,官网虽然有添加块设备用户的例子,但是因为不懂,所以先跳过了。
还需要ceph.conf配置文件。
key与配置文件放到/etc/ceph下。

[root@client mnt]# ls /etc/ceph
ceph.client.admin.keyring  ceph.conf  rbdmap

那个rbdmap是安装ceph-common自带的,不用管它。

映射块设备到客户端系统

把块设备映射到客户端系统。

rbd map {pool-name}/{image-name}

我这里报错了。

[root@client ~]# rbd map rbd1/image01
rbd: sysfs write failed
RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature disable rbd1/image01 object-map fast-diff deep-flatten".
In some cases useful info is found in syslog - try "dmesg | tail".
rbd: map failed: (6) No such device or address

dmesg查看显示。

[root@client ~]# dmesg | tail
[1121381.321506] libceph: mon2 172.100.102.92:3300 socket closed (con state CONNECTING)
[1121381.909708] libceph: mon2 172.100.102.92:3300 socket closed (con state CONNECTING)
[1121382.909645] libceph: mon2 172.100.102.92:3300 socket closed (con state CONNECTING)
[1121384.911681] libceph: mon2 172.100.102.92:3300 socket closed (con state CONNECTING)
[1121384.916231] libceph: mon3 172.100.102.92:6789 session established
[1121384.916464] libceph: client44779 fsid d5f060f7-3b0e-468e-857b-7cc592d3a94c
[1121384.927833] rbd: image image01: image uses unsupported features: 0x38

关闭不支持的features:

rbd -p {pool-name} feature disable {image-name} {feature-name} ......

关闭exclusive-lock, object-map, fast-diff, deep-flatten

rbd -p rbd1 feature disable image01 exclusive-lock, object-map, fast-diff, deep-flatten

映射:

[root@client ~]# rbd map rbd1/image01
/dev/rbd0

查看一下本地的块设备:

[root@client ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  150G  0 disk
├─sda1   8:1    0    4G  0 part [SWAP]
└─sda2   8:2    0  146G  0 part /
sr0     11:0    1 1024M  0 rom
rbd0   253:0    0   20G  0 disk

这个/dev/rbd0就跟本地的块设备一样,可以格式化,然后挂载。

[root@client ~]# mkfs.xfs /dev/rbd0
meta-data=/dev/rbd0              isize=512    agcount=16, agsize=327680 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=5242880, imaxpct=25
         =                       sunit=1024   swidth=1024 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
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

[root@client ~]# mount /dev/rbd0 /mnt
[root@client ~]#
[root@client ~]# df -Th
文件系统       类型      容量  已用  可用 已用% 挂载点
/dev/sda2      xfs       146G  3.4G  143G    3% /
devtmpfs       devtmpfs  990M     0  990M    0% /dev
tmpfs          tmpfs    1000M     0 1000M    0% /dev/shm
tmpfs          tmpfs    1000M  8.9M  991M    1% /run
tmpfs          tmpfs    1000M     0 1000M    0% /sys/fs/cgroup
tmpfs          tmpfs     200M     0  200M    0% /run/user/0
/dev/rbd0      xfs        20G   33M   20G    1% /mnt

在客户端操作这个块设备的I/O时,ceph status 可以看到一些信息:

io:
    client:   4.0 KiB/s rd, 0 B/s wr, 3 op/s rd, 2 op/s wr
取消映射
rbd unmap {pool-name}/{image-name}
[root@client /]# umount mnt
[root@client /]# rbd unmap rbd1/image01

也可以直接unmap本地的块设备: rbd unmap /dev/rbd1

取消映射以后再重新映射就不需要格式化了, 因为这个快设备已经格式化过了。

修改快大小
rbd resize --size 2048 foo (to increase)
rbd resize --size 2048 foo --allow-shrink (to decrease)

在缩小快设备的时候必须加上--allow-shrink,不然报错,就像一种确认吧。

[root@cephnode1 ~]# rbd -p rbd1 resize --size 30G image01
Resizing image: 100% complete...done.

[root@cephnode1 ~]# rbd -p rbd1 resize --size 20G image01 --allow-shrink
Resizing image: 100% complete...done.

再映射以后就会变成30G了。在已经映射并且挂载的情况下,块大小也可以修改,只是客户端系统显示的还是之前的大小。


如果客户端挂载了块设备,然后关机了, 通常情况下,系统会卡主。 而且也为了安全,一般的使用可能会由systemd管理,关机的时候取消映射并卸载, 开机了在映射块,然后挂载。


四、快照、克隆

快照

https://docs.ceph.com/docs/master/rbd/rbd-snapshot
快照大家都知道。
只是需要注意一下,如果块设备正在使用,在创建快照时,客户端最好停止I/O的使用,不然可能会导致文件系统故障,需要使用fsck修复。

  • 可以使用fsfreeze命令。
  • 虚拟机,可以使用qemu-guest-agent冻结文件系统。
    image.png

使用fsfreeze以后文件系统会变成只读状态。使用fsfreeze --unfreeze /mnt恢复`

[root@client /]# fsfreeze --freeze /mnt
[root@client /]# cd /mnt
[root@client mnt]# touch 2
^C^C^C^C

创建快照
rbd snap create {pool-name}/{image-name}@{snap-name}
[root@cephnode1 ~]# rbd snap create rbd1/image01@image01-snap01
列出快照清单
rbd snap ls {pool-name}/{image-name}
[root@cephnode1 ~]# rbd snap ls rbd1/image01
SNAPID NAME           SIZE   PROTECTED TIMESTAMP
     6 image01-snap01 20 GiB           Thu Mar 19 09:25:39 2020

查看所有块信息:

[root@cephnode1 ~]# rbd -l ls rbd1
NAME                   SIZE   PARENT FMT PROT LOCK
image01                20 GiB          2
image01@image01-snap01 20 GiB          2

查看详细信息:

[root@cephnode1 ~]# rbd info rbd1/image01@image01-snap01
rbd image 'image01':
	size 20 GiB in 5120 objects
	order 22 (4 MiB objects)
	snapshot_count: 1
	id: af697b1fd4a0
	block_name_prefix: rbd_data.af697b1fd4a0
	format: 2
	features: layering
	op_features:
	flags:
	create_timestamp: Tue Mar 17 17:39:09 2020
	access_timestamp: Tue Mar 17 17:39:09 2020
	modify_timestamp: Tue Mar 17 17:39:09 2020
	protected: False
回滚快照
rbd snap rollback {pool-name}/{image-name}@{snap-name}

在回滚之前,需要把已经挂载的取消挂载 不然会与本地已经挂载的文件系统产生冲突。出现这种情况:

[root@client /]# umount /mnt
[root@client /]# mount /dev/rbd0 /mnt
mount: 文件系统类型错误、选项错误、/dev/rbd0 上有坏超级块、
       缺少代码页或助手程序,或其他错误

       有些情况下在 syslog 中可以找到一些有用信息- 请尝试
       dmesg | tail  这样的命令看看。

要么就使用工具修复文件系统,但是可能丢失数据。要么重新回滚快照。

[root@cephnode1 ~]# rbd snap rollback rbd1/image01@image01-snap01
Rolling back to snapshot: 100% complete...done.
[root@cephnode1 ~]#

注意: 将映像回滚到快照意味着用快照中的数据覆盖映像的当前版本。执行回滚所需的时间随映像的大小而增加。

删除快照
rbd snap rm {pool-name}/{image-name}@{snap-name}
[root@cephnode1 ~]# rbd snap rm rbd1/image01@image01-snap01
Removing snap: 100% complete...done.

删除块设备对应的所有快照

rbd snap purge {pool-name}/{image-name}
[root@cephnode1 ~]# rbd snap purge rbd1/image01
Removing all snapshots: 100% complete...done.

克隆

克隆一般用于对虚拟机的系统模板做克隆。
ceph支持写时复制的克隆功能,就是类似于vmware的链接克隆。把快照作为基础,而不是整个复制出来一份。ceph仅支持对格式id为2的块设备做克隆。
image.png

快照作为只读层,叫做Parent
克隆出来的读写层,叫做Child。 每个克隆出来的映像(Child),都保存着对Parent的引用。

保护快照

因为所有克隆出来的映像都是基于快照, 如果快照被删除,所有映像都会失效。
为了防止这种情况,克隆之前,必须对快照添加保护。

rbd snap protect {pool-name}/{image-name}@{snapshot-name}
[root@cephnode1 ~]# rbd snap protect rbd1/image01@image01-snap01
[root@cephnode1 ~]# rbd snap rm rbd1/image01@image01-snap01
Removing snap: 2020-03-19 10:11:35.529 7f4342129b00 -1 librbd::Operations: snapshot is protected0
% complete...failed.
rbd: snapshot 'image01-snap01' is protected from removal.
创建克隆
rbd clone {pool-name}/{parent-image}@{snap-name} {pool-name}/{child-image-name}

这里创建了两个克隆,一个是其他pool里的, 一个是本pool里的。

[root@cephnode1 ~]# rbd clone rbd1/image01@image01-snap01 rbd2/rbd1-image01-clone01

[root@cephnode1 ~]# rbd clone rbd1/image01@image01-snap01 rbd1/rbd1-image01-clone02

因为可以克隆到另一个pool里, 所以可以在一个pool里专门放用于克隆的快照。

列出快照的Child

也就是所有克隆出去的。

rbd children {pool-name}/{image-name}@{snapshot-name}
[root@cephnode1 ~]# rbd children rbd1/image01@image01-snap01
rbd1/rbd1-image01-clone02
rbd2/rbd1-image01-clone01
展平克隆的映像

就是把引用的快照完整复制到克隆里,也就相当于vmware的完整克隆。 之后就可以删除快照了。

rbd flatten {pool-name}/{image-name}

这里的pool-nameimage-name都是克隆出去的映像。

[root@cephnode1 ~]# rbd flatten rbd1/rbd1-image01-clone02
Image flatten: 100% complete...done.
[root@cephnode1 ~]# rbd flatten rbd2/rbd1-image01-clone01
Image flatten: 100% complete...done.
取消快照保护

快照必须取消保护以后才能删除,并且不能有任何克隆还在依赖这个快照。

rbd snap unprotect {pool-name}/{image-name}@{snapshot-name}
[root@cephnode1 ~]# rbd snap unprotect rbd1/image01@image01-snap01
[root@cephnode1 ~]# rbd snap rm rbd1/image01@image01-snap01
Removing snap: 100% complete...done.

导出导入映像

导出
rbd export {pool-name}/{image-name} {dst-path}
[root@cephnode1 ~]# rbd export rbd1/image01 /root/image01
Exporting image: 100% complete...done.
导入
[root@cephnode1 ~]# rbd import /root/image01 rbd2/image09 --image-format 2
Importing image: 100% complete...done.
[root@cephnode1 ~]# rbd ls rbd2
image01
image02
image09
rbd1-image01-clone01
[root@cephnode1 ~]#