> 文章列表 > Ceph运维操作

Ceph运维操作

Ceph运维操作

1. 操控集群

1.1 UPSTART

Ubuntu系统下,基于ceph-deploy部署集群后,可以用这种方法来操控集群。

列出节点上所有Ceph进程:

initctl list | grep ceph

启动节点上所有Ceph进程:

start ceph-all

启动节点上特定类型的Ceph进程:

sudo start ceph-osd-all
sudo start ceph-mon-all
sudo start ceph-mds-all

停止特定类型的Ceph进程的某个实例:

sudo start ceph-osd id={id}
sudo start ceph-mon id={hostname}
sudo start ceph-mds id={hostname}

停止特定类型的Ceph进程的某个实例:

sudo stop ceph-osd id={id}
sudo stop ceph-mon id={hostname}
sudo stop ceph-mds id={hostname}

1.2 SYSVINIT

在 CentOS 、 Redhat 、 Fedora 和 SLES 发行版上可以通过传统的 sysvinit 运行 Ceph , Debian/Ubuntu 的较老的版本也可以用此方法。

命令格式:

# 启动、重启或停止
sudo /etc/init.d/ceph [options] [start|restart|stop] [daemonType|daemonID]# 示例:# -a 表示在所有节点执行
sudo /etc/init.d/ceph -a start
sudo /etc/init.d/ceph -a stop
sudo /etc/init.d/ceph start osd
sudo /etc/init.d/ceph -a stop osd
sudo /etc/init.d/ceph start osd.0
sudo /etc/init.d/ceph stop osd.0 

2. 监控集群

2.1 检查集群状态

执行 ceph status或则 ceph **-**s可以查看集群的状态:

  1. active+clean:说明集群健康运行

  2. undersized+degraded:如果有OSD节点宕机,可能进入此状态。降级后还是可以正常读写数据

  3. undersized+degraded+peered:如果超过min size要求的OSD宕机,则不可读写,显示为此状态。min size默认2,副本份数默认3。执行下面的命令可以修改min size:

    ceph osd pool set rbd min_size 1
    

    peered相当于已经配对(PG - OSDs),但是正在等待OSD上线

  4. remapped+backfilling:默认情况下,OSD宕机5分钟后会被标记为out状态,Ceph认为它已经不属于集群了。Ceph会按照一定的规则,将已经out的OSD上的PG重映射到其它OSD,并且从现存的副本来回填(Backfilling)数据到新OSD

执行 ceph health可以查看简短的健康状态。

执行 ceph **-**w可以持续的监控发生在集群中的各种事件。

2.2 检查存储用量

执行命令 ceph df可以查看集群的数据用量及其在存储池内的分布情况:

GLOBAL:# 已用存储空间总量(包括所有副本)SIZE     AVAIL     RAW USED     %RAW USED 323G      318G        4966M          1.50 # 这一段显示的数值,不包含副本、克隆、快照的用量
POOLS:# 大概使用率              # 大概对象数NAME     ID     USED      %USED     MAX AVAIL     OBJECTS rbd      1      3539M      1.14          300G        1018 

2.3 检查MON状态

# 基本信息
ceph mon stat
# 详细信息
ceph mon dump
# 法定人数状态、monmap内容
ceph quorum_status -f json-pretty

2.4 检查MDS状态

ceph mds stat
ceph mds dump

2.5 检查OSD状态

通过PG这个中间层,Ceph确保了数据不会被绑死在某个特定的OSD。要追踪错误根源,你需要检查归置组、以及底层的OSD。

执行下面的命令,获取最简短的OSD状态:

ceph osd stat
# 输出
12 osds: 12 up, 12 in 

执行 ceph osd dump则可以获得详细信息,包括在CRUSH map中的权重、UUID、是in还是out:

osd.0 up   out weight 0 up_from 70 up_thru 172 down_at 65 last_clean_interval [51,60) 10.5.39.13:6800/48 10.5.39.13:6801/48 10.5.39.13:6802/48 10.5.39.13:6803/48 exists,up 354a6547-3437-46d6-a928-f5633eb7f059
osd.1 up   in  weight 1 up_from 74 up_thru 327 down_at 63 last_clean_interval [55,60) 10.5.39.42:6800/48 10.5.39.42:6801/48 10.5.39.42:6802/48 10.5.39.42:6803/48 exists,up 0fb4bb77-7c84-45ac-919a-2cc350fc62b9

执行 ceph osd tree可以在OSD树中打印各OSD的位置、状态、权重。如果OSD的in数量大于up数量,可以通过此命令快速定位:

# 仅仅包含out的OSD
ceph osd tree out
# ID CLASS WEIGHT  TYPE NAME               STATUS REWEIGHT PRI-AFF 
# -1       4.89999 root default                                
# -2             0     host k8s-10-5-38-25                     
#  2   hdd       0         osd.2              DNE        0 

2.6 检查PG状态

执行命令 ceph pg stat可以查看全局性的PG统计信息。

可以获取PG列表:

# 输出的第一列为PG ID
ceph pg dump
# 导出为JSON
ceph pg dump -o {filename} --format=json

执行下面的命令可以查看PG到OSD的映射关系:

# PG ID 格式为 存储池号.归置组ID,归置组ID为一个十六进制数字
ceph pg map 1.13d
# 输出
osdmap e790 pg 1.13d (1.13d) -> up [4,6,5] acting [4,6,5]

执行 ceph status也可以看到PG的统计性信息。

执行 ceph pg 1.13d query可以查看某个PG的非常细节的信息。

3. 操控MON

3.1 增加

MONID=Neon
MONADDR=10.0.3.1:6789# 创建目录
mkdir /var/lib/ceph/mon/ceph-$MONID# 获取密钥和monmap
ceph auth get mon. -o /tmp/keyring
ceph mon getmap -o /tmp/monmap# 初始化Mon
sudo ceph-mon -i $MONID --mkfs --monmap /tmp/monmap --keyring /tmp/keyring# 启动Mon
ceph-mon -i $MONID --public-addr $MONADDR

3.2 删除

ceph mon rm Xenon 

3.3 monmap

导出monmap:

ceph mon getmap -o monmap

打印monmap的内容:

monmaptool --print monmap

从monmap中删除一个MON:

monmaptool  monmap --rm xenon

添加一个MON到monmap中:

monmaptool  monmap --add Xenon 10.0.5.1:6789

导入monmap到MON节点:

ceph-mon -i Xenon --inject-monmap monmap 

4. 操控OSD

4.1 增加

