关于 Ceph 系列其他文章的传送门
-
《 Ceph 从入门到放弃 》 您当前所在位置

一、Ceph 命令¶
查看即时状态¶
ceph pg stat:查看 PG 状态;ceph osd pool stats POOL_NAME:查看指定存储池池的状态;ceph df:显示整个 ceph 的存储空间用量,输出两段内容,GLOBAL和POOLS:GLOBAL:存储量概览SIZE:集群的整体存储容量AVAIL:集群中可以使用的可用空间容量RAW USED:已用的原始存储量% RAW USED:已用的原始存储量百分比。将此数字与full ratio和near full ratio搭配使用,可确保您不会用完集群的容量。
POOLS:存储池列表和每个存储池的理论用量,但出不反映副本、克隆数据或快照
检查 OSD 和 MON 的状态¶
可通过执行以下命令来检查 OSD,以确保它们已启动且正在运行:
ceph osd stat;ceph osd demp;
还可以根据OSD在CRUSH地图中的位置查看OSD:
ceph osd tree:Ceph 将列显 CRUSH 树及主机,它的 OSD 是否已启动及其权重;
集群中存在多个 Mon 主机时,应该在启动集群之后读取或写入数据之前检查 Mon 的仲裁状态;事实上,管理员也应该定期检查这种仲裁结果。
- 显示监视器映射:
ceph mon stat或ceph mon dump; - 显示仲裁状态:
ceph quorum_status
使用套接字管理 Ceph¶
Ceph 的管理套接字接口常用于查询守护进程,需要注意的是:
- 套接字默认保存于
/var/run/ceph目录; - 此接口的使用不能以远程方式进程,只能在本地使用。
命令的使用格式:
ceph --admin-daemon /var/run/ceph/SOCKET_NAME arg- 获取
SOCKET_NAME使用帮助:ceph --admin-daemon /var/run/ceph/SOCKET_NAME help
- 获取
1 | # ceph --admin-daemon /var/run/ceph/ceph-osd.0.asok status |
停止或重启 Ceph 集群¶
停止¶
-
告知 Ceph 集群不要将 OSD 标记为 out:
- 命令:
ceph osd set noout
- 命令:
-
按如下顺序停止守护进程和节点:
- 存储客户端
- 网关,例如 RadosGW
- 元数据服务器(MDS)
- Ceph OSD
- Ceph Manager
- Ceph Monitor
启动¶
-
以停止过程相反的顺序启动节点:
- Ceph Monitor
- Ceph Manager
- Ceph OSD
- 元数据服务器(MDS)
- 网关,例如 RadosGW
- 存储客户端
-
删除 noout 标志:
- 命令:
ceph osd unset noout
- 命令:
二、Ceph 配置文件¶
ceph 的配置文件是 ini 风格的:
[mon]:这样的配置段代表对所有 mon 生效;[mon.mon01]:这样的配置段代表仅对mon.mon01生效。
配置文件的加载顺序:
- 通过
$CEPH_CONF变量指定的配置文件路径; - 使用
-c path/path通过命令行传递的配置文件路径; - 在
/etc/ceph/ceph.conf下的配置文件; - 启动服务的用户的家目录
~/.ceph/config下的配置文件; - 用户当前工作目录中的
./ceph.conf配置文件。
Ceph 的元变量¶
元变量极大地简化了Ceph存储集群的配置,当在配置文件中使用了一个元变量时,Ceph 会将该元变量转换为一个具体的值。
在 Ceph 配置文件的 [global]、[osd]、[mon] 或 [client] 部分中使用时,元变量非常强大。但是,也可以将它们与管理套接字一起使用。
常用的元参数:
$cluster:当前 Ceph 集群的名称;$type:当前服务的类型名称,会转换为类似osd或mon;$id:进程的标识符,例如对osd.0来说,其标识符为0;$host:守护进程所在主机的主机名;$name:其值为$type.$id。
三、关于存储池¶
RADOS 存储集群提供的基础存储服务需要由“存储池(pool)”分割为逻辑存储区域,此类的逻辑区域亦是对象数据的名称空间:
- 生产环境中,管理员可以为特定应用程序的不同存储类型的需求分别创建专用的存储池,例如 rbd 存储池、rgw 存储池等,也可以为某个项目或某个用户创建专用的存储池。
- 存储池还可以再进一步细分为一至多个名称空间(namespace)。
- 客户端(包括 rbd 和 rgw 等)存取数据时,需要事先指定存储池名称、用户名和密钥等信息完成认证,而后将一直维持与其指定的存储池的连接,于是也可以把存储池看作是客户端的 IO 接口。
存储池类型:
- 副本池(replicated):把每个对象在集群中存储为多个副本,其中存储于主 OSD 的为主副本,副本数量在创建存储池时由管理员指定;
- 默认的存储池类型;
- 纠删码池(erasure code):把各对象存储为
N=K+M个块,其中K为数据块数量,M为编码块数量,因此存储池的尺寸为K+M;
RDB 类型的存储池只支持使用副本池,RadosGW 类型的可以使用纠删码池。
副本池对读 IO 有很好的负载表现,会占用更多的存储空间;纠删码池节约空间,但是会占用更多的 CPU。
副本池 IO¶
对于 3 副本来讲,任何一个 PG 都要选出 3 个 OSD,其中 Primary OSD 负载读写,其他两个 OSD 负责同步数据。
将一个数据对象存储为多副本的步骤:
- 写入操作时,Ceph 客户端使用 CRUSH 算法来计算对象的 PG ID 和 Primary OSD;
- 客户端从 Mon 查询到 Primary OSD 在哪个节点上,并获取到 Cluster Map;
- 客户端去连接 Primary OSD 所在节点的套接字,与 OSD 进程通信,把数据提交给 Primary OSD;
- Primary OSD 根据设定的副本数、对象的名称、存储池名称和集群运行图(Cluster Map)计算出 PG 的各辅助 OSD,而后由主 OSD 将数据同步给这些辅助 OSD;
- 当 Primary OSD 收到所有辅助 OSD 返回的确认信息后,才会把确认信息返回给客户端。

纠删码池 IO¶
纠删码是一种前向纠错(FEC)代码:
- 通过将
K块的数据转换为N块,假设N=K+M,则其中的M代表纠删码算法添加的额外或冗余的块数量以提供冗余机制(即编码块),而N则表示在纠删码编码之后要创建的块的总数,其可以故障的总块数为M(即N-K)个; - 类似于 RAID 5;
纠删码池减少了确保数据持久性所需的磁盘空间量,但计算量上却比副本存储池要更多一些。
RGW 可以使用纠删码存储池,但 RBD 不支持。
工作逻辑:
例如,把包含数据
ABCDEFGHI的对象NYAN保存到存储池中时,假设纠删码算法会把所有数据分割为三个数据块:
第一个包含ABC,第二个为DEF,最后一个为GHI,并为这三个数据块做前向纠错码计算,计算并创建另外两个编码块:第四个YXY和第五个GQC。所有块都要存放在不同的 OSD 中,并且有次序之分,因此每一个分片都应该指定它在当前整个数据文件当中的偏移量是多少。
如下图,正确的分片顺序是:osd 5-osd 1-osd 2-osd 3-osd 4。
任何的块损坏,都可以通过计算还原,而且由于有两给纠删码块,所以可以同时坏两个块。

