OSD与Pool池的常见操作及管理

OSD与Pool池的常见操作及管理

查看osd状态

ceph -s

通过ceph -s可以查看集群的概况,其中包括了部分osd相关的健康信息。

ceph-s-osd-down-1-2020-07-26

ceph osd stat

ceph osd stat可以验证当前集群内的状态。

1
2
[ceph@servera ~]$ ceph osd stat
9 osds: 9 up, 9 in

当前集群内共有9个OSD,目前这9个OSD的状态均为OK!

ceph osd tree

ceph osd tree 显示所有的OSD列表

ceph-osd-tree-1-2020-10-23

在ID列,可以看到每一个OSD的ID均为正数,并且每个OSD的ID顺序是打乱、分散的。3台机器共9个OSD的ID被随机分配了。

值得注意的点是所有的主机和集群也被进行了ID编号,只不过它们的编号为负数。

ceph osd df

如果要查看每个OSD的使用情况以及数据所占用OSD空间的百分比,可以使用ceph osd df命令查看。

ceph-osd-df-1-2020-07-26

删除Pool

ceph osd pool delete rbd rbd --yes-i-really-really-mean-it

想要删除一个Pool你需要按照上面的格式进行确认,但是即便是一再确认,默认情况下MON节点还是不允许你删除Pool池。会提示Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

那么有下面两种方式可以删除Pool:

修改MON配置文件

修改配置文件,在配置文件中标记允许删除Pool,这样在重启集群所有的MON节点后会重新读取到这条配置文件,在删除Pool的时候不会进行阻拦。

vim /etc/ceph/ceph.conf

所有的MON节点下的配置文件中添加下面的配置:

1
2
[mon]
mon allow pool delete = true

修改后保存设置,重启集群内所有的MON节点服务

之后执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉。

这种方式要登录到所有的MON节点机器中修改配置,并且需要重启MON节点服务,如果你是单节点集群或者对集群的稳定性有严格需求,这种方式不太友好。

使用ceph tell运行时注入配置

Ceph支持运行时注入配置,那么可以进行下面的操作:

ceph tell mon.* injectargs --mon_allow_pool_delete true

之后会看到输出:

1
2
3
4
5
6
mon.vm1: {}
mon.vm2: {}
mon.vm3: {}
mon.vm1: mon_allow_pool_delete = 'true'
mon.vm2: mon_allow_pool_delete = 'true'
mon.vm3: mon_allow_pool_delete = 'true'

此时执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉刚才不能删除的Pool。

Pool池

Pool是一个抽象的存储池,它是PG之上的一层逻辑。它规定了数据冗余的类型以及对应的副本分布策略。

目前有两种pool类型:replicated类型和Erasure Code类型。

  • 一个pool由多个PG构成,一个PG只能属于一个Pool
  • 同一个Pool中的PG具有相同的类型,比如,如Pool为副本类型,则Pool中所有的PG都是多副本的

注意:在ceph 12.2.1(luminous)版本中,目前还不支持缩减PG、PGP数量,但是可以增加它们的数量,这适用于OSD存储节点的扩容,但是却不利于缩减OSD存储节点……
不过在

创建副本Pool

使用副本Pool时,每个对象都会被复制到n个osd上进行存储。复制几份由pool的size属性决定,默认情况下会有3个副本,在生产环境下应该至少存在3个副本才可以保证数据可靠性。

ceph osd pool create <poolname> <int[0-]> {<int[0-]>} {replicated|erasure} {<erasure_code_profile>} {<rule>} {<int>}

现在来创建一个名字叫rbd的Pool,使用默认的replicated模式创建并且默认的副本数量为3,将它的PG和PGP数量设置为64。

ceph osd pool create rbd 64 64

创建纠删码Pool

使用纠删码Pool可以减少副本的磁盘占用并且能与副本Pool得到同等的数据保护效果。它可以减少集群为了保护数据而而外付出的存储开销。

不过使用纠删码虽然与副本类型相比会减少很多存储空间,但是需要对数据进行较多的运算。在回复数据时会占用大量的计算资源如CPU、内存。

创建一个名字为reapool的PG、PGP数为50的纠删码类型Pool:

ceph osd pool create reapool 50 50 erasure

纠删码由配置定义,在创建纠删码存储池及其相关的 CRUSH 规则时用到。

创建 Ceph 集群时初始化的、名为 default 的纠删码配置可提供与两副本相同的冗余水平,却能节省 25% 的磁盘空间。在此配置中 k=2 和 m=1 ,其含义为数据分布于 3 个 OSD ( k+m==3 )且允许一个失效。

为了在不增加原始存储空间需求的前提下提升冗余性,你可以新建配置。例如,一个 k=10 且 m=4 的配置可容忍 4 个 OSD 失效,它会把一对象分布到 14 个( k+m=14 ) OSD 上。此对象先被分割为 10 块(若对象为 10MB ,那每块就是 1MB )、并计算出 4 个用于恢复的编码块(各编码块尺寸等于数据块,即 1MB );这样,原始空间仅多占用 10% 就可容忍 4 个 OSD 同时失效、且不丢失数据。