# 空间使用率达到 near full 比率后, OSD 失败可能导致集群空间占满。因此,你需要提前扩容
# 执行下面的命令创建一个新的OSD,其OSD号会输出到控制台:# uuid、id可选,如果不指定则自动生成。不能和现有OSD的uuid、id重复。不建议手工指定id
ceph osd create [{uuid} [{id}]]# 如果希望OSD使用独立磁盘或者分区,可以先创建好文件系统,再挂载到适当位置
sudo mkfs -t {fstype} /dev/{drive}
# 示例
mkfs -t xfs -f /dev/sda3
# 挂载点
mkdir /var/lib/ceph/osd/ceph-{osd-num}
# 挂载
mount /dev/sda3 /var/lib/ceph/osd/ceph-14# 初始化OSD数据目录:
ceph-osd -i {osd-num} --mkfs --mkkey# 注册OSD认证密钥:
ceph auth add osd.{osd-num} osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/${cluster-name}-{osd-num}/keyring
# 示例
ceph auth add osd.14 osd 'allow *' mon 'allow rwx' -i /var/lib/ceph/osd/ceph-14/keyring# 你需要把OSD加入到CRUSH map,这样数据才会分配到此OSD上: 
# 把OSD加入到CRUSH树的适当位置(桶)
# 如果指定了不止一个桶,则将OSD加入到最靠近叶子节点的桶中,并把此桶移动到你指定的其它桶中
# 如果你指定了root桶,则此OSD直接挂在root下,则是不建议的,CRUSH规则期望OSD位于主机这种桶类型的下级节点
ceph osd crush add {id-or-name} {weight}  [{bucket-type}={bucket-name} ...]
# 示例
ceph osd crush add 14 0.11589
# 如果设置osd_crush_update_on_start=true,则可以OSD启动后自动加入到CRUSH树并更新权重
# 警告,如果上述参数设置为false,且你没有将osd添加到适当位置,则osd可能无法承载PG

4.2 查询

ceph osd find 14
{"osd": 14,"ip": "10.0.1.1:6804/3146","crush_location": {"host": "Carbon","root": "default"}
} 

4.3 启动

一旦启动了 OSD ,其状态就变成了 up+in ,此时可以通过ceph -w来观察数据迁移。归置组状态会变为active, some degraded objects,最终变回active+clean

# Debian/Ubuntu 上用 Upstart:
start ceph-osd id={osd-num}
# CentOS/RHEL 上用 sysvinit:
/etc/init.d/ceph start osd.{osd-num}
# 基于systemd的系统
systemctl start ceph-osd@14.service 

4.4 删除

删除OSD之前,应该评估集群容量,保证操作之后,集群不会到达 near full 比率

# 首先从CRUSH map中移除
ceph osd crush remove {name}
# 删除其认证密钥
ceph auth del osd.{osd-num}
# 删除OSD
ceph osd rm {osd-num}

4.5 标记为宕机

ceph osd down {osd-num}

4.6 标记为踢出

踢出OSD后,Ceph会进行数据迁移,达到再平衡。归置组状态会变为active, some degraded objects,最终变回active+clean。

ceph osd out {osd-num}

对于某些小型测试集群,踢出一个OSD即导致CRUSH进入临界状态,某些归置组一直卡在active+remapped状态。如果遇到这种情况,你可以:

# 把被踢出的集群重新加进来
ceph osd in {osd-num}
# 将其权重标记为0,而非踢出
ceph osd crush reweight osd.{osd-num} 0 

等待数据迁移完毕后,再将OSD踢出。

4.7 标记为进入

你可能需要更新CRUSH map才能让新进入的OSD接受数据:

ceph osd in {osd-num}

4.8 标记为丢失

标记OSD为lost,可能导致数据丢失,谨慎:

ceph osd lost {id} [--yes-i-really-mean-it]

4.9 设置权重

# 权重默认是以TB为单位
ceph osd reweight {osd-num} {weight} 

4.10 清理OSD

ceph osd scrub {osd-num}
# 清理所有
ceph osd scrub all

4.11 深度清理OSD

ceph osd deep-scrub all 

4.12 修复OSD

ceph osd repair N

4.13 测试OSD性能

ceph tell osd.N bench [TOTAL_DATA_BYTES] [BYTES_PER_WRITE]

4.14 空间不足处理

Ceph不允许向满的 OSD 写入数据,以免丢失数据。在运营着的集群中,你应该能收到集群空间将满的警告。mon osd full ratio 默认为 0.95 ,也就是说达到 95% 时它将阻止客户端写入数据; mon osd backfillfull ratio 默认为 0.90 ,也就是说达到容量的 90% 时它会阻塞,防止回填启动; OSD 将满比率默认为 0.85 ,也就是说达到容量的 85% 时它会产生健康警告。

使用下面的命令临时修改设置,否则你可能没有机会清理不需要的RBD以腾出空间:

ceph osd set-nearfull-ratio 0.95
ceph osd set-full-ratio 0.99
ceph osd set-backfillfull-ratio 0.99

5. 操控MDS

5.1 增加

首先,在/var/lib/ceph/mds/mds.N创建一个数据挂载点。N是MDS的ID,通常就是主机名。

然后,修改Ceph配置,添加一个mds段。修改完毕后进行配置分发:

[mds.N]
host = {hostname}

如果启用了CephX,需要创建认证密钥:

sudo ceph auth get-or-create mds.N mon 'profile mds' mgr 'profile mds' mds 'allow *' osd 'allow *' > \\/var/lib/ceph/mds/ceph-N/keyring

5.2 移除

执行下面的命令将目标mds标记为宕机:

ceph mds fail <mds name>

移除MDS的/var/lib/ceph/mds/ceph-NAME下对应目录,然后,删除/etc/systemd/system/ceph-mds.target.wants/下的对应项目:

systemctl stop ceph-mds@Neon.service
systemctl disable ceph-mds@Neon.service
rm -rf /var/lib/ceph/mds/ceph-Neon 

如果服务是通过/etc/init.d/ceph加载的,则:

service ceph stop
update-rc.d ceph disable

5.3 状态

查看守护进程的简短状态:

ceph mds stat

5.4 启动

service ceph start mds.NAME

5.5 引用守护进程

你可以使用多种方式来引用一个MDS守护进程:

ceph mds fail 5446     # 基于GID
ceph mds fail myhost   # 基于名称
ceph mds fail 3:0      # 基于FSCID:rank
ceph mds fail myfs:0   # 基于文件系统名称:rank

5.6 管理故障转移

和MDS进程的Standby行为相关的配置项包括:

# 如果设置为true则standby会持续的从Rank中读取元数据日志,从而维持一个有效的元数据缓存,这可以加速Failover
mds_standby_replay = true
# 仅仅作为具有指定名称的MDS的Standby
mds_standby_for_name = Carbon
# 仅仅作为指定Rank的Standby
mds_standby_for_rank
# 仅仅作为指定文件系统的Standby
mds_standby_for_fscid

如果不进行任何配置,没有持有Rank的那些MDS进程,可以作为任何Rank的Standby。

配置示例:

# a、b两个MDS互备,负责Rank 0
[mds.a]
mds standby replay = true
mds standby for rank = 0[mds.b]
mds standby replay = true
mds standby for rank = 0

5.7 修改配置

ceph tell mds.{mds-id} config set {setting} {value}
# 示例
ceph tell mds.0 config set debug_ms 1

5.8 启用诊断信息

ceph mds stat

5.9 手工故障转移

标记当前活动MDS为失败,触发故障转移:

ceph mds fail 0 

6. 操控CephFS

6.1 创建