在有着两个编码块配置的存储池中,它容许至多两个 OSD 不可用而不影响数据的可用性。
假设,在某个时刻 OSD 1 和 OSD 3 因故无法正常响应客户端请求,这意味着客户端仅能读取到 DEF YXY 和 QGC,此时纠删编码算法会通过计算重现出 ABC 和 GHI。
四、关于归置组¶
归置组(Placement Group)是用于跨 OSD 将数据存储在某个存储池中的内部数据结构:
- 相对于存储池来说,PG 是一个虚拟组件,它是对象映射到 OSD 时使用的虚拟层;
- 出于规模伸缩及性能方面的考虑,Ceph 将存储池细分为归置组,把每个单独的对象映射到归置组(通过一致性 Hash),并将归置组分配给一个主 OSD(通过 CRUSH);
- 存储池由一系列的归置组组成,而 CRUSH 算法则根据集群运行图和集群状态,将各 PG 均匀、伪随机地分布到集群中的 OSD 之上;
- 若某 OSD 失败或需要对集群进行重新平衡,Ceph 则移动或复制整个归置组而无需单独寻址每个对象;
归置组在 OSD 守护进程和 Ceph 客户端之间生成了一个中间层,CRUSH 算法负责将每个对象动态映射到一个归置组,然后再将每个归置组动态映射到一个或多个 OSD 守护进程,从而能够支持在新的 OSD 设备上线时动态进行数据重新平衡。
归置组计数¶
归置组的数量由管理员在创建存储池时指定,而后由 CRUSH 负责创建和使用。
通常,PG 的数量应该是数据的合理粒度的子集:
- 例如,一个包含 256 个 PG 的存储池意味着每个 PG 包含大约 1/256 的存储池数据。
当需要将 PG 从一个 OSD 移动到另一个 OSD 时,PG 的数量会对性能产生影响:
- PG 数量过少,Ceph 将不得不同时移动相当数量的数据,其产生的网络负载将对集群的正常性能输出产生负面影响;
- 而在过多的 PG 数量场景中在移动极少量的数据时,Ceph 将会占用过多的 CPU 和 RAM,从而对集群的计算资源产生负面影响。
PG 数量在群集分发数据和重新平衡时扮演着重要作用:
- 在所有 OSD 之间进行数据持久存储及完成数据分布会需要较多的归置组,但是它们的数量应该减少到最大性能所需的最小数量值,以节省 CPU 和内存资源;
- 一般说来,对于有着超过 50 个 OSD 的 RADOS 集群,建议每个 OSD 大约有 50-100 个 PG 以平衡资源使用,取得更好的数据持久性和数据分布,更大规模的集群中,每个 OSD 大约可持有 100-200 个 PG;
- 至于应该使用多少个 PG,可通过下面的公式计算后,将其值以类似于四舍五入到最近的 2 的 N 次幂(因为 Hash 编码是十六进制数字,而十六进制对 2 的 N 次幂进行取模的计算速度最快);
(Total OSDs * PGPerOSD)/Replication factor => Total PGs
- 一个 RADOS 集群上可能会存在多个存储池,因此管理员还需要考虑所有存储池上的 PG 分布后每个 OSD 需要映射的 PG 数量。
归置组状态¶
依据 PG 当前的工作特性或工作进程所处的阶段,它总是处于某个或某些个状态中,最为常见的状态应该为 active+clean
PG 的常见状态¶
- Active:
- 主 OSD 和各辅助 OSD 均处于就绪状态,可正常服务于客户端的 IO 请求;
- 一般 Peering 操作过程完成后即会转入 Active 状态。
- Clean:
- 主 OSD 和各辅助 OSD 均处于就绪状态,所有对象的副本数量均符合期望,并且 PG 的活动集和上行集是为同一组 OSD;
- 活动集(Acting Set):由 PG 当前的主 OSD 和所有的处于活动状态的辅助 OSD 组成,这组 OSD 负责执行此 PG 上数据对象的存取操作 I/O;
- 上行集(Up Set):根据 CRUSH 的工作方式,集群拓扑架构的变动将可能导致 PG 相应的 OSD 变动或扩展至其它的 OSD 之上,这个新的 OSD 集也称为 PG 的 “上行集(Up Set)”,其映射到的新 OSD 集可能部分地与原有 OSD 集重合,也可能会完全不相干;上行集 OSD 需要从当前的活动集 OSD 上复制数据对象,在所有对象同步完成后,上行集便成为新的活动集,而 PG 也将转为“活动(active)” 状态。
- 主 OSD 和各辅助 OSD 均处于就绪状态,所有对象的副本数量均符合期望,并且 PG 的活动集和上行集是为同一组 OSD;
- Peering:
- 一个 PG 中的所有 OSD 必须就它们持有的数据对象状态达成一致,而“对等(Peering)”即为让其 OSD 从不一致转为一致的过程。
- Degraded:
- 在某 OSD 标记为
down时,所有映射到此 OSD 的 PG 即转入“降级(degraded)”状态; - 此 OSD 重新启动并完成 Peering 操作后,PG 将重新转回 Clean;
- 一旦 OSD 标记为 down 的时间超过 5 分钟,它将被标记出集群,而后 Ceph 将对降级状态的 PG 启动恢复操作,直到所有因此而降级的 PG 重回 Clean 状态;
- 在其内部 OSD 上某对象不可用或悄然崩溃时,PG 也会被标记为降级状态,直至对象从某个权威副本上正确恢复。
- 在某 OSD 标记为
- Stale:
- 每个 OSD 都要周期性地向 RADOS 集群中的监视器报告其作为主 OSD 所持有的所有 PG 的最新统计数据,因任何原因导致某个主 OSD 无法正常向监视器发送此类报告,或者由其它 OSD 报告某个 OSD 已经 down 掉,则所有以此 OSD 为主 OSD 的 PG 将立即被标记为“过期(stale)”状态。
- Undersized:
- PG 中的副本数少于其存储池定义的个数时即转入 undersized 状态,恢复和回填操作在随后会启动,以修复其副本数为期望值。
- Scrubbing:
- 各 OSD 还需要周期性地检查其所持有的数据对象的完整性,以确保所有对等 OSD 上的数据一致;处于此类检查过程中的 PG 便会被标记为 scrubbing 状态,这也通常被称作 light scrubs、shallow scrubs 或者 simply scrubs;
- 另外,PG 还偶尔需要进行 deep scrubs 检查以确保同一对象在相关的各 OSD 上能按位匹配,此时 PG 将处于 scrubbing+deep 状态。
- Recovering:
- 添加一个新的 OSD 至存储集群中或某 OSD 宕掉时,PG 则有可能会被 CRUSH 重新映射进而将持有与此不同的 OSD 集,而这些处于内部数据同步过程中的 PG 则被标记为 recovering 状态。
- Backfilling:
- 新 OSD 加入存储集群后,Ceph 则会进入数据重新均衡的状态,即一些数据对象会在进程后台从现有 OSD 移到新的 OSD 之上,此操作过程即为 backfill。
五、关于 CRUSH¶
把对象直接映射到 OSD 之上会导致二者之间的耦合关系过于紧密,在 OSD 设备变动时不可避免地对整个集群产生惊群扰动,于是,Ceph 客户端将一个对象映射进 RADOS 集群的过程分为两步:
- 首先是以一致性哈希算法将对象名称映射到 PG;
- 而后将从 ClusterMap 获取到的 PG ID 基于 CRUSH 算法映射到 OSD;
此两个过程都以“实时计算”的方式完成,而非传统的查表方式,从而有效规避了任何组件被“中心化”的可能性,使得集群规模扩展不再受限
这个实时计算操作用到的算法就是 CRUSH(Controlled Replication Under Scalable Hashing),它是一种数据分布式算法,类似于一致性哈希算法,用于为 RADOS 存储集群控制数据分布。

