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}
在 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
执行 ceph status或则 ceph **-**s可以查看集群的状态:
active+clean:说明集群健康运行
undersized+degraded:如果有OSD节点宕机,可能进入此状态。降级后还是可以正常读写数据
undersized+degraded+peered:如果超过min size要求的OSD宕机,则不可读写,显示为此状态。min size默认2,副本份数默认3。执行下面的命令可以修改min size:
ceph osd pool set rbd min_size 1
peered相当于已经配对(PG - OSDs),但是正在等待OSD上线
remapped+backfilling:默认情况下,OSD宕机5分钟后会被标记为out状态,Ceph认为它已经不属于集群了。Ceph会按照一定的规则,将已经out的OSD上的PG重映射到其它OSD,并且从现存的副本来回填(Backfilling)数据到新OSD
执行 ceph health可以查看简短的健康状态。
执行 ceph **-**w可以持续的监控发生在集群中的各种事件。
执行命令 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
# 基本信息
ceph mon stat
# 详细信息
ceph mon dump
# 法定人数状态、monmap内容
ceph quorum_status -f json-pretty
ceph mds stat
ceph mds dump
通过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
执行命令 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的非常细节的信息。
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
ceph mon rm Xenon
导出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
# 空间使用率达到 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
ceph osd find 14
{
"osd": 14,
"ip": "10.0.1.1:6804/3146",
"crush_location": {
"host": "Carbon",
"root": "default"
}
}
一旦启动了 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 [email protected]
删除OSD之前,应该评估集群容量,保证操作之后,集群不会到达 near full 比率
# 首先从CRUSH map中移除
ceph osd crush remove {name}
# 删除其认证密钥
ceph auth del osd.{osd-num}
# 删除OSD
ceph osd rm {osd-num}
ceph osd down {osd-num}
踢出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踢出。
你可能需要更新CRUSH map才能让新进入的OSD接受数据:
ceph osd in {osd-num}
标记OSD为lost,可能导致数据丢失,谨慎:
ceph osd lost {id} [--yes-i-really-mean-it]
# 权重默认是以TB为单位
ceph osd reweight {osd-num} {weight}
ceph osd scrub {osd-num}
# 清理所有
ceph osd scrub all
ceph osd deep-scrub all
ceph osd repair N
ceph tell osd.N bench [TOTAL_DATA_BYTES] [BYTES_PER_WRITE]
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
首先,在/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
执行下面的命令将目标mds标记为宕机:
ceph mds fail
移除MDS的/var/lib/ceph/mds/ceph-NAME下对应目录,然后,删除/etc/systemd/system/ceph-mds.target.wants/下的对应项目:
systemctl stop [email protected]
systemctl disable [email protected]
rm -rf /var/lib/ceph/mds/ceph-Neon
如果服务是通过/etc/init.d/ceph加载的,则:
service ceph stop
update-rc.d ceph disable
查看守护进程的简短状态:
ceph mds stat
service ceph start mds.NAME
你可以使用多种方式来引用一个MDS守护进程:
ceph mds fail 5446 # 基于GID
ceph mds fail myhost # 基于名称
ceph mds fail 3:0 # 基于FSCID:rank
ceph mds fail myfs:0 # 基于文件系统名称:rank
和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
ceph tell mds.{mds-id} config set {setting} {value}
# 示例
ceph tell mds.0 config set debug_ms 1
ceph mds stat
标记当前活动MDS为失败,触发故障转移:
ceph mds fail 0
要创建一个文件系统,你至少需要两个存储池,一个存放数据,另外一个存放元数据。注意:
示例:
# ceph fs new
# 示例,可以使用现有的存储池
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}
ceph fs ls
查看CephFS的详细状态,包括MDS列表、Rank列表等:
ceph fs status
ceph fs rm [--yes-i-really-mean-it]
mds set down true
要获取某个文件系统的信息,可以:
ceph fs get cephfs
fs set
# 示例
# 设置单个文件的大小,默认1TB
fs set cephfs max_file_size 1099511627776
fs add_data_pool
fs rm_data_pool
如果集群中有多个文件系统,而客户端在挂载时没有明确指定使用哪个,则使用默认文件系统:
ceph fs set-default cephfs
EC池可以作为Ceph的数据池,但是需要启用overwirte:
ceph osd pool set my_ec_pool allow_ec_overwrites true
注意:EC池不能用来存储元数据。
CephFS支持对任何一个子目录进行配额。但是,需要注意以下限制:
设置配额(设置为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
你可以直接使用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
要在用户空间挂载CephFS,你需要:
将Ceph配置文件拷贝到客户端,命名为/etc/ceph/ceph.conf
将Keyring拷贝到客户端,命名为/etc/ceph/ceph.keyring:
sudo scp -i ~/Documents/puTTY/gmem.key [email protected]:/etc/ceph/ceph.client.admin.keyring /etc/ceph/ceph.keyring
执行挂载:
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
# 设置新建存储池时使用的默认参数
osd pool default pg num = 128
osd pool default pgp num = 128
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
# 创建存储池
# 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
创建存储池之后,在管理节点上,使用rbd工具来初始化池:
rbd pool init
# 修改存储池配置
ceph osd pool set {pool-name} {key} {value}
# 读取存储池配置
ceph osd pool get {pool-name} {key}
ceph osd lspools
# 输出
# 1 rbd,3 rbd-ssd,4 rbd-hdd,
# 列出存储池中的对象
rados -p rbd ls
# 显示所有存储池的使用情况
rados df
# 或者
ceph df
# 更多细节
ceph df detail
# USED %USED MAX AVAIL OBJECTS DIRTY READ WRITE RAW USED
# 用量 用量百分比 对象数量 读速度 写数量 用量x副本份数
# 设置最大对象数量、最大字节数
ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}]
# 示例:
ceph osd pool set-quota data max_objects 10000
要取消配额,设置为0即可。
# 制作存储池快照
ceph osd pool mksnap {pool-name} {snap-name}
# 删除存储池快照
ceph osd pool rmsnap {pool-name} {snap-name}
# 删除存储池
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
# 列出池中对象,逐个删除
for i in `rados -p rbd-ssd ls`; do echo $i; rados -p rbd-ssd rm $i; done
镜像就是块设备,所谓块是一系列连续的字节序列(例如512KB)。基于块的存储接口,是磁盘、CD、软盘、甚至磁带都使用的,是存储对象最广泛使用的方式。
Ceph的块设备具有以下特点:thin-provisioned(精简配备)、可改变大小、跨越多OSD存储。
rbd ls {poolname}
如果不指定池名称,则列出默认池中的镜像。
下面的命令可以列出池中延迟删除的镜像:
rbd trash ls {poolname}
rbd du --pool rbd-ssd
注意:rbd info输出的是thin provisioning的大小,不是实际磁盘空间占用。
除了上面的命令,还可以:
rbd diff k8s/kubernetes-dynamic-pvc | awk '{ SUM += $2 } END { print SUM/1024/1024 " MB" }'
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 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.7655b643c9869
format: 2
features: layering
flags:
create_timestamp: Thu Jun 7 11:36:58 2018
可以看到什么客户端在使用(watch)镜像:
rbd status k8s/kubernetes-dynamic-pvc-ca081cd3-01a0-11eb-99eb-ce0c4cdcd662
# Watchers:
# watcher=192.168.106.18:0/756489925 client.254697953 cookie=18446462598732840981
rbd create --size {megabytes} {pool-name}/{image-name}
# 示例
# 创建大小为1G的镜像
rbd create test --size 1G
如果不指定存储池,则在默认池中创建镜像。
# 修改镜像大小
rbd --image test resize --size 2G
# 不但可以扩大,还可以缩小
rbd --image test resize --size 1G --allow-shrink
# 将镜像映射为本地块设备,可以进行格式化、挂载
rbd map test
# 格式化
mkfs.xfs -f /dev/rbd0
# 挂载
mount /dev/rbd0 /test
# 显示映射到本地块设备的镜像
rbd showmapped
# 卸载
umount /dev/rbd0
# 解除映射
rbd unmap /dev/rbd0
rbd rm {pool-name}/{image-name}
rbd --image test rm
# 放入回收站
rbd trash mv {pool-name}/{image-name}
# 彻底删除
rbd trash rm {pool-name}/{image-id}
# 还原
rbd trash restore {image-id}
# 创建快照
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}
# 克隆镜像,注意只有镜像格式2才支持克隆
# 从快照创建克隆
rbd clone --image test --snap test_snap test_clone
# 列出快照的所有克隆
rbd children --image test --snap test_snap
# 将父镜像(被克隆的镜像的快照)的数据扁平化到子镜像,从而解除父子关联
rbd flatten --image test_clone
从Jewel开始,RBD镜像可以异步的跨越两个集群进行镜像(Mirroring)。通过配置,你可以镜像池中的所有、或者一部分镜像。
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取值:
rbd mirror pool disable {pool-name}
rbd --cluster local mirror pool disable image-pool
rbd --cluster remote mirror pool disable image-pool
# 在池中创建一个对象,其内容来自文件
echo "Hello World" > /tmp/file
rados -p rbd put helloworld /tmp/file
查看对象
rados -p rbd ls | grep helloworld
# 根据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
# 显示镜像和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]
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}]
ceph pg repair 1.c0
# instructing pg 1.c0 on osd.9 to repair
ceph pg force-backfill [...]
ceph pg force-recovery [...]
# 取消
ceph pg cancel-force-backfill [...]
ceph pg cancel-force-recovery [...]
参考官网的算法进行计算。
执行调整之前,必须保证集群处于健康状态。
为避免调整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
按照2的幂进行翻倍增长,例如原来32个,可以先调整为64个。
注意:不要一下子把PG设置为太大的值,这会导致大规模的rebalance,影响系统性能。
等到上一步操作后,集群变为Active+Clean状态后,再将pgp_num设置的和pg_num一致。
# 在RGW节点安装软件
# yum install ceph-radosgw
RGW_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
[client.rgw.Carbon]
rgw_frontends = "civetweb port=80"
推送修改后的配置文件后,重启RGW服务:
systemctl restart ceph-radosgw.service
[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
RGW在index_pool池中存放桶(Bucket)索引数据,此池默认名为.rgw.buckets.index。
从0.94版本开始,支持对桶索引进行分片,避免单个桶中对象数量过多时出现性能瓶颈:
# 每个桶的最大索引分片数,默认0,表示不支持分片
rgw_override_bucket_index_max_shards = 0
你可以在global段配置上面的选项。
要使用RGW的RESTful接口,你需要:
要创建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客户端来验证用户是否可用。
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没有提供对应的命令行。需要注意以下约束:
我们可以使用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"
# ]
Ceph默认开启了cephx协议,加密认证需要消耗少量的资源。
启用cephx后,Cephe会自动在包括/etc/ceph/ceph.$name.keyring在内的位置寻找钥匙串,你可以指定keyring选项来修改默认路径,但是不推荐
在禁用了cephx的集群上,启用它的步骤为:
# 如果你使用的自动部署工具已经生成此文件,切勿执行此命令,会覆盖
ceph auth get-or-create client.admin mon 'allow *' mds 'allow *' osd 'allow *' -o /etc/ceph/ceph
ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'
cp /tmp/ceph.mon.keyring /var/lib/ceph/mon/ceph-a/keyring
ceph auth get-or-create osd.{$id} mon 'allow rwx' osd 'allow *' -o /var/lib/ceph/osd/ceph-{$id}/keyring
ceph auth get-or-create mds.{$id} mon 'allow rwx' osd 'allow *' mds 'allow *' -o /var/lib/ceph/mds/ceph-{$id}/keyring
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
# 停止当前节点上的所有Ceph守护进程
sudo stop ceph-all
sudo start ceph-all
修改配置文件global段:
auth cluster required = none
auth service required = none
auth client required = none
然后重启Ceph集群。
# 列出keyring
ceph auth ls
# 添加OSD的keyring
ceph auth add {osd} {--in-file|-i} {path-to-osd-keyring}
任何时后你都可以Dump、反编译、修改、编译、注入CURSH map。如果要完全基于手工方式管理,不使用自动生成的CRUSH map,可以设置:
osd crush update on start = false
执行命令 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": {}
}
执行下面的命令,导出当前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.000
alg straw2
hash 0 # rjenkins1
}
# rules
rule replicated_rule {
id 0
type replicated
min_size 1
max_size 10
step take default
step chooseleaf firstn 0 type host
step 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
# 会输出修订版号
默认情况下,Ceph自动根据硬件类型,设置OSD的设备类型为hdd, ssd或nvme。你可以手工进行设置:
# 你需要移除当前设置的设备类型,才能重新设置
ceph osd crush rm-device-class [...]
# 示例
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 [...]
# 示例
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
列出集群中的CRUSH rule:
ceph osd crush rule ls
Dump出规则的内容:
ceph osd crush rule dump
ceph osd crush rule rm replicated_rule_ssd
创建一个规则,仅仅使用指定类型的设备:
ceph osd crush rule create-replicated
# 示例:仅仅使用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
为存储池指定所使用的规则:
ceph osd pool set crush_rule
# 修改规则
ceph osd pool set rbd-ssd crush_rule replicated_rule_ssd
# 创建存储池时指定规则
ceph osd pool create rbd-ssd 384 replicated replicated_rule_ssd
CRUSH rule的语法如下:
rule {
ruleset
type [ replicated | erasure ]
min_size
max_size
# 根据桶名称来选取CRUSH子树,并迭代,可限定设备类型
step take [class ]
# choose:选择指定数量、类型的桶
# chooseleaf:选择指定数量、类型的桶,并选择每个这些桶的一个叶子节点
step [choose|chooseleaf] [firstn|indep]
step emit
}
示例一,将主副本存放在SSD中,第二副本存放在HDD中:
rule ssd-primary-affinity {
ruleset 0
type replicated
min_size 2
max_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 host
step emit
}
示例二,在第一个机架上存储两个副本,第二个机架上存储一个副本:
rule 3_rep_2_racks {
ruleset 1
type replicated
min_size 2
max_size 3
step take default
# 选择一个Rack,存储2个副本
step choose firstn 2 type rack
# 在上述选定的Rack中选择Host
step chooseleaf firstn 2 type host
step emit
}
如果要添加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
ceph osd crush reweight {name} {weight}
ceph osd crush remove {name}
ceph osd crush add-bucket {bucket-name} {bucket-type}
ceph osd crush move {bucket-name} {bucket-type}={bucket-name}, [...]
ceph osd crush remove {bucket-name}
# 自动优化
ceph osd crush tunables optimal
# 最大兼容性,存在老旧内核的cephfs/rbd客户端时
ceph osd crush tunables legacy
# 选择一个PROFILE,例如jewel
ceph osd crush tunables {PROFILE}
# weight在0-1之间,默认1,值越小,CRUSH 越避免将目标OSD作为主
ceph osd primary-affinity
使用CRUSH rule,可以限定某个Pool仅仅使用一部分OSD:
# SSD主机
host ceph-osd-ssd-server-1 {
id -1
alg straw
hash 0
item osd.0 weight 1.00
item osd.1 weight 1.00
}
# HDD主机
host ceph-osd-hdd-server-1 {
id -3
alg straw
hash 0
item osd.4 weight 1.00
item osd.5 weight 1.00
}
# HDD的根桶
root hdd {
id -5
alg straw
hash 0
item ceph-osd-hdd-server-1 weight 2.00
}
# SSD的根桶
root ssd {
id -6
alg straw
hash 0
item ceph-osd-ssd-server-1 weight 2.00
}
# 仅仅使用HDD的规则
rule hdd {
ruleset 3
type replicated
min_size 0
max_size 10
step take hdd
# 选择
step chooseleaf firstn 0 type host
step emit
}
# 仅仅使用SSD的规则
rule ssd {
ruleset 4
type replicated
min_size 0
max_size 4
step take ssd
step chooseleaf firstn 0 type host
step emit
}
# 在SSD上存储主副本,其它副本存放在HDD
rule ssd-primary {
ruleset 5
type replicated
min_size 5
max_size 10
step take ssd
step chooseleaf firstn 1 type host
step emit
step take hdd
step chooseleaf firstn -1 type host
step emit
}
前提条件:
步骤,针对每个需要改变尺寸的OSD,一个个的处理:
修改Cephe配置,设置 osd_journal_size = NEWSIZE
禁止数据迁移(防止OSD进入out状态): ceph osd set noout
停止目标OSD实例
刷出缓存: ceph-osd **-**i OSDID **–flush-**journal
删除日志:
# 基于Helm部署时,需要到宿主机上的osd_directory下寻找对应目录
cd /var/lib/ceph/osd/ceph-osd.OSDID
rm journal
创建一个新的日志文件: ceph-osd **–**mkjournal **-**i OSDID
启动OSD
验证新的日志尺寸被使用:
# Helm安装的情况下,需要在OSD容器中执行
ceph --admin-daemon /var/run/ceph/ceph-osd.OSDID.asok config get osd_journal_size
确保集群处于OK状态,所有PG处于active+clean状态
处理完所有OSD后,执行: ceph osd unset noout,清除noout标记
# 默认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倍
要动态、临时(重启后消失)的修改组件的参数,可以使用tell命令。
# 临时修改所有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' # 最大活跃的恢复请求数
可以将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
ceph osd blacklist ls
# listed 1 entries
# 10.0.3.1:0/158685765 2018-08-21 18:04:31.855791
ceph osd blacklist rm 10.0.3.1:0/158685765
ceph osd blacklist clear
# 列出池
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
# 列出池快照
rados lssnap -p rbd
# 创建池快照
rados mksnap snap-name -p rbd
# 删除池快照
rados rmsnap mksnap snap-name -p rbd
# 从快照中恢复对象
rados rollback
# 列出对象的快照
rados listsnaps
# 读对象
rados get object-name /tmp/obj -p rbd
# 使用指定的偏移量写对象
rados put object-name /tmp/obj --offset offset
# 附加内容到对象
rados append [infile
# 截断对象为指定的长度
rados truncate length
# 创建对象
rados create
# 移除对象
rados rm ...[--force-full]
# 复制对象
rados cp [target-obj]
# 列出扩展属性
rados listxattr
# 获取扩展属性
rados getxattr attr
# 设置扩展属性
rados setxattr attr val
# 移除扩展属性
rados rmxattr attr
# 显示属性
rados stat
rados list-inconsistent-pg pool-name
rados list-inconsistent-obj 40.14 --format=json-pretty
rados list-inconsistent-snapset 40.14
ceph mgr module enable dashboard
# 使用自签名证书
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
ceph dashboard ac-user-create admin administrator -i - <<<"pswd"
# 创建用户
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