要创建一个文件系统,你至少需要两个存储池,一个存放数据,另外一个存放元数据。注意:

  1. 元数据池的副本份数要设置的高,因为任何元数据的丢失都会导致整个文件系统不可用
  2. 元数据池应该使用高速存储,例如SSD,因为这对客户端操作的延迟有直接影响

示例:

# ceph fs new <fs_name> <metadata> <data>
# 示例,可以使用现有的存储池
ceph fs new cephfs rbd-ssd rbd-hdd# Error EINVAL: pool 'rbd-ssd' already contains some objects. Use an empty pool instead.
# 出现上述错误,可以:
ceph fs new cephfs rbd-ssd rbd-hdd --force

创建了文件系统之后,在Luminous版本中,集群状态中显示:

mds: cephfs-1/1/1 up  {0=Carbon=up:active}

6.2 列出

ceph fs ls

6.3 状态

查看CephFS的详细状态,包括MDS列表、Rank列表等:

ceph fs status

6.4 删除

ceph fs rm <filesystem name> [--yes-i-really-mean-it]

6.5 关闭

mds set <fs_name> down true

6.6 查看选项

要获取某个文件系统的信息,可以:

ceph fs get cephfs

6.7 设置选项

fs set <filesystem name> <var> <val># 示例
# 设置单个文件的大小,默认1TB
fs set cephfs max_file_size 1099511627776

6.8 增减数据池

fs add_data_pool <filesystem name> <pool name/id>
fs rm_data_pool <filesystem name> <pool name/id>

6.9 设为默认

如果集群中有多个文件系统,而客户端在挂载时没有明确指定使用哪个,则使用默认文件系统:

ceph fs set-default cephfs

6.10 使用EC池

EC池可以作为Ceph的数据池,但是需要启用overwirte:

ceph osd pool set my_ec_pool allow_ec_overwrites true

注意:EC池不能用来存储元数据。

6.11 配额

CephFS支持对任何一个子目录进行配额。但是,需要注意以下限制:

  1. 需要客户端协作,因此被篡改过的客户端可以突破配额
  2. 配额不是非常精确的
  3. 内核客户端,仅仅在4.17+才支持配额。用户空间客户端fuse、libcephfs都支持配额

设置配额(设置为0则移除配额):

setfattr -n ceph.quota.max_bytes -v 100000000 /some/dir     # 按字节数
setfattr -n ceph.quota.max_files -v 10000 /some/dir         # 按文件数

查看配额:

getfattr -n ceph.quota.max_bytes /some/dir
getfattr -n ceph.quota.max_files /some/dir 

7. 挂载CephFS

7.1 内核驱动

你可以直接使用Linux内核提供的驱动来挂载CephFS:

mkdir /mnt/cephfs
mount -t ceph 10.0.1.1:6789:/ /mnt/cephfs

如何启用了CephX,需要指定访问密钥,否则会报22错误:

mount -t ceph 10.0.1.1:6789:/ /mnt/cephfs -o name=admin,secret=AQDRNBZbCp3WMBAAynSCCFPtILwHeI3RLDADKA==
# 或者指定包含密钥的文件
mount -t ceph 10.0.1.1:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret

如果报can’t read superblock,说明客户端内核不支持。

要实现自动挂载,你需要修改fstab:

{ipaddress}:{port}:/ {mountpoint} {fs-type} [name=username,secret=key|secretfile=file],[{mount.options}]# 示例
10.0.1.1:6789:/ /mnt/cephfs  ceph name=admin,secretfile=/etc/ceph/cephfs.key,noatime,_netdev    0       2

7.2 FUSE

要在用户空间挂载CephFS,你需要:

  1. 将Ceph配置文件拷贝到客户端,命名为/etc/ceph/ceph.conf

  2. 将Keyring拷贝到客户端,命名为/etc/ceph/ceph.keyring:

    sudo scp -i ~/Documents/puTTY/gmem.key root@xenon.gmem.cc:/etc/ceph/ceph.client.admin.keyring /etc/ceph/ceph.keyring 
  3. 执行挂载:

    sudo ceph-fuse -m 10.0.1.1:6789 /mnt/cephfs
    # ceph-fuse[847]: starting ceph client                                                                                                                                             
    # 2018-06-07 19:18:25.503086 7fa5c44e1000 -1 init, newargv = 0x7fa5cd643b40 newargc=9                                                                                              
    # ceph-fuse[847]: starting fuse  
    

如果有多个CephFS,你可以为ceph-fuse指定命令行选项–client_mds_namespace,或者在客户端的ceph.conf中添加client_mds_namespace配置。

要实现自动挂载,你需要修改fstab:

none    /mnt/ceph  fuse.ceph ceph.id={user-ID}[,ceph.conf={path/to/conf.conf}],_netdev,defaults  0 0# 示例
none    /mnt/ceph  fuse.ceph ceph.id=admin,_netdev,defaults  0 0
none    /mnt/ceph  fuse.ceph ceph.id=admin,ceph.conf=/etc/ceph/ceph.conf,_netdev,defaults  0 0 

8. 操控存储池

8.1 设置默认参数

# 设置新建存储池时使用的默认参数
osd pool default pg num = 128
osd pool default pgp num = 128

8.2 运行时修改参数

ceph osd pool set {pool-name} option-name num
# 示例
ceph osd pool set  .rgw.root pg_num 128
ceph osd pool set  .rgw.root pgp_num 128 

8.3 创建存储池

# 创建存储池
# crush-ruleset-name:使用的默认CRUSH规则集名称
# 复制型的默认规则集由选项osd pool default crush replicated ruleset控制
# 
ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] \\[crush-ruleset-name] [expected-num-objects]
ceph osd pool create {pool-name} {pg-num}  {pgp-num}   erasure \\[erasure-code-profile] [crush-ruleset-name] [expected_num_objects]# 示例
ceph osd pool create rbd-ssd 384 replicated replicated_rule_ssd

8.4 初始化存储池

创建存储池之后,在管理节点上,使用rbd工具来初始化池:

rbd pool init <pool-name>

8.5 读写存储池配置

# 修改存储池配置
ceph osd pool set {pool-name} {key} {value}
# 读取存储池配置
ceph osd pool get {pool-name} {key}

8.6 列出存储池

ceph osd lspools
# 输出
# 1 rbd,3 rbd-ssd,4 rbd-hdd,

8.7 列出存储池中的对象

# 列出存储池中的对象
rados -p rbd ls

8.8 存储池用量

# 显示所有存储池的使用情况
rados df# 或者
ceph df# 更多细节
ceph df detail
# USED       %USED       MAX AVAIL     OBJECTS     DIRTY     READ      WRITE      RAW USED 
# 用量       用量百分比                对象数量              读速度    写数量     用量x副本份数

8.9 存储池配额

# 设置最大对象数量、最大字节数
ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}]
# 示例:
ceph osd pool set-quota data max_objects 10000

要取消配额,设置为0即可。

8.10 存储池快照

# 制作存储池快照
ceph osd pool mksnap {pool-name} {snap-name}
# 删除存储池快照
ceph osd pool rmsnap {pool-name} {snap-name}