六、客户端 IO 的简要工作流程¶
存取对象时,客户端从 Ceph 监视器检索出集群运行图,绑定到指定的存储池,并对存储池上 PG 内的对象执行 IO 操作:
- 存储池的 CRUSH 规则集和 PG 的数量是决定 Ceph 如何放置数据的关键性因素;
- 基于最新版本的集群运行图,客户端能够了解到集群中的所有监视器和 OSD 以及它们各自的当前状态;
- 不过,客户端对目标对象的位置却一无所知。
执行对象的存取操作时,客户端需要输入的是对象标识和存储池名称:
- 客户端需要在存储池中存储命名对象时,它将对象名称、对象名称的哈希码、存储池中的 PG 数量和存储池名称作为输入,而后由 CRUSH 计算出 PG 的 ID 及此 PG 的主 OSD。
- 通过将对象标识进行一致性哈希运算得到的哈希值与 PG 位图掩码进行“与”运算得到目标 PG,从而得出目标 PG 的 ID(pg_id),完成由 Object 至 PG 的映射;
- 而后,CRUSH 算法便将以此 pg_id、CRUSH 运行图和归置规则(Placement Rules)为输入参数再次进行计算,并输出一个确定且有序的目标存储向量列表(OSD 列表),从而完成从 PG 至 OSD 的映射。
简要完整流程¶
Ceph 客户端使用以下步骤来计算 PG ID:
- 客户端输入存储池名称及对象名称,例如:
pool = pool1以及object-id = obj1; - 获取对象名称并通过一致性哈希算法对其进行哈希运算,即
hash(o),其中o为对象名称; - 将计算出的对象标识哈希码与 PG 位图掩码进行“与”运算获得目标 PG 的标识符,即 PG ID,例如
1701;- 计算公式为
pgid=func(hash(o)&m,r),其中变量o是对象标识符,变量m是当前存储池中 PG 的位图掩码,变量r是指复制因子,用于确定目标 PG 中 OSD 数量;
- 计算公式为
- CRUSH 根据集群运行图计算出与目标 PG 对应的有序的 OSD 集合,并确定出其主 OSD;
- 客户端获取到存储池名称对应的数字标识,例如,存储池
pool1的数字标识11; - 客户端将存储池的 ID 添加到 PG ID,例如:
11.1701; - 客户端通过直接与 PG 映射到的主 OSD 通信来执行诸如写入、读取或删除之类的对象操作。
七、后端存储引擎 FileStore and BlueStore¶
ceph 后端支持多种存储引擎,以插件化的形式来进行管理使用,目前支持:
- filestore;
- kvstore;
- memstore;
- bluestore,
BlueStore的优势:
- 对于大型写入操作,避免了原先 FileStore 的两次写入
- 注意,很多 FileStore 将 journal 日志存放到独立到 SSD 上,也能够获得类似的性能提升,不过分离 journal 的部署方式是绕开 FileStore 的短板
- 对于小型随机写入,BlueStore 比 FileStore with journal 性能还要好
- 对于 Key/value 数据 BlueStore 性能明显提升
- 当集群数据接近爆满时,BlueStore 避免了 FileStore 的性能陡降问题
- 在 BlueStore 上使用 raw 库的小型顺序读性能有降低,和 BlueStore 不采用预读 (readahead) 有关,但可以通过上层接口(如 RBD 和 CephFS)来实现性能提升
- BlueStore 在 RBD 卷或 CephFS 文件中采用了 copy-on-write 提升了性能
从 Ceph Luminous v12.2.z 开始,默认采用了新型的 BlueStore 作为 Ceph OSD 后端,用于管理存储磁盘。