详见修改纠删码副本及冗余数量

管理和操作Pool

为Pool设置应用

在创建一个pool之后,你应该把这个pool分配一个application对这个pool进行标记。可以设置的应用有cephfsrbdrgw

ceph osd pool application enable <poolname> <app>

现在将刚刚创建名字为rbd这个Pool设置为用于rbd应用。

ceph osd pool application enable rbd rbd

在没有设置应用之前,使用ceph -s查看集群状态可能会有警告提示。设置之后再次查询,警告消失。

ceph -sceph health detail

通过eph osd pool application get rbd命令查看application发现已激活rbd应用在这个pool上。

1
2
3
4
[ceph@servera ~]$ ceph osd pool application get rbd
{
"rbd": {}
}

查看Pool信息

查看集群内的Pool

ceph osd lspools

1
2
[ceph@servera ~]$ ceph osd lspools
7 rbd,8 testpool,

ceph osd pool ls

1
2
3
[ceph@servera ~]$ ceph osd pool ls
rbd
testpool

查看集群内Pool的资源使用情况

ceph df

1
2
3
4
5
6
7
8
9
[ceph@servera ~]$ ceph df
GLOBAL:
SIZE AVAIL RAW USED %RAW USED
170G 169G 1071M 0.61
POOLS:
NAME ID USED %USED MAX AVAIL OBJECTS
rbd 7 0 0 82552M 0
testpool 8 0 0 82552M 0

查看每个OSD资源使用情况

ceph osd df

1
2
3
4
5
6
7
8
9
10
11
12
13
[ceph@servera ~]$ ceph osd df
ID CLASS WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR PGS
0 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 197
3 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 213
8 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 204
2 hdd 0.01849 1.00000 19444M 127M 19317M 0.66 1.08 206
4 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 185
6 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 205
1 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 181
5 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 200
7 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 209
TOTAL 170G 1068M 169G 0.61
MIN/MAX VAR: 0.99/1.08 STDDEV: 0.02

查看Pool当前执行的任务,可以使用ceph osd pool stats来查看Pool当前正在执行的任务和写入、读取速度。

1
2
3
4
5
6
[ceph@servera ~]$ ceph osd pool stats
pool rbd id 7
nothing is going on

pool testpool id 8
nothing is going on

重命名Pool

你可以使用ceph osd pool rename命令重新命名你不满意的名字。

osd pool rename <current_poolname> <new_poolname>

对Pool进行快照

你可以创建或者删除一个Pool的快照。

ceph osd pool mksnap/rmsnap <poolname> <snap>

对当前的rbdPool进行创建快照操作:

ceph osd pool mksnap rbd rbd@snap-20200721

查看该Pool中创建的Pool快照:

rados lssnap -p rbd

1
2
3
[ceph@servera ~]$ rados lssnap -p rbd
1 rbd@snap-20200721 2020.07.21 15:26:39
1 snaps

删除刚刚创建的快照:

ceph osd pool rmsnap rbd rbd@snap-20200721

还原快照:

rados -p <poolname> rollback <obj-name> <snap-name>

rados -p <poolname> -s <snap-name> get <obj-name> file

Ceph支持两种类型的快照,一种是pool snaps,也就是Pool级别的快照,是给整个pool中的对象整体做一个快照。另一个是self managed snaps,rbd使用的就是这种类型的快照。
要注意的是:这两种快照类型是互斥的,不能同时存在。如果你要是用Pool快照那么默认情况下就不能在这个Pool下创建RBD了。

更改Pool参数

对Pool进行调整可以设置副本数、纠删码份数,还可以限制该Pool所使用的资源大小等。

ceph osd pool set <poolname> <parameter> <value>

限制Pool所用资源数量

管理员可以对Pool设置限额(quotas)来限制最大使用的存储量和对象(object)数量。

ceph osd pool set-quota <poolname> max_objects|max_bytes <val>

限制rbdPool最大仅能使用1GB存储空间:

ceph osd pool set-quota rbd max_bytes 1073741824

更改副本数/纠删码个数

修改副本数

在实际生产环境中副本数通常在3个或以上。默认的副本数是两个,不过保险起见生产环境下应越多越保险。

ceph osd pool set rbd size 3

修改纠删码副本及冗余数量

使用纠删码创建的Pool可以配置纠删码算法及相应规则,你可以自己新建一个纠删码规则适用于当前的业务需求。

和副本模式相比纠缠码可以大幅减少存储成本,但当集群内的其他OSD遇到数据盘损坏时会重新计算丢失的数据。这会对计算资源和网络资源造成较大的负担!

合理的配置纠删码文件可以带来更好的效率。

使用ceph osd erasure-code-profile get default查看创建一个纠删码模式的Pool时默认的的配置信息。

1
2
3
4
k=2
m=1
plugin=jerasure
technique=reed_sol_van
  • k 对对象分割的数量,k=2为默认值。对一个对象分割成两部分。
  • m 纠删码数量,默认m=1。假如k=2时,一个对象文件被分割成了两份存在了不同的OSD上,此时有一个OSD坏掉了的话通过纠删码就可以计算出坏掉的那个OSD磁盘中的数据。