8.11 删除存储池

# 删除存储池
ceph osd pool delete {pool-name} [{pool-name} --yes-i-really-really-mean-it]# 示例
ceph osd pool rm rbd-ssd rbd-ssd --yes-i-really-really-mean-it
ceph osd pool rm rbd-hdd rbd-hdd --yes-i-really-really-mean-it

8.12 清空缓存池

# 列出池中对象,逐个删除
for i in `rados -p rbd-ssd ls`; do echo $i; rados -p rbd-ssd rm $i; done

9. 操控镜像

镜像就是块设备,所谓块是一系列连续的字节序列(例如512KB)。基于块的存储接口,是磁盘、CD、软盘、甚至磁带都使用的,是存储对象最广泛使用的方式。

Ceph的块设备具有以下特点:thin-provisioned(精简配备)、可改变大小、跨越多OSD存储。

9.1 列出镜像

rbd ls {poolname}

如果不指定池名称,则列出默认池中的镜像。

下面的命令可以列出池中延迟删除的镜像:

rbd trash ls {poolname} 

9.2 查看镜像磁盘占用

rbd du --pool rbd-ssd

注意:rbd info输出的是thin provisioning的大小,不是实际磁盘空间占用。

除了上面的命令,还可以:

rbd diff k8s/kubernetes-dynamic-pvc | awk '{ SUM += $2 } END { print SUM/1024/1024 " MB" }' 

9.3 查看镜像信息

rbd info {pool-name}/{image-name}
rbd info {image-name}# 输出示例:
rbd image 'kubernetes-dynamic-pvc-0783b011-6a04-11e8-a266-3e299ab03dc6':# 总大小(thin-provisioning的大小,不是实际占用磁盘大小),分布在多少个对象中size 2048 MB in 512 objectsorder 22 (4096 kB objects)block_name_prefix: rbd_data.7655b643c9869format: 2features: layeringflags:create_timestamp: Thu Jun  7 11:36:58 2018

9.4 查看镜像状态

可以看到什么客户端在使用(watch)镜像:

rbd status k8s/kubernetes-dynamic-pvc-ca081cd3-01a0-11eb-99eb-ce0c4cdcd662
# Watchers:
#         watcher=192.168.106.18:0/756489925 client.254697953 cookie=18446462598732840981 

9.5 创建镜像

rbd create --size {megabytes} {pool-name}/{image-name}
# 示例
# 创建大小为1G的镜像
rbd create test --size 1G

如果不指定存储池,则在默认池中创建镜像。

9.6 修改镜像大小

# 修改镜像大小
rbd --image test resize --size 2G
# 不但可以扩大,还可以缩小
rbd --image test resize --size 1G --allow-shrink

9.7 映射为块设备

# 将镜像映射为本地块设备,可以进行格式化、挂载
rbd map test
# 格式化
mkfs.xfs -f /dev/rbd0
# 挂载
mount /dev/rbd0 /test# 显示映射到本地块设备的镜像
rbd showmapped# 卸载
umount /dev/rbd0
# 解除映射
rbd unmap /dev/rbd0

9.8 删除镜像

rbd rm {pool-name}/{image-name}rbd --image test rm

9.9 延迟删除

# 放入回收站
rbd trash mv {pool-name}/{image-name}
# 彻底删除
rbd trash rm {pool-name}/{image-id}
# 还原
rbd trash restore {image-id}

9.10 快照管理

# 创建快照
rbd snap create --image test --snap test_snap
# 列出镜像的所有快照
rbd snap ls --image test# 回滚到指定快照
rbd snap rollback --image test --snap test_snap
# 另一种写法
rbd snap rollback rbd/test@test_snap# 删除快照,注意删除是异步进行的,空间不会立刻释放
rbd snap rm --image test --snap test_snap
rbd snap purge --image test# 保护快照
rbd snap protect --image test --snap test_snap
# 取消保护
rbd snap unprotect --image test --snap test_snap# 清除指定镜像的所有快照
rbd snap purge {pool-name}/{image-name}

9.11 镜像克隆

# 克隆镜像,注意只有镜像格式2才支持克隆
# 从快照创建克隆
rbd clone --image test --snap test_snap test_clone
# 列出快照的所有克隆
rbd children --image test --snap test_snap
# 将父镜像(被克隆的镜像的快照)的数据扁平化到子镜像,从而解除父子关联
rbd flatten --image test_clone

10. 镜像镜像

从Jewel开始,RBD镜像可以异步的跨越两个集群进行镜像(Mirroring)。通过配置,你可以镜像池中的所有、或者一部分镜像。

10.1 启用镜像复制

rbd mirror pool enable {pool-name} {mode}# 启用名为local的集群的镜像复制,默认为pool
rbd --cluster local mirror pool enable image-pool pool
rbd --cluster remote mirror pool enable image-pool pool

mode取值:

  1. pool,池中所有启用了journaling特性的镜像都被复制
  2. image,只有明确配置的镜像才进行复制

10.2 禁用镜像复制

rbd mirror pool disable {pool-name}rbd --cluster local mirror pool disable image-pool
rbd --cluster remote mirror pool disable image-pool

11. 操控对象

11.1 创建对象

# 在池中创建一个对象,其内容来自文件
echo "Hello World" > /tmp/file
rados -p rbd put helloworld /tmp/file

11.2 查看对象

 查看对象
rados -p rbd ls | grep helloworld

12. 操控CRUSH

 # 根据CRUSH Map,列出OSD树
ceph osd tree
#                 缩进显示树层次
# ID  CLASS WEIGHT  TYPE NAME               STATUS REWEIGHT PRI-AFF 
#  -1       5.73999 root default                            
#  -2       0.84000     host k8s-10-5-38-25                 
#   0   hdd 0.84000         osd.0               up  1.00000 1.00000 
#  -5       0.45000     host k8s-10-5-38-70                 
#   1   hdd 0.45000         osd.1               up  1.00000 1.00000 # 移动桶的位置
# 将rack01移动到{root=default} 
ceph osd crush move rack01 root=default

13. 操控PG

13.1 镜像和PG对应关系

# 显示镜像和PG的关系
ceph osd map rbd  test
#                                                 此镜像存放在1.b5这个PG中
#                                                        此PG位于 osd.3 osd.1 osd.6中
#                                                                      主副本 位于osd.3中
# osdmap e26 pool 'rbd' (1) object 'test' -> pg 1.40e8aab5 (1.b5) -> up ([3,1,6], p3) acting ([3,1,6], p3)# 显示PG和镜像的关系
ceph pg map 1.c0
# osdmap e1885 pg 1.c0 (1.c0) -> up [9,8] acting [9,8]

13.2 Dump出PG统计信息

Dump出所有PG:

pg dump {all|summary|sum|delta|pools|osds|pgs|pgs_brief [all|summary|sum|delta|pools|osds|pgs|pgs_brief...]}
# 示例
ceph pg dump [--format {format}]  # format取值plain或json