更多详细,推荐阅读:
https://cloud-atlas.readthedocs.io/zh_CN/latest/ceph/bluestore.html
https://blog.csdn.net/weixin_43618070/article/details/87931284
八、操作存储池¶
存储的常用管理操作包括列出、创建、重命名和删除等操作,常用相关的工具都是 ceph osd pool 的子命令,包括 ls、create、rename 和 rm 等;
创建存储池¶
副本型存储池创建命令:
1 | ceph osd pool create {pool-name} [{pg-num} [{pgp-num}]] [replicated] \ |
纠删码池创建命令:
1 | ceph osd pool create {pool-name} [{pg-num} [{pgp-num}]] erasure \ |
命令格式中常用的参数:
pool-name:存储池名称,在一个 RADOS 存储集群上必须具有唯一性;pg-num:当前存储池中的 PG 数量,合理的 PG 数量对于存储池的数据分布及性能表现来说至关重要;pgp-num:用于归置的 PG 数量,其值应该等于 PG 的数量;replicated|erasure:存储池类型;副本存储池需要更多原始存储空间,但已实现 Ceph 支持的所有操作,而纠删码存储池所需原始存储空间较少,但目前仅实现了 Ceph 的部分操作;crush-ruleset-name:指定此存储池所用的 CRUSH 规则集的名称,引用的规则集必须事先存在,不过 Ceph 中有默认的规则集,不指定则使用默认的。
获取存储池的相关信息¶
- 列出存储池:
ceph osd pool ls [detail]; - 获取存储池的统计数据:
ceph osd pool stats [pool-name]; - 显示存储池的用量信息:
rados df; - 重命名存储池:
ceph osd pool rename old-name new-name。
删除存储池¶
意外删除存储池会导致数据丢失,因此 Ceph 实施了两个机制来防止删除存储池,要删除存储池,必须先禁用这两个机制:
- 第一个机制是 NODELETE 标志,其值需要为
false,默认也是false;- 查看命令:
ceph osd pool get pool-name nodelete; - 修改命令:
ceph osd pool set pool-name nodelete false;
- 查看命令:
- 第二个机制是集群范围的配置参数
mon allow pool delete,其默认值为false,这表示默认不能删除存储池,临时设定的方法如下:ceph tell mon.* injectargs --mon-allow-pool-delete={true|false};- 建议删除之前将其值设置为
true,删除完成后再改为false。
删除命令:ceph osd pool rm pool-name pool-name --yes-i-really-really-mean-it。
设置存储池配额¶
Ceph 支持为存储池设置可存储对象的最大数量(max_objects)和可占用的最大空间(max_bytes)两个纬度的配额:
- 命令格式:
ceph osd pool set-quota <pool-name> max_objects|max_bytes <val>; - 查询存储池配额的相关信息:
ceph osd pool get-quota <pool-name>;
配置存储池参数¶
- 存储池的诸多配置属性保存于配置参数中
- 获取配置:
ceph osd pool get <pool-name>; - 设定配置:
ceph osd pool set <pool-name> <key> <value>。
- 获取配置:
常用的可配置参数:
size:存储池中的对象副本数;min_size:允许客户端进行 I/O 操作时,所需要的最小副本数;pg_num:存储池的 PG 数量;pgp_num:计算数据归置时要使用的 PG 的有效数量;crush_ruleset:用于在集群中映射对象归置的规则组;nodelete:控制是否可删除存储池;nopgchange:控制是否可更改存储池的pg_num和pgp_num;nosizechange:控制是否可更改存储池的大小;noscrub和nodeep-scrub:控制是否可整理或深层整理存储池以解决临时高 I/O 负载的问;scrub_min_interval:集群负载较低时整理存储池的最小时间间隔;- 默认值为
0,表示其取值来自于配置文件中的osd_scrub_min_interval参数;
- 默认值为
scrub_max_interval:整理存储池的最大时间间隔;- 默认值为
0时,表示其取值来自于配置文件中的osd_scrub_max_interval参数;
- 默认值为
deep_scrub_interval:深层整理存储池的间隔;- 默认值为
0时,表示其取值来自于配置文件中的osd_deep_scrub参数。
- 默认值为
存储池快照¶
关于存储池快照:
- 存储池快照是指整个存储池的状态快照;
- 通过存储池快照,可以保留存储池状态的历史;
- 创建存储池快照可能需要大量存储空间,具体取决于存储池的大小;
创建存储池快照:
ceph osd pool mksnap <pool-name> <snap-name>- 或
rados -p <pool-name> mksnap <snap-name>
列出存储池的快照:
rados -p <pool-name> lssnap
回滚存储池至指定的快照:
rados -p <pool-name> rollback <snap-name>
删除存储池快照:
ceph osd pool rmsnap <pool-name> <snap-name>- 或
rados -p <pool-name> rmsnap <snap-name>
数据压缩¶
BlueStore 存储引擎提供即时数据压缩,以节省磁盘空间。
启用压缩:
ceph osd pool set <pool-name> compression_algorithm snappy:- 压缩算法有 none、zlib、lz4、zstd 和 snappy 等几种,默认为 snappy;
- zstd 有较好的压缩比,但比较消耗 CPU;
- lz4 和 snappy 对 CPU 占用比例较低;
- 不建议使用 zlib。
- 压缩算法有 none、zlib、lz4、zstd 和 snappy 等几种,默认为 snappy;
ceph osd pool set <pool-name> compression_mode aggressive:- 压缩模式 none、aggressive、passive 和 force,默认值为 none;
- none:不压缩;
- passive:若指明 COMPRESSIBLE,则压缩;
- aggressive:除非指明 INCOMPRESSIBLE,否则就压缩;
- force:始终压缩。
- 压缩模式 none、aggressive、passive 和 force,默认值为 none;
其它可用的压缩参数:
compression_required_ratio:指定压缩比,取值格式为双精度浮点型,其值为SIZE_COMPRESSED/SIZE_ORIGINAL,即压缩后的大小与原始内容大小的比值,默认为.875;compression_max_blob_size:压缩对象的最大体积,无符号整数型数值,默认为0;compression_min_blob_size:压缩对象的最小体积,无符号整数型数值,默认为0;
全局压缩选项:
- 可在 ceph 配置文件中设置压缩属性,它将对所有的存储池生效,可设置的相关参数如下:
bluestore_compression_algorithm;bluestore_compression_mode;bluestore_compression_required_ratio;bluestore_compression_min_blob_size;bluestore_compression_max_blob_size;bluestore_compression_min_blob_size_ssd;bluestore_compression_max_blob_size_ssd;bluestore_compression_min_blob_size_hdd;bluestore_compression_max_blob_size_hdd。
纠删码存储池¶
空间利用率高:K/N:
K为数据块量,N为加上编码块量的总块数;
创建纠删码池:
1 | ceph osd pool create <pool-name> <pg-num> <pgp-num> erasure \ |
- 未指定要使用的纠删编码配置文件时,创建命令会为其自动创建一个,并在创建相关的 CRUSH 规则集时使用到它;
- 默认配置文件自动定义
k=2和m=1,这意味着 Ceph 将通过三个 OSD 扩展对象数据,并且可以丢失其中一个 OSD 而不会丢失数据,因此,在冗余效果上,它相当于一个大小为 2 的副本池,不过其存储空间有效利用率为 2/3 而非 1/2。
九、认证、授权与 CephX 协议¶
CephX 认证机制¶
Ceph 使用 cephx 协议对客户端进行身份认证,每个 Mon 都可以对客户端进行身份验证并分发密钥,不存在单点故障和性能瓶颈。
客户端向 Ceph 请求身份验证时的具体流程:
- 管理员事先在 Mon 上创建用户账号,之后由管理员以安全的方式把创建好的用户密钥复制到客户端,一般保存在
/etc/ceph目录下; - Mon 会自动把刚刚新创建的用户的相关信息同步给其他组件,比如 Mon、OSD、MDS 等;
- 当用户请求验证时,Mon 使用客户端密钥对 session key 进行加密后发给客户端(客户端密钥是在部署时提前手动分发好的);
- 客户端使用自己的密钥解密后得到 session key,之后使用 session key 向 Mon 请求所需的服务;
- Mon 验证 session key 是否为自己发放的,如果是就通过验证。之后 Mon 会把一个 ticket 经过加密后向客户端提供,客户端解密后拿着这个 ticket 向实际处理数据的 OSD 等验正客户端身份;
- 因为 Mon 和 OSD 共享同一个 secret,因此 OSD 会信任由 MON 发放的 ticket;
- ticket 存在有效期限,过一段时间后会过期。
注意:CephX 身份验正功能仅限制了 Ceph 的各组件之间,它不能扩展到其它非 Ceph 组件。而且并不解决数据传输加密的问题。
CephX 身份验正流程:

CephX 身份验正 – MDS 和 OSD:

认证与授权¶
认证与授权
- 无论 Ceph 客户端是何类型,Ceph 都会在存储池中将所有数据存储为对象。
- Ceph 用户需要拥有存储池访问权限才能读取和写入数据;
- Ceph 用户必须拥有执行权限才能使用 Ceph 的管理命令。
相关概念
- 用户;
- 授权;
- 使能(Capabilities)。
用户¶
用户是指人类或系统参与者(例如应用),通过创建用户,可以控制谁(或哪个参与者)能够访问 Ceph 存储集群、以及可访问的存储池及存储池中的数据。
Ceph 支持多种类型的用户,但可管理的用户都属于 Client 类型:
- 区分用户类型的原因在于,MON、OSD 和 MDS 等系统组件也使用 cephx 协议,但它们并非为
客户端; - 通过点号来分隔用户类型和用户名,格式为
TYPE.ID,例如client.admin等。
授权和使能¶
Ceph 基于 “使能(caps)” 来描述用户可针对 MON、OSD 或 MDS 使用的权限范围或级别。
通用语法格式:daemon-type 'allow caps' [...];
- MON 使能:
- 包括
r、w、x和allow profile cap(类似统计数据); - 例如:
mon 'allow rwx',以及mon 'allow profile osd'等;
- 包括
- OSD 使能:
- 包括
r、w、x、class-read(类查询)、class-write(类写入)和profile osd; - 此外,OSD 使能还允许针对某个特定的存储池和名称空间设置
- 包括
- MDS 使能:
- 只需要 allow,或留空。
各项使能的意义¶
allow:需先于守护进程的访问设置指定;- 仅对 MDS 表示
rw之意,对于其他的比如 OSD 来说只表示字面意义 “允许。。。”;
- 仅对 MDS 表示
r:读取权限,访问 MON 以检索 CRUSH 时依赖此使能;w:对象写入权限;x:调用类方法(读取和写入)的能力,以及在 MON 上执行 auth 操作的能力;class-read:x能力的子集,授予用户调用类读取方法的能力;class-write:x的子集,授予用户调用类写入方法的能力;*:授予用户对特定守护进程/存储池的读取、写入和执行权限,以及执行管理命令的能力;profile osd:- 授予用户以某个 OSD 身份连接到其他 OSD 或监视器的权限;
- 授予 OSD 权限,使 OSD 能够处理复制检测信号流量和状态报告;
profile mds:- 授予用户以某个 MDS 身份连接到其他 MDS 或监视器的权限;
profile bootstrap-osd:- 授予用户引导 OSD 的权限;
- 授权给部署工具,使其在引导 OSD 时有权添加密钥;
profile bootstrap-mds:- 授予用户引导元数据服务器的权限;
- 授权给部署工具,使其在引导元数据服务器时有权添加密钥;
用户管理¶
Ceph 集群管理员能够直接在 Ceph 集群中创建、更新和删除用户。创建用户时,可能需要将密钥分发到客户端,以便将密钥添加到密钥环
密钥环可以将多个用户的认证信息存放在同一个文件内,文件内任意一个用户都可以使用。也可以将每个用户单独存放。
列出用户:ceph auth list;
- 用户标识:
TYPE.ID,因此,osd.0表示 OSD 类型的用户,用户 ID 为0;
检索特定用户:ceph auth get TYPE.ID 或者 ceph auth export TYPE.ID。
添加用户:
ceph auth add:规范方法,它能够创建用户、生成密钥并添加指定的 caps;ceph auth get-or-create:简便方法,创建用户并返回密钥文件格式的密钥信息,或者在用户存在时返回用户名及密钥文件格式的密钥信息;ceph auth get-or-create-key:简便方法,创建用户并返回密钥信息,或者在用户存在时返回密钥信息
注意:典型的用户至少要对 Ceph monitor 具有读取功能,并对 Ceph OSD 具有读取和写入功能;另外,用户的 OSD 权限通常应该限制为只能访问特定的存储池,否则,他将具有访问集群中所有存储池的权限。
示例:
1 | # ceph auth add client.testuser mon 'allow r' osd 'allow rw pool=rbdpool' |
只列出用户的密钥信息:ceph auth print-key TYPE.ID;
导入用户:ceph auth import,需要指定密钥环;
修改用户的 caps:ceph auth caps;
- 会覆盖用户现有的 caps,因此建立事先使用
ceph auth get TYPE.ID命令查看用户的 caps; - 若为添加 caps,则需要先指定现有的 caps;
- 语法:
ceph auth caps TYPE.ID daemon 'allow [r|w|x|*|...] [pool=pool-name] [namespace=namespace-name]' ...
示例:
1 | 先查看 caps 是什么 |
删除用户:ceph auth del TYPE.ID;
Keyring¶
密钥环是能够同时存储密码、密钥、证书并将其提供给应用程序的集合组件。
密钥环文件存储一个或多个 Ceph 身份验证密钥以及其他关联的功能。
每个键都与实体名称相关联,格式为 [client|mon|mds|osd].name。
ceph-authtool 是用于创建,查看和修改 Ceph 密钥环文件的实用程序。
访问 Ceph 集群时,任何客户端会于本地查找密钥环,默认情况下,Ceph 会使用以下四种格式命名密钥环:
/etc/ceph/cluster-name.user-name.keyring:保存单个用户的 keyring;cluster-name是集群名称,user-name为用户标识TYPE.ID;
/etc/ceph/cluster.keyring:保存多个用户的 keyring;/etc/ceph/keyring;/etc/ceph/keyring.bin。
管理 Keyring¶
创建 Keyring¶
ceph auth add 等命令添加的用户如果需要 keyring 文件,还需要额外使用 ceph-authtool 命令为其创建用户密钥环:
- 命令:
ceph-authtool --create-keyring /path/to/kerying
注意:
- keyring 文件一般应该保存于
/etc/ceph目录中,以便客户端能自动查找; - 当创建包含多个用户的 keyring 文件时,应该使用
cluster-name.keyring作为文件名; - 当创建仅包含单个用户的 kerying 文件时,应该使用
cluster-name.user-name.keyring作为文件名;
将用户添加至 Keyring¶
可将某个用户从包含多个用户的 keyring 中导出,并保存为一个专用的 keyring 文件:
- 命令:
ceph auth get TYPE.ID -o /etc/ceph/cluster-name.user-name.keyring
也可将用户的 keyring 合并至一个统一的 keyring 文件中:
- 命令:
ceph-authtool /etc/ceph/cluster-name.keyring --import-keying /etc/ceph/cluster- name.user-name.keyring
十、RADOS 块设备 – RDB¶
RBD,全称 RADOS Block Devices,是一种建构在 RADOS 存储集群之上为客户端提供块设备接口的存储服务中间层,这类的客户端包括虚拟化程序 KVM(结合 qemu)和云的计算操作系统 OpenStack 和 CloudStack 等。
RBD 基于 RADOS 存储集群中的多个 OSD 进行条带化,支持存储空间的简配(thin-provisioning)和动态扩容等特性,并能够借助于 RADOS 集群实现快照、副本和一致性。
RBD 自身也是 RADOS 存储集群的客户端,它通过将存储池提供的存储服务抽象为一到多个 image(表现为块设备)向客户端提供块级别的存储接口。
RBD 支持两种格式的 image,不过 v1 格式因特性较少等原因已经处于废弃状态,当前默认使用的为 v2 格式。
客户端访问 RBD 设备的方式有两种:
- 通过内核模块
rbd.ko将 image 映射为节点本地的块设备,相关的设备文件一般为/dev/rdb#(#为设备编号,例如rdb0等); - 另一种则是 librbd 提供的 API 接口,它支持 C/C++ 和 Python 等编程语言,qemu 即是此类接口的客户端。
1. RBD 命令¶
RBD 相关的管理有如 image 的创建、删除、修改和列出等基础 CRUD 操作,也有分组、镜像、快照回收站等管理需求,这些均能够通过 rbd 命令完成。
rbd [-c ceph.conf] [-m monaddr] [--cluster cluster-name] [-p|--pool pool] [command...]
创建并初始化 RBD 存储池¶
使用块设备客户端之前必须事先创建专用的存储池、启用 rbd 并完成其初始化:
- 创建存储池:
ceph osd pool create {pool-name} {pg-num} {pgp-num}; - 启用 rbd:
ceph osd pool application enable {pool-name} rbd; - rbd 初始化:
rbd pool init -p {pool-name}。
示例:
1 | ceph osd pool create kube 64 64 |
2. 创建并查看 image¶
创建 image¶
语法:rbd create --size <megabytes> --pool <pool-name> <image-name>。
例如:下面的命令于存储池 rbdpool中创建了一个大小为 2GB 的映像 myimg:
1 | 第二种写法 |
其他参数:
order <order>:指定要切分成的块大小,默认为 4M;--image-feature:指定镜像的特性;--no-progress:不显示创建过程。
列出 image¶
存储池中的各 image 名称需要惟一,rbd ls 命令能够列出指定存储池中的 image:
rbd ls [-p <pool-name>] [--long] [--format json|xml] [--pretty-format] <pool-name>
查看指定 images 的详细信息¶
要获取指定 image 的详细信息,则通常使用 rbd info 命令:
rbd info [--pool <pool>] [--image <image>] [--image-id <image-id>] [--format <format>] [--pretty-format] <image-spec>--format json|xml:以指定的格式输出;--pretty-format:当使用 json 或 xml 时以美观的格式输出。
1 | # rbd info kube/vol01 |
rbd info 命令输出解析¶
size M GiB in N objects:image 空间大小为 M,共分割至 N 个对象(分割的数量由条带大小决定);order 22 (4 MiB objects):块大小(条带)的标识序号,有效范围为12-25,分别对应着4K-32M之间的大小;id:当前 image 的标识符;block_name_prefix:当前image相关的object的名称前缀;format:image 的格式,其中的2表示v2;features:当前 image 启用的功能特性,其值是一个以逗号分隔的字符串列表;op_features:可选的功能特性。
3. image 特性¶
- layering:是否支持克隆;
- exclusive-lock:是否支持分布式排他锁机制,以限制同时仅能有一个客户端访问当前 image;
- object-map:是否支持 object 位图,主要用于加速导入、导出及已用容量统计等操作,依赖于 exclusive-lock 特性;
- fast-diff:是否支持快照间的快速比较操作,依赖于 object-map 特性;
- deep-flatten:深层展平,是否支持克隆分离时解除在克隆 image 时创建的快照与其父 image 之间的关联关系;
- striping:是否支持数据对象间的数据条带化;
- journaling:是否支持日志 IO,即是否支持记录 image 的修改操作至日志对象;依赖于 exclusive-lock 特性;
- data-pool:是否支持将 image 的数据对象存储于纠删码存储池,主要用于将 image 的元数据与数据放置于不同的存储池;
新版 Ceph 中的 rbd 默认开启了前 5 种特性,但是 rbd 被加载到 Linux 内核时不支持其中的后 3 种,要关闭:
- 关闭指定镜像的指定特性:
rbd feature disable <image-spec> <features> [<features> ...]
- 打开指定镜像的指定特性:
rbd feature enable <image-spec> <features> [<features> ...]
1 | rbd feature disable kube/vol01 object-map fast-diff deep-flatten |
4. 调整 image 的大小¶
rbd resize [--pool <pool>] [--image <image>] --size <size> [--allow-shrink] [--no-progress] <image-spec>- 增大:
rbd resize [--pool <pool>] [--image <image>] --size <size> - 减少:
rbd resize [--pool <pool>] [--image <image>] --size <size> [--allow-shrink]
- 增大:
5. 删除 image¶
语法:rbd remove [--pool <pool>] [--image <image>] [--no-progress] <image-spec>
注意:删除 image 会导致数据丢失,且不可恢复;建议使用 trash 命令先将其移入 trash,确定不再需要时再从 trash 中删除:
rbd trash {list|move|purge|remove|restore}
6. 在客户端使用 image¶
在 RBD 客户端节点上以本地磁盘方式使用块设备之前,需要先将目标 image 映射至本地内核,而且,若存储集群端启用了 CephX 认证,还需要指定用户名和 keyring 文件,语法:
rbd map [--pool <pool>] [--image <image>] [--id <user-name>] [--keyring </path/to/keyring>]
查看已经映射的 image:rbd showmapped
断开:rbd unmap [--pool <pool>] [--image <image>] <image-or-device-spec>
注意:节点重启后,使用 rbd 命令建立的 image 映射会丢失。
示例:在 Linux 在内核级加载和断开 rbd。
1. 检查内核模块¶
在 Linux 内核级加载 rbd 的前提是系统必须装有内核模块:
1 | # modinfo ceph |
2. CephX 认证¶
Client 这台机器有也只有 192.168.50.0/24 这个网段的地址,这也是 Ceph 的 public network。
要使用 Ceph 的 rbd,需要 Client 能够通过 CephX 连接并认证到 Mon,在 Client 端安装 Ceph 客户端:
1 | 先从其他节点把 ceph 和 epel 的 yum 仓库配置文件传到 client |
为 Client 创建一个用户授权,并复制到 Client:
1 | 创建并赋予权限 |
3. 映射 image¶
在 Client 客户端指定通过 kube 用户把 image 映射到本地:
1 | 映射 |
查看已经映射的 image:
1 | # rbd showmapped |
从 Server 端也能看到挂载信息:
1 | # rbd ls -p kube -l |
4. 断开 image¶
彻底断开 image 的映射:
1 | # umount /mnt |
7. image 快照¶
RBD 支持 image 快照技术,快照可以保留 image 的状态历史,Ceph 还支持快照“分层”机制,从而可实现快速克隆 VM 映像;
rbd 命令及许多高级接口(包括 QEMU、libvirt、OpenStack 等)都支持设备快照。
创建快照¶
rbd snap create [--pool <pool>] --image <image> --snap <snap>- 或
rbd snap create [<pool-name>/]<image-name>@<snapshot-name>
注意:在创建映像快照之前应停止 image 上的 IO 操作,且 image 上存在文件系统时,还要确保其处于一致状态。
列出快照¶
rbd snap ls [--pool <pool>] --image <image> [--format <format>] [--pretty-format] [--all]
回滚快照¶
rbd snap rollback [--pool <pool>] --image <image> --snap <snap> [--no-progress]
注意:将映像回滚到快照意味着会使用快照中的数据重写当前版本的 image,而且执行回滚所需的时间将随映像大小的增加而延长。
限制快照数量¶
限制数量:快照数量过多,必然会导致 image 上的原有数据第一次修改时的 IO 压力恶化:
rbd snap limit set [--pool <pool>] [--image <image>] [--limit <limit>]
解除限制:rbd snap limit clear [--pool <pool>] [--image <image>]
删除快照¶
• rbd snap rm [--pool <pool>] [--image <image>] [--snap <snap>] [--no-progress] [--force]
提示:Ceph OSD 会以异步方式删除数据,因此删除快照并不能立即释放磁盘空间。
清理快照¶
删除一个 image 的所有快照,可以使用 rbd snap purge 命令:
rbd snap purge [--pool <pool>] --image <image> [--no-progress]
示例:为 vol01 的 images 创建快照:
1 | 事先已经将 vol01 映射到客户端的 /mnt 目录 |
8. image 快照分层¶
Ceph 支持在一个块设备快照的基础上创建一到多个 COW 或 COR(Copy-On-Read) 类型的克隆,这种中间快照层(snapshot layering)机制提了一种极速创建 image 的方式。
用户可以创建一个基础 image 并为其创建一个只读快照层,而后可以在此快照层上创建任意个克隆进行读写操作,甚至能够进行多级克隆。
例如,实践中可以为 Qemu 虚拟机创建一个 image 并安装好基础操作系统环境作为模板,对其创建创建快照层后,便可按需创建任意多个克隆作为 image 提供给多个不同的 VM 使用,或者每创建一个克隆后进行按需修改,而后对其再次创建下游的克隆。
通过克隆生成的 image 在其功能上与直接创建的 image 几乎完全相同,它同样支持 读、写、克隆、空间扩缩容等功能,惟一的不同之处是克隆引用了一个只读的上游快照,而且此快照必须要置于“保护”模式之下。
支持 COW 和 COR 两种类型,COW 是为默认的类型,仅在数据首次写入时才需要将它复制到克隆的 image 中,而 COR 则是在数据首次被读取时复制到当前克隆中,随后的读写操作都将直接基于此克隆中的对象进行。
在 RBD 上使用分层克隆的方法非常简单:创建一个 image,对 image 创建一个快照,并将其置入保护模式,之后克隆此快照即可。
创建克隆的 image 时,需要指定引用的存储池、镜像和镜像快照,以及克隆的目标 image 的存储池和镜像名称,因此,克隆镜像支持跨存储池进行