创建一个新的纠删码配置

1
2
3
4
5
6
ceph osd erasure-code-profile set {name} \
[{directory=directory}] \
[{plugin=plugin}] \
[{stripe_unit=stripe_unit}] \
[{key=value} ...] \
[--force]
  • directory 设置纠删码插件的路径,需是目录。
  • plugin 指定纠删码插件来计算编码块、及恢复丢失块。
  • stripe_unit 每一个条带中、一个数据块的数据量。例如,在一个配置中,数据块为 2 且 stripe_unit=4K ,数据进来时会把 0-4K 放入块 0 , 4K-8K 放入块 1 ;然后 8K-12K 又是块 0 。为实现最佳性能,这里应该设置成 4K 的倍数。默认值是在存储池创建时从监视器配置选项 osd_pool_erasure_code_stripe_unit 获取的。一个使用着这个配置的存储池,其 stripe_width 值(条带宽度)就是数据块的数量乘以这里的 stripe_unit 值。
  • key 纠删码插件所定义的键/值对含义。

创建一个k=6,m=3的纠删码配置文件:

ceph osd erasure-code-profile set test k=6 m=3

查看test纠删码配置信息

ceph osd erasure-code-profile get test

1
2
3
4
5
6
7
8
9
10
[ceph@servera ~]$ ceph osd erasure-code-profile get test
crush-device-class=
crush-failure-domain=host
crush-root=default
jerasure-per-chunk-alignment=false
k=6
m=3
plugin=jerasure
technique=reed_sol_van
w=8

创建一个新的纠删码类型Pool并使用刚刚创建的test纠删码配置进行创建。

ceph osd pool create erasurepool 10 10 erasure test

查看Pool信息

ceph osd pool ls detail

pool 12 'erasurepool' erasure size 9 min_size 7 crush_rule 2 object_hash rjenkins pg_num 10 pgp_num 10 last_change 618 flags hashpspool stripe_width 24576

删除Pool

ceph osd pool delete rbd rbd --yes-i-really-really-mean-it

想要删除一个Pool你需要按照上面的格式进行确认,但是即便是一再确认,默认情况下MON节点还是不允许你删除Pool池。会提示Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

那么有下面两种方式可以删除Pool:

修改MON配置文件

修改配置文件,在配置文件中标记允许删除Pool,这样在重启集群所有的MON节点后会重新读取到这条配置文件,在删除Pool的时候不会进行阻拦。

vim /etc/ceph/ceph.conf

所有的MON节点下的配置文件中添加下面的配置:

1
2
[mon]
mon allow pool delete = true

修改后保存设置,重启集群内所有的MON节点服务

之后执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉。

这种方式要登录到所有的MON节点机器中修改配置,并且需要重启MON节点服务,如果你是单节点集群或者对集群的稳定性有严格需求,这种方式不太友好。

使用ceph tell运行时注入配置

Ceph支持运行时注入配置,那么可以进行下面的操作:

ceph tell mon.* injectargs --mon_allow_pool_delete true

之后会看到输出:

1
2
3
4
5
6
mon.vm1: {}
mon.vm2: {}
mon.vm3: {}
mon.vm1: mon_allow_pool_delete = 'true'
mon.vm2: mon_allow_pool_delete = 'true'
mon.vm3: mon_allow_pool_delete = 'true'

此时执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉刚才不能删除的Pool。

Pool命名空间

命名空间是Pool池的逻辑组。可以设置一个命名空间限制个个用户能访问到该Pool的范围,限制用户只访问到该Pool的部分范围。当然也可以按照不同应用应用的方式进行分组。

要存储一个对象到命名空间时客户端需要指明Pool和命名空间。

默认情况下每个Pool包括一个孔明成的命名空间作为默认的命名空间使用。

放置对象到命名空间

使用rados命令可以将Object对象放置在Pool上的指定命名空间内。

rados -p <poolname> [-N <namespace>] put <obj-name> [infile] [--offset offset]

rados -p rbd -N system put release /etc/redhat-release

上面这个命令是将/etc/redhat-release这个文件放在了rbd存储池的system命名空间里,并且文件名为release

列出命名空间内的对象

rados -p <poolname> [-N <namespace>] ls [--all]

列出rbd存储池中system命名空间下的对象:

rados -p rbd -N system ls

返回列表如下,返回的这些object都是属于system这个命名空间下的对象。

1
2
services-name
release

不过,在不指明命名空间的情况下,只能看得到默认命名空间里的对象,如果要显示出该Pool内全部命名空间的对象的话如何操作?

rados -p rbd ls --all

1
2
3
system  services-name
system release
release

这样就可以显示出全部命名空间里的对象名称了,那么没有名字的release对象就是存放在默认的命名空间下。

还可以以JSON的格式进行输出:

rados -p rbd ls --all --format=json | python -m json.tool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@servera ~]$ rados -p rbd ls --all --format=json | python -m json.tool
[
{
"name": "services-name",
"namespace": "system"
},
{
"name": "release",
"namespace": "system"
},
{
"name": "release",
"namespace": ""
}
]