Dump出卡在指定状态中的PG的统计信息:

# threshold默认30秒
ceph pg dump_stuck inactive|unclean|stale|undersized|degraded [--format {format}] [-t|--threshold {seconds}]

13.3 修复PG

ceph pg repair 1.c0
# instructing pg 1.c0 on osd.9 to repair

13.4 优先回填或修复

ceph pg force-backfill <pgid> [<pgid>...]  
ceph pg force-recovery <pgid> [<pgid>...] 
# 取消
ceph pg cancel-force-backfill <pgid> [<pgid>...]
ceph pg cancel-force-recovery <pgid> [<pgid>...]

14. 调整PG数量

14.1 计算PG合理值

参考官网的算法进行计算。

14.2 确保集群健康

执行调整之前,必须保证集群处于健康状态。

14.3 调整数据同步参数

为避免调整PG数量导致业务性能受到严重影响,应该调整一些参数:

ceph tell osd.* injectargs '--osd-max-backfills 1'
ceph tell osd.* injectargs '--osd-recovery-max-active 1'

其它相关的参数还包括:

 osd_backfill_scan_min = 4 
osd_backfill_scan_max = 32 
osd recovery threads = 1 
osd recovery op priority = 1 

14.4 调整PG数量

按照2的幂进行翻倍增长,例如原来32个,可以先调整为64个。注意:不要一下子把PG设置为太大的值,这会导致大规模的rebalance,影响系统性能。

14.5 调整PGP数量

等到上一步操作后,集群变为Active+Clean状态后,再将pgp_num设置的和pg_num一致。 

15. 操控RGW

15.1 手工安装

# 在RGW节点安装软件
# yum install ceph-radosgwRGW_HOST=$(hostname -s)# 在RGW节点,配置ceph.conf
cat << EOF >> /etc/ceph/ceph.conf
[client.rgw.$RGW_HOST]
rgw_frontends = "civetweb port=7480"
EOF# 拷贝配置到所有Ceph节点# 在RGW节点,创建数据目录
mkdir -p /var/lib/ceph/radosgw/ceph-rgw.$RGW_HOST# 在RGW节点,创建用户,输出Keyring
ceph auth get-or-create client.rgw.$RGW_HOST osd 'allow rwx' mon 'allow rw' \\-o /var/lib/ceph/radosgw/ceph-rgw.$RGW_HOST/keyring
chown -R ceph:ceph /var/lib/ceph/radosgw# 在RGW节点,启用Systemd服务
systemctl enable ceph-radosgw.target
systemctl enable ceph-radosgw@rgw.$RGW_HOST
systemctl start ceph-radosgw@rgw.$RGW_HOST

15.2 修改端口

[client.rgw.Carbon]
rgw_frontends = "civetweb port=80"

推送修改后的配置文件后,重启RGW服务:

systemctl restart ceph-radosgw.service

15.3 启用ssl

[client.rgw.Carbon]
# 指定包含了私钥和证书的PEM
rgw_frontends = civetweb port=443s ssl_certificate=/etc/ceph/private/keyandcert.pem
# Luminous开始,可以同时绑定SSL和非SSL端口
rgw_frontends = civetweb port=80+443s ssl_certificate=/etc/ceph/private/keyandcert.pem

15.4 配置桶分片

RGW在index_pool池中存放桶(Bucket)索引数据,此池默认名为.rgw.buckets.index。

从0.94版本开始,支持对桶索引进行分片,避免单个桶中对象数量过多时出现性能瓶颈:

# 每个桶的最大索引分片数,默认0,表示不支持分片
rgw_override_bucket_index_max_shards = 0

你可以在global段配置上面的选项。

15.5 启用用户

要使用RGW的RESTful接口,你需要:

  1. 创建初始的S3接口的用户
  2. 创建Swift接口的子用户
  3. 验证用户可以访问网关

要创建S3接口用户,需要在网关机上执行:

radosgw-admin user create --uid="rgw" --display-name="rgw"

access_key、secret_key会打印在屏幕上,要访问网关,客户端必须提供这两个key:

{"user_id": "rgw","display_name": "rgw","email": "","suspended": 0,"max_buckets": 1000,"auid": 0,"subusers": [],"keys": [{"user": "rgw","access_key": "IN01UCU1M1996LK6OM88","secret_key": "AuuAbroSUlWLykbQHCbFLVO6RU2ozUEjIFkYeoqc"}],"swift_keys": [],"caps": [],"op_mask": "read, write, delete","default_placement": "","placement_tags": [],"bucket_quota": {"enabled": false,"check_on_raw": false,"max_size": -1,"max_size_kb": 0,"max_objects": -1},"user_quota": {"enabled": false,"check_on_raw": false,"max_size": -1,"max_size_kb": 0,"max_objects": -1},"temp_url_keys": [],"type": "rgw"
}

要创建Swift子用户,需要在网关机上执行:

radosgw-admin subuser create --uid=alex --subuser=alex:swift --access=full

你需要为Swift子用户创建secret key:

radosgw-admin key create --subuser=alex:swift --key-type=swift --gen-secret

现在,你可以用自己熟悉的语言的S3、Swift客户端来验证用户是否可用。

15.6 操控桶

radosgw-admin bucket list                # 列出桶
radosgw-admin bucket limit check         # 显示桶的分片情况
radosgw-admin bucket link                # 将桶链接到用户
radosgw-admin bucket unlink              # 取消桶到用户的链接
radosgw-admin bucket stats               # 显示桶的统计信息
radosgw-admin bucket rm                  # 删除桶
radosgw-admin bucket check               # 检查桶索引
radosgw-admin bucket reshard             # 对桶进行重分片
radosgw-admin bucket sync disable        # 禁止桶同步
radosgw-admin bucket sync enable         # 启用桶同步

要创建桶,你需要使用合法的User ID + AWS Access Key发起请求,Ceph没有提供对应的命令行。需要注意以下约束:

  1. 桶名称必须唯一
  2. 桶名称不能格式化为IP地址
  3. 桶名称在3-63字符之间
  4. 桶名称不得包含大写字母、下划线,但是可以包含短横线
  5. 桶名称必须以小写字母或数字开头
  6. 桶名称必须由一系列的标签组成,每个标签用点号.分隔

我们可以使用MinIO客户端创建桶:

# 添加配置
#                                               access_key           secret_key
mc config host add rgw https://rgw.gmem.cc:7480 IN01UCU1M1996LK6OM88 AuuAbroSUlWLykbQHCbFLVO6RU2ozUEjIFkYeoqc# 创建桶
mc mb rgw/test

现在通过Rgw命令行可以看到这个桶:

radosgw-admin buckets list
# [
#     "test"
# ]

16. 管理身份验证

Ceph默认开启了cephx协议,加密认证需要消耗少量的资源。

启用cephx后,Cephe会自动在包括/etc/ceph/ceph.$name.keyring在内的位置寻找钥匙串,你可以指定keyring选项来修改默认路径,但是不推荐

16.1 手工启用