使用分层快照¶
保护上游的原始快照:
- 下游 image 需要引用上游快照中的数据,快照的意外删除必将导致数据服务的中止,因此 在克隆操作之外,必须将上游的快照置于保护模式
rbd snap protect [--pool <pool>] --image <image> --snap <snap>
克隆快照:
rbd clone [--pool <pool>] --image <image> --snap <snap> --dest-pool <dest-pool> [--dest <dest>- 或
rbd clone [<pool-name>/]<image-name>@<snapshot-name> [<pool- name>/]<image-name>
列出快照下创建了多少克隆:
rbd children [--pool <pool>] --image <image> --snap <snap>
示例:
1 | 对 vol01 镜像创建一个快照 |
展平克隆快照¶
此时如果想直接删除父快照是不被允许的,因为克隆镜像内还有依赖父镜像的数据,必须先把镜像展平。
1 | # rbd snap rm kube/vol01@clone --user kube |
展平时,可通过将数据从父快照复制到克隆镜像,进行 image 的“展平”操作。
注意:
- 展平克隆所需的时间随着映像大小的增加而延长;
- 用户无法删除克隆镜像所引用的快照,需要先平展父快照的每个克隆,然后才能删除快照。
把克隆镜像展平¶
让克隆镜像去把引用了别人的数据复制到自己这,之后它就是独立的个体了,不依赖任何:
- 命令:
rbd flatten [--pool <pool>] --image <image> --no-progress
1 | # rbd flatten kube/my_image01 |
取消快照保护¶
- 必须先取消快照保护,然后才能删除快照;
- 命令:
rbd snap unprotect [--pool <pool>] --image <image> --snap <snap>
- 命令:
1 | # rbd snap unprotect kube/vol01@clone |
删除父快照¶
1 | # rbd snap rm kube/vol01@clone |
9. 导入 image¶
1 | 下载一个 cirros 的镜像 |
十一、CephFS¶
经典文件系统概述¶
- 索引式文件系统将底层存储数据的磁盘空间切分为 “块”,并为每个文件对象所占用所有块建立一个索引表进行统一存放在一个称为“元数据区” 的空间中:
- 索引表就是块地址数组,每个数组元素就是块的地址,于是,一个文件对象的块可以分散存储到离散块空间中;
- 索引表的索引结构称为 inode,用于索引、跟踪一个文件对象的权限、隶属关系、时间戳和占据的所有的块等属性信息,不过却不包括文件名和文件内容本身。
- 文件名及其隶属的目录层级关系通过 Dentry 进行描述:
- 每个 Dentry 就像一个映射表,它保存了本级目录或者文件名以及紧邻的下一级目录或者文件的名称与各自 inode 的映射关系;
- 而 Dentry 自身也需要由专用的 inode 对象承载,它也拥有自己的 inode,于是这种映射便可组织出多级别层次来,这个多级别的层次起始于一个惟一的称之为 “根” 的起始点,从 而形成一个树状组织结构。
CephFS 概述¶
- CephFS 用于为 RADOS 存储集群提供一个 POSIX 兼容的文件系统接口:
- 基于 RADOS 存储集群将数据与元数据 IO 进行解耦;
- 动态探测和迁移元数据负载到其它 MDS,实现了对元数据 IO 的扩展;
- 第一个稳定版随 Jewel 版本释出;
- 自 Luminous 版本起支持多活 MDS(Multiple Active MDS)。
- 特性:
- 目录分片;
- 动态子树分区和子树绑定(静态子树分区);
- 支持内核及 FUSE 客户端;
- 其它尚未稳定特性还包括内联数据(INLINE DATA)、快照和多文件系统等;
MetaData(元数据) Server¶
- MDS 自身并不会直接存储任何数据,所有的数据均由后端的 RADOS 集群负责存储,包括元数据,MDS 本身更像是一个支持读写的索引服务
- CephFS 依赖于专用的 MDS(MetaData Server)组件管理元数据信息并向客户端输出一个倒置的树状层级结构:
- 将元数据缓存于 MDS 的内存中;
- 把元数据的更新日志于流式化后存储在 RADOS 集群上;
- 将层级结构中的的每个名称空间对应地实例化成一个目录且存储为一个专有的 RADOS 对象;

CephFS Components¶
- CephFS 库层包括 CephFS libcephfs 库,它在 librados 之上工作,代表 Ceph 文件系统。
- 最上层代表可以访问 Ceph 文件系统的两种类型的客户端。

创建 CephFS 存储池¶
CephFS 分别将元数据和数据放置于不同的存储池中,而且通常应该配置它们各自 使用专用的存储池,例如 cephfs-metadata 和 cephfs-data
ceph osd pool create cephfs-metadata 32ceph osd pool create cephfs-data 64
创建 CephFS
ceph fs new <fs-name> <metadata-pool> <data-pool>- 例如,以
cephfs-metadata为元数据池,以cephfs-data为数据池ceph fs new cephfs cephfs-metadata cephfs-data
状态查看
ceph fs status <fsname>ceph mds stat
之前在部署时创建了一个 ceph 的存储池,查看:
1 | # ceph osd pool ls | grep cephfs |
创建 CephFS 客户端账号¶
在集群上启用 CephX 认证,CephFS 的客户端在完成认证后方可挂载访问文件系统。
创建专用客户端账号,以 client.fsclient 为例:
1 | # 创建 fsclient 账号 |
注意:元数据池仅可由 MDS 访问,无须授权给客户端账号;另外,数据池上的权限指定应根据实际需要进行;
保存用户账号的密钥信息于 secret 文件,用于客户端挂载操作认证之用:
1 | ceph authtool -p -n client.fsclient /etc/ceph/ceph.client.fsclient.keyring > fsclient.key |
此密钥文件需要保存于挂载 CephFS 的客户端主机上,以 server01 为例:
1 | scp ceph.client.fsclient.keyring fsclient.key root@server01:/etc/ceph/ |
在 Linux 客户端中通过内核级挂载 CephFS¶
前提,客户端主机需要有以下环境:
- 内核模块
ceph.ko; - 已经安装好
ceph-common程序包; - 创建了
ceph.conf配置文件; - 有用于认证的密钥文件。
检查 ceph.ko 模块,如下:
1 | # modinfo ceph |
在 Server 端导出密钥文件
1 | 在 Server 端创建 keyring 文件 |
挂载
1 | 指定多个 mon 作为冗余,以防单点故障 |
编辑 fstab 配置开机自动挂载
1 | mon01:6789,mon03:6789:/ /data ceph name=fsclient,secretfile=/etc/ceph/fsclient.key,_netdev,noatime 0 0 |
在不支持内核级挂载的 Linux 客户端中,使用 FUSE 客户端¶
FUSE,全称 Filesystem in Userspace,用于非特权用户能够无需操作内核而创建文件系统。
如果客户端内核不支持 ceph 模块,那么可以使用用户级的挂载方式。
前提:
- 已经安装好
ceph-common程序,并创建了ceph.conf配置文件。 - 安装 ceph-fuse,这个程序不要求内核有 ceph 模块,但是在用户空间要安装一个程序包:
yum install ceph-fuse
和内核级挂载时使用的 client.fsclient.key 密钥文件不同,ceph-fuse 需要使用 keyring 格式的密钥文件:
1 | 在 Server 端创建 keyring 文件 |
挂载
1 | # 指定使用哪个用户 # 指定 mon # 指定挂载目录 |
编辑 fstab 配置开机自动挂载
1 | none /data fuse.ceph ceph.id=fsclient,ceph.conf=/etc/ceph/ceph.conf,_netdev,defaults 0 0 |
元数据分区¶
文件元数据的工作负载通常是一类小而密集的 IO 请求,因此很难实现类似数据读写 IO 那样的扩展方式。
分布式文件系统业界提供了将名称空间分割治理的解决方案,通过将文件系统根树及其热点子树分别部署于不同的元数据服务器进行负载均衡,从而赋予了元数据存储线性扩展的可能:
- 静态子树分区
- 静态 hash 分区
- 惰性混编分区
- 动态子树分区

Multi MDS(多主 MDS)¶
多主 MDS 模式是指 CephFS 将整个文件系统的名称空间切分为多个子树并配置到多个 MDS 之上,不过,读写操作的负载均衡策略不同,分别是子树切分和目录副本
- 将写操作负载较重的目录切分成多个子目录以分散负载;
- 为读操作负载较重的目录创建多个副本以均衡负载。
子树分区和迁移的决策是一个同步过程,各 MDS 每 10 秒钟做一次独立的迁移决策 ,每个 MDS 并不存在一个一致的名称空间视图,且 MDS 集群也不存在一个全局调度器负责统一的调度决策。
各 MDS 彼此间通过交换心跳信息(HeartBeat,简称 HB)及负载状态来确定是否要进行迁移、如何分区名称空间,以及是否需要目录切分为子树等。
管理员也可以配置 CephFS 负载的计算方式从而影响 MDS 的负载决策,目前,CephFS 支持基于 CPU 负载、文件系统负载及混合此两种的决策机制。
动态子树分区依赖于共享存储完成热点负载在 MDS 间的迁移,于是 Ceph 把 MDS 的元数据存储于后面的 RADOS 集群上的专用存储池中,此存储池可由多个 MDS 共享。
- MDS 对元数据的访问并不直接基于 RADOS 进行,而是为其提供了一个基于内存的缓存区以缓存热点元数据,并且在元数据相关日志条目过期之前将一直存储于内存中。
CephFS 使用元数据日志来解决容错问题
- 元数据日志信息流式存储于 CephFS 元数据存储池中的元数据日志文件上,类似于 LFS(Log-Structured File System)和 WAFL( Write Anywhere File Layout)的工作机制。
- CephFS 元数据日志文件的体积可以无限增长以确保日志信息能顺序写入 RADOS,并额外赋予守护进程修剪冗余或不相关日志条目的能力。
每个 CephFS 都会有一个易读的文件系统名称和一个称为 FSCID 标识符 ID,并且每个 CephFS 默认情况下都只配置一个 Active MDS 守护进程。
一个 MDS 集群中可处于 Active 状态的 MDS 数量的上限由 max_mds 参数配置,它控制着可用的 rank 数量,默认值为 1。
- rank 是指 CephFS 上可同时处于 Active 状态的 MDS 守护进程的可用编号,其范围从
0到max_mds-1; - 一个 rank 编号意味着一个可承载 CephFS 层级文件系统 目录子树 元数据管理功能的 Active 的 ceph-mds 守护进程编制,
max_mds的值为1时意味着仅有一个0号 rank 可用; - 刚启动的 ceph-mds 守护进程没有接管任何 rank,它随后由 MON 按需进行分配;
- 一个 ceph-mds 一次仅可占据一个 rank,并且在守护进程终止时将其释放;
- 一个 rank 可以处于下列三种状态中的某一种:
- Up:rank 已经由某个 ceph-mds 守护进程接管;
- Failed:rank 未被任何 ceph-mds 守护进程接管;
- Damaged:rank 处于损坏状态,其元数据处于崩溃或丢失状态; 在管理员修复问题并对其运行
ceph mds repaired命令之前,处于 Damaged 状态的 rank 不能分配给其它任何 MDS 守护进程。
1 | # ceph mds stat |
添加 mds 节点¶
在 ceph-admin 节点上执行:
1 | 初始化 mds 主机 |
Prometheus 的介绍页面:
https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice/index.html
未完。。。
十二、CRUSH¶
Cluster Map 包括:
- Moniter Map:维护当前集群的唯一标识,当前集群的位置、名称、地址、端口、版本等相关信息等等;
- OSD Map:包含集群自己的 ID,OSD 的创建时间,有多少个存储池,存储池、OSD、归置组自身的信息等等;
- PG Map:包含有多少个 PG,PG 的时间戳,PG 的状态,PG 的占满率等等;
- MDS Map:包含有多少个 MDS,有多少个活跃的,有多少个备用的等等;
- CRUSH Map:包含存储设备列表,故障域树状结构,存储数据时如何利用此树状结构的规则。
导出 CRUSH¶
ceph osd getcrushmap -o /tmp/mycrush.map.bin:获取当前集群运行图的二进制文件,包括当前集群树状结构的定义、归置规则的定义等;
crushtool -d /tmp/mycreshmap.bin -o ./mycrushmap.txt:反编译为文本文件;
查看这个 Crush 文件
1 | # cat crushmap.txt |
导入 CRUSH¶
crushtool -C mycrushmap.txt -o mycrushmap-v2.bin:编译为二进制文件;
ceph osd setcrushmap -i mycrushmap-v2.bin:注入回集群,即刻生效。
未完。。。
十三、RadosGW¶
未完。。。
十四、Ceph 启⽤ Dashboard V2¶
启⽤相关的模块:
1 | ~]$ ceph mgr module enable dashboard |
若使⽤ http 协议的 Dashboard V2,需要设定禁⽤ SSL 功能:
1 | ~]$ ceph config set mgr mgr/dashboard/ssl false |
若使⽤ https 协议的 Dashboard V2,需要以如下步骤⽣成证书及相关配置:
Dashboard 要通过 https 协议提供服务。管理员可配置其使⽤⾃动⽣成的⾃签证书,也可以为其提供⾃定义的证书 ⽂件,⼆者先其⼀即可。
若需要使⽤⾃签证书,运⾏如下命令⽣成⾃动⽣成证书即可:
1 | ~]$ ceph dashboard create-self-signed-cert |
若需要⾃定义证书,则应该通过合适的⽅式获取到相关证书。例如,以如下⽅式运⾏命令⽣成⾃定义的证书:
1 | ~]$ openssl req -new -nodes -x509 -subj "/O=IT/CN=ceph-mgr-dashboard" \ |
⽽后配置 dashboard 加载证书:
1 | ~]$ ceph config-key set mgr mgr/dashboard/crt -i dashboard.crt |
配置监听的地址和端⼝:
1 | ~]$ ceph config set mgr mgr/dashboard/server_addr 0.0.0.0 |
也可以分别为每个 mgr 实例配置监听的地址和端⼝,将下⾯命令格式中的 $name 替换为 mgr 实例的名称即可。
1 | ceph config set mgr mgr/dashboard/$name/server_addr $IP |
确认配置的结果:
1 | ~]$ ceph mgr services { "dashboard": "https://0.0.0.0:8443/" } |
重新启⽤ Dashboard V2
1 | ~]$ ceph mgr module disable dashboard |
配置管理员认证信息,命令格式:
1 | ceph dashboard set-login-credentials <username> <password> |
例如,为 admin 设置密码:
1 | ~]$ ceph dashboard set-login-credentials admin mageedu |
查看 mgr 节点主机:
1 | ~]$ ceph status |
⽽后通过相关节点的地址和端⼝访问服务。
十五、让 K8s 使用 ceph 的准成事项¶
在目标的 ceph 存储池代动态供给创建 image 是由 Kube-Controller-Manager 中的一个控制器实现的,这个控制器要在当前节点中找一个叫 rbd 的命令。遗憾的是,如果 K8s 是通过 kubeadm 部署的话,Kube-Controller-Manager 是运行为 Pod 的,所以这个 Pod 的镜像文件中需要有 rbd 命才行,但是默认这是没有的,而且也不支持额外安装。所以是通过 kubeadm 部署的 K8s 集群,只能手动提供 rbd 存储卷,而动态供给功能无法使用。
为了解决这个文件,必须在 K8s 集群中额外部署一个 external-provision,否则无法使用动态供给功能。所以每个节点上都要部署 external-provision,并且每个节点也都要有 ceph.conf 这个配置文件才可以。
未完。。。