在禁用了cephx的集群上,启用它的步骤为:

  1. 创建 client.admin 密钥:
    # 如果你使用的自动部署工具已经生成此文件,切勿执行此命令,会覆盖
    ceph auth get-or-create client.admin mon 'allow *' mds 'allow *' osd 'allow *' -o /etc/ceph/ceph
    
  2. 创建mon集群所需的钥匙串、密钥:
    ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'
    
  3. 将上述钥匙串复制到所有mon的mon data目录,例如:
    cp /tmp/ceph.mon.keyring /var/lib/ceph/mon/ceph-a/keyring
    
  4. 为每个OSD生成密钥:
    ceph auth get-or-create osd.{$id} mon 'allow rwx' osd 'allow *' -o /var/lib/ceph/osd/ceph-{$id}/keyring
    
  5. 为每个 MDS 生成密钥:
    ceph auth get-or-create mds.{$id} mon 'allow rwx' osd 'allow *' mds 'allow *' -o /var/lib/ceph/mds/ceph-{$id}/keyring
    
  6. 添加以下内容到配置文件的global段:
    auth cluster required = cephx
    auth service required = cephx
    auth client required = cephx
    
  7. 启动或重启Ceph集群:
     # 停止当前节点上的所有Ceph守护进程
    sudo stop ceph-all
    sudo start ceph-all
    

16.2 禁用认证

修改配置文件global段:

auth cluster required = none
auth service required = none
auth client required = none

然后重启Ceph集群。

16.3 身份验证命令

# 列出keyring
ceph auth ls
# 添加OSD的keyring
ceph auth add {osd} {--in-file|-i} {path-to-osd-keyring}

17. 管理CRUSH map

17.1 手工管理

任何时后你都可以Dump、反编译、修改、编译、注入CURSH map。如果要完全基于手工方式管理,不使用自动生成的CRUSH map,可以设置:

osd crush update on start = false

17.2 查看Dump

执行命令 ceph osd crush dump,可以将整个CRUSH导出为可读形式:

# 下面的输出时安装后最初的状态,没有任何OSD{   # 设备列表,最初为空                                                                                                                                                                   "devices": [],   # 桶类型定义列表                                                                                                                                                           "types": [                                                                                                                                                                       {                                                                                                                                                                            "type_id": 0,                                                                                                                                                            "name": "osd"                                                                                                                                                            },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 1,                                                                                                                                                            "name": "host"                                                                                                                                                           },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 2,                                                                                                                                                            "name": "chassis"                                                                                                                                                        },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 3,                                                                                                                                                            "name": "rack"                                                                                                                                                           },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 4,                                                                                                                                                            "name": "row"                                                                                                                                                            },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 5,                                                                                                                                                            "name": "pdu"                                                                                                                                                            },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 6,                                                                                                                                                            "name": "pod"                                                                                                                                                            },                                                                                                                                                                           {                                                                                                                                                                            "type_id": 7,                                                                                                                                                            "name": "room"                                                                                                                                                           },{"type_id": 8,"name": "datacenter"},{"type_id": 9,"name": "region"},{"type_id": 10,"name": "root"}],# 桶列表,可以形成树状结构"buckets": [{"id": -1,"name": "default","type_id": 10,"type_name": "root","weight": 0,"alg": "straw2","hash": "rjenkins1","items": []}# 加入一个OSD节点(基于目录),自动生成如下两个Bucket:{                                                                                                                                                                      "id": -2,                                                                                                                                                          "name": "k8s-10-5-38-25",                                                                                                                                          "type_id": 1,                                                                                                                                                      "type_name": "host",                                                                                                                                               "weight": 55050,                                                                                                                                                   "alg": "straw2",                                                                                                                                                   "hash": "rjenkins1",                                                                                                                                               "items": [                                                                                                                                                         {                                                                                                                                                              "id": 0,                                                                                                                                                   "weight": 55050,                                                                                                                                           "pos": 0                                                                                                                                                   }                                                                                                                                                              ]                                                                                                                                                                  },                                                                                                                                                                     {                                                                                                                                                                      "id": -3,                                                                                                                                                          "name": "k8s-10-5-38-25~hdd",                                                                                                                                      "type_id": 1,                                                                                                                                                      "type_name": "host",                                                                                                                                               "weight": 55050,                                                                                                                                                   "alg": "straw2",                                                                                                                                                   "hash": "rjenkins1",                                                                                                                                               "items": [                                                                                                                                                         {"id": 0,"weight": 55050,"pos": 0}]},],# 规则列表"rules": [{"rule_id": 0,"rule_name": "replicated_rule",# 所属规则集"ruleset": 0,# 此规则是否用于RAID,取值replicated 或 raid4"type": 1,# 如果Pool的副本份数不在此范围内,则CRUSH不会使用当前规则"min_size": 1,"max_size": 10,"steps": [{# 选择一个桶,并迭代其子树"op": "take","item": -1,"item_name": "default"},{# 在上一步的基础上,确定每个副本如何放置"op": "chooseleaf_firstn",# 取值0,此Step适用pool-num-replicas个副本(所有)# 取值>0 & < pool-num-replicas,适用num个副本# 取值<0,适用pool-num-replicas -num个副本"num": 0,"type": "host"},{"op": "emit"}]}],# 可微调参数,以及一些状态信息"tunables": {                                                                                                                                                                    "choose_local_tries": 0,                                                                                                                                                     "choose_local_fallback_tries": 0,                                                                                                                                            "choose_total_tries": 50,                                                                                                                                                    "chooseleaf_descend_once": 1,                                                                                                                                                "chooseleaf_vary_r": 1,                                                                                                                                                      "chooseleaf_stable": 1,                                                                                                                                                      "straw_calc_version": 1,                                                                                                                                                     "allowed_bucket_algs": 54,  # 使用的Profile,执行ceph osd crush tunables hammer后此字段改变,连带其它tunables字段自动改变                                                                                                                                               "profile": "jewel",                                                                                                                                                          "optimal_tunables": 1,                                                                                                                                                       "legacy_tunables": 0,                                                                                                                                                        "minimum_required_version": "jewel",                                                                                                                                         "require_feature_tunables": 1,                                                                                                                                               "require_feature_tunables2": 1,                                                                                                                                              "has_v2_rules": 0,                                                                                                                                                           "require_feature_tunables3": 1,                                                                                                                                              "has_v3_rules": 0,                                                                                                                                                           "has_v4_buckets": 1,                                                                                                                                                         "require_feature_tunables5": 1,"has_v5_rules": 0},"choose_args": {}
}

17.3 编辑Dump

执行下面的命令,导出当前Map:

ceph osd getcrushmap -o curshmap

然后,需要反编译为文本:

crushtool -d curshmap -o curshmap.src

源文件内容示例:

# begin crush map
tunable choose_local_tries 0
tunable choose_local_fallback_tries 0
tunable choose_total_tries 50
tunable chooseleaf_descend_once 1
tunable chooseleaf_vary_r 1
tunable straw_calc_version 1
tunable allowed_bucket_algs 54# devices# types
type 0 osd
type 1 host
type 2 chassis
type 3 rack
type 4 row
type 5 pdu
type 6 pod
type 7 room
type 8 datacenter
type 9 region.Values.storageclass.fsType
type 10 root# buckets
root default {id -1           # do not change unnecessarily# weight 0.000alg straw2       hash 0  # rjenkins1
}
# rules
rule replicated_rule {id 0type replicatedmin_size 1max_size 10step take defaultstep chooseleaf firstn 0 type hoststep emit
}# end crush map

我们可以根据实际需要,对源文件进行修改,例如将算法改为straw,解决CentOS 7上CEPH_FEATURE_CRUSH_V4 1000000000000特性不满足的问题:

sed -i 's/straw2/straw/g' curshmap.src

修改源文件完毕后,执行下面的命令编译:

crushtool -c curshmap.src -o curshmap

最后,注入最新编译的Map:

 ceph osd setcrushmap -i curshmap
# 会输出修订版号 

17.4 修改设备类型

默认情况下,Ceph自动根据硬件类型,设置OSD的设备类型为hdd, ssd或nvme。你可以手工进行设置:

# 你需要移除当前设置的设备类型,才能重新设置
ceph osd crush rm-device-class <osd-name> [...]
# 示例
ceph osd crush rm-device-class osd.3 osd.4 osd.5 osd.6 osd.7 osd.8 osd.0 osd.10 osd.1 osd.12 osd.2 osd.13 ceph osd crush set-device-class <class> <osd-name> [...]
# 示例
ceph osd crush set-device-class ssd osd.3 osd.4 osd.5 osd.6 osd.7 osd.8 osd.0 osd.10 osd.1 osd.12 osd.2 osd.13 

17.5 查看规则

列出集群中的CRUSH rule:

ceph osd crush rule ls

Dump出规则的内容:

ceph osd crush rule dump

17.6 删除规则

ceph osd crush rule rm replicated_rule_ssd

17.7 创建规则

创建一个规则,仅仅使用指定类型的设备:

ceph osd crush rule create-replicated <rule-name> <root> <failure-domain> <class>
# 示例:仅仅使用ssd类型的设备,失败域为host,也就是数据副本必须位于不同的主机上
ceph osd crush rule create-replicated replicated_rule_ssd default host ssd
ceph osd crush rule create-replicated replicated_rule_hdd default host hdd

17.8 应用规则

为存储池指定所使用的规则:

ceph osd pool set <pool-name> crush_rule <rule-name>
# 修改规则
ceph osd pool set rbd-ssd crush_rule replicated_rule_ssd
# 创建存储池时指定规则
ceph osd pool create rbd-ssd 384 replicated replicated_rule_ssd

17.9 编辑规则

CRUSH rule的语法如下:

 rule <rulename> {ruleset <ruleset>type [ replicated | erasure ]min_size <min-size>max_size <max-size># 根据桶名称来选取CRUSH子树,并迭代,可限定设备类型step take <bucket-name> [class <device-class>]# choose:选择指定数量、类型的桶# chooseleaf:选择指定数量、类型的桶,并选择每个这些桶的一个叶子节点step [choose|chooseleaf] [firstn|indep] <N> <bucket-type>step emit
}

示例一,将主副本存放在SSD中,第二副本存放在HDD中:

rule ssd-primary-affinity {ruleset 0type replicatedmin_size 2max_size 3# 选择名为SSD的桶step take ssd# 在上述桶中的host类型的子树中选择叶子节点,存储1个副本(第一个)step chooseleaf firstn 1 type host# 执行step emit# 选择名为HDD的桶step take hdd# 在上述桶中的host类型的子树中选择叶子节点,存储N-1个副本(所有其它副本)step chooseleaf firstn -1 type hoststep emit
}

示例二,在第一个机架上存储两个副本,第二个机架上存储一个副本:

 rule 3_rep_2_racks {ruleset 1type replicatedmin_size 2max_size 3step take default# 选择一个Rack,存储2个副本step choose firstn 2 type rack# 在上述选定的Rack中选择Hoststep chooseleaf firstn 2 type hoststep emit
}

17.10 增加OSD

如果要添加OSD到CRUSH map中,执行:

ceph osd crush set {name} {weight} root={root} [{bucket-type}={bucket-name} ...]
# 示例
ceph osd crush set osd.14 0 host=xenial-100
ceph osd crush set osd.0 1.0 root=default datacenter=dc1 room=room1 row=foo rack=bar host=foo-bar-1

17.11 调整OSD权重

ceph osd crush reweight {name} {weight}

17.12 移除OSD

ceph osd crush remove {name}

17.13 增加Bucket

ceph osd crush add-bucket {bucket-name} {bucket-type}

17.14 移动Bucket

ceph osd crush move {bucket-name} {bucket-type}={bucket-name}, [...]

17.15 移除Bucket

ceph osd crush remove {bucket-name} 

17.16 调整Tunable

# 自动优化
ceph osd crush tunables optimal
# 最大兼容性,存在老旧内核的cephfs/rbd客户端时
ceph osd crush tunables legacy# 选择一个PROFILE,例如jewel
ceph osd crush tunables {PROFILE} 

17.17 避免作为主OSD

# weight在0-1之间,默认1,值越小,CRUSH 越避免将目标OSD作为主
ceph osd primary-affinity <osd-id> <weight>

17.18 分配Pool到特定OSD

使用CRUSH rule,可以限定某个Pool仅仅使用一部分OSD:

# SSD主机
host ceph-osd-ssd-server-1 {id -1alg strawhash 0item osd.0 weight 1.00item osd.1 weight 1.00
}# HDD主机
host ceph-osd-hdd-server-1 {id -3alg strawhash 0item osd.4 weight 1.00item osd.5 weight 1.00
}# HDD的根桶
root hdd {id -5alg strawhash 0item ceph-osd-hdd-server-1 weight 2.00
}# SSD的根桶
root ssd {id -6alg strawhash 0item ceph-osd-ssd-server-1 weight 2.00
}# 仅仅使用HDD的规则
rule hdd {ruleset 3type replicatedmin_size 0max_size 10step take hdd# 选择step chooseleaf firstn 0 type hoststep emit
}# 仅仅使用SSD的规则
rule ssd {ruleset 4type replicatedmin_size 0max_size 4step take ssdstep chooseleaf firstn 0 type hoststep emit
}# 在SSD上存储主副本,其它副本存放在HDD
rule ssd-primary {ruleset 5type replicatedmin_size 5max_size 10step take ssdstep chooseleaf firstn 1 type hoststep emitstep take hddstep chooseleaf firstn -1 type hoststep emit
}

18. 修改日志尺寸

前提条件:

  1. 集群处于OK状态
  2. 所有PG处于active+clean状态

步骤,针对每个需要改变尺寸的OSD,一个个的处理:

  1. 修改Cephe配置,设置 osd_journal_size = NEWSIZE

  2. 禁止数据迁移(防止OSD进入out状态): ceph osd set noout

  3. 停止目标OSD实例

  4. 刷出缓存: ceph-osd **-**i OSDID **–flush-**journal

  5. 删除日志:

     # 基于Helm部署时,需要到宿主机上的osd_directory下寻找对应目录
    cd /var/lib/ceph/osd/ceph-osd.OSDID
    rm journal 
    
  6. 创建一个新的日志文件: ceph-osd **–**mkjournal **-**i OSDID

  7. 启动OSD

  8. 验证新的日志尺寸被使用:

    # Helm安装的情况下,需要在OSD容器中执行
    ceph --admin-daemon /var/run/ceph/ceph-osd.OSDID.asok config get osd_journal_size
    
  9. 确保集群处于OK状态,所有PG处于active+clean状态

    处理完所有OSD后,执行:  ceph osd unset noout,清除noout标记
    

19. 性能测试

19.1 rbd bench

# 默认4K,可以--io-size定制
# 默认16线程,可以--io-threads定制# 随机读
rbd bench -p rbd-hdd --image benchmark --io-total 128M --io-type read --io-pattern rand
# elapsed: 25 ops:  32768 ops/sec:  1284.01  bytes/sec: 5259316.53
# elapsed: 15 ops: 327680 ops/sec: 20891.46  bytes/sec: 85571410.91
# HDD差20倍# 顺序读
rbd bench -p rbd-hdd --image benchmark --io-total 64M --io-type read --io-pattern seq
# elapsed: 46 ops:  163840 ops/sec:   3528.06  bytes/sec: 14450938.87
# elapsed: 45 ops: 1638400 ops/sec:   35672.87 bytes/sec: 146116057.32
# HDD差10倍# 随机写
rbd bench -p rbd-hdd --image benchmark --io-total 128M --io-type write --io-pattern rand
# elapsed: 85  ops:  32768 ops/sec: 383.24  bytes/sec: 1569743.22
# elapsed: 111 ops: 327680 ops/sec: 2936.78 bytes/sec: 12029055.24
# HDD差7倍# 顺序写
rbd bench -p rbd-hdd --image benchmark --io-total 128M --io-type write --io-pattern seq
# elapsed: 3  ops: 32768  ops/sec:  9382.16 bytes/sec: 38429334.91
# elapsed: 17 ops: 327680 ops/sec: 18374.69 bytes/sec: 75262749.05
# HDD差1倍

20. 运行时修改参数

要动态、临时(重启后消失)的修改组件的参数,可以使用tell命令。

20.1 控制恢复进程

# 临时修改所有OSD和恢复相关的选项
ceph tell osd.* injectargs '--osd-max-backfills 1'             # 并发回填操作数
ceph tell osd.* injectargs '--osd-recovery-threads 1'          # 恢复线程数量
ceph tell osd.* injectargs '--osd-recovery-op-priority 1'      # 恢复线程优先级  
ceph tell osd.* injectargs '--osd-client-op-priority 63'       # 客户端线程优先级
ceph tell osd.* injectargs '--osd-recovery-max-active 1'       # 最大活跃的恢复请求数 

21. 管理Watcher

21.1 加入黑名单

可以将RBD上的Watcher加入黑名单,这样可以解除RBD的Watcher,再其它机器上挂载RBD:

rbd status  kubernetes-dynamic-pvc-22d9e659-6e31-11e8-92e5-c6b9f35768f0                                                                                           
# Watchers:                                                                                                                                                                      
#         watcher=10.0.3.1:0/158685765 client.3524447 cookie=18446462598732840965# 添加到黑名单
ceph osd blacklist add 10.0.3.1:0/158685765
# blacklisting 10.0.3.1:0/158685765 until 2018-08-21 18:04:31.855791 (3600 sec)rbd status  kubernetes-dynamic-pvc-22d9e659-6e31-11e8-92e5-c6b9f35768f0
# Watchers: none

21.2 显示黑名单

ceph osd blacklist ls
# listed 1 entries
# 10.0.3.1:0/158685765 2018-08-21 18:04:31.855791

21.3 移除黑名单

ceph osd blacklist rm 10.0.3.1:0/158685765

21.4 清空黑名单

ceph osd blacklist clear

22. RADOS管理

22.1 管理池

# 列出池
rados lspools
.rgw.root
default.rgw.control
default.rgw.meta
default.rgw.log
rbd
rbd-ssd
rbd-hdd# 创建池pool-name,使用auid 123,使用crush规则4
mkpool pool-name [123[ 4]] # 复制池的内容
cppool pool-name dest-pool# 移除池
rmpool pool-name pool-name --yes-i-really-really-mean-it# 清空池中对象
purge pool-name --yes-i-really-really-mean-it# 显示每个池的对象数量、空间占用情况
rados df# 列出池中对象
rados ls -p rbd# 将池的所有者设置为auid 123
rados chown 123  -p rbd

22.2 管理快照

# 列出池快照
rados lssnap -p rbd# 创建池快照
rados mksnap snap-name -p rbd# 删除池快照
rados rmsnap mksnap snap-name -p rbd# 从快照中恢复对象
rados rollback <obj-name> <snap-name># 列出对象的快照
rados listsnaps <obj-name>

22.3 读写对象

 # 读对象
rados get object-name /tmp/obj -p rbd# 使用指定的偏移量写对象
rados put object-name /tmp/obj --offset offset# 附加内容到对象
rados append <obj-name> [infile# 截断对象为指定的长度
rados truncate <obj-name> length# 创建对象
rados create <obj-name># 移除对象
rados rm <obj-name> ...[--force-full]# 复制对象
rados cp <obj-name> [target-obj]

22.4 读写对象属性

 # 列出扩展属性
rados listxattr <obj-name>
# 获取扩展属性
rados getxattr <obj-name> attr
# 设置扩展属性
rados setxattr <obj-name> attr val
# 移除扩展属性
rados rmxattr <obj-name> attr# 显示属性
rados stat <obj-name>

22.5 列出不一致PG

rados list-inconsistent-pg pool-name

22.6 列出不一致对象

rados list-inconsistent-obj  40.14  --format=json-pretty

22.7 列出不一致快照

rados list-inconsistent-snapset 40.14 

23. 配置仪表盘

23.1 启用仪表盘

ceph mgr module enable dashboard

23.2 SSL支持配置

# 使用自签名证书
ceph dashboard create-self-signed-cert# 使用外部提供的证书
ceph dashboard set-ssl-certificate -i dashboard.crt
ceph dashboard set-ssl-certificate-key -i dashboard.key# 禁用SSL
ceph config set mgr mgr/dashboard/ssl false

23.3 设置用户

ceph dashboard ac-user-create admin  administrator -i - <<<"pswd"

23.4 管理RGW

# 创建用户
radosgw-admin user create --uid=rgw --display-name=rgw --system# 设置access_key和secret_key
ceph dashboard set-rgw-api-access-key -i - <<< "$(radosgw-admin user info --uid=rgw | jq -r .keys[0].access_key)"
ceph dashboard set-rgw-api-secret-key -i - <<< "$(radosgw-admin user info --uid=rgw | jq -r .keys[0].secret_key)"# 禁用SSL校验
ceph dashboard set-rgw-api-ssl-verify False