关于 Ceph 系列其他文章的传送门
-
《 Ceph 集群部署 》 您当前所在位置

一、基础概念¶
存储设备的类型¶
- DAS(直接附加存储):IDE、SATA、SCSI、SAS、USB;
- NAS(网络附加存储):NFS、CIFS;
- SAN(存储区域局域网络):也是网络存储,只不过提供给客户端的存储接口是块设备接口。
- SCSI 协议只能使用 SCSI 专用线来传输数据,但是因为 SCSI 协议是分层的,所以有人就把底层的物理传输接口改换为光纤和以太网,就有了 FC SAN、iSCSI。
Ceph 的基础概念¶
Ceph 是什么?¶
Ceph 是一个对象(object)式存储系统,它把每一个待管理的数据流(例如一个文件) 切分为一到多个固定大小的对象数据,并以其为原子单元完成数据存取
- 对象数据的底层存储服务是由多个主机(host)组成的存储集群,该集群也被称之为 RADOS(Reliable Automatic Distributed Object Store)存储集群,即可靠、自动化、 分布式对象存储系统;
- 底层存储服务由 librados 接口向外提供,这个接口是 RADOS 存储集群的 API,它支持 C、C++、Java、Python、Ruby 和 PHP 等编程 语言。
存储数据时,可以自己编写一个客户端软件,去调用 librados 的 api 接口。而 ceph 为没有编程能力的用户在 librados api 之上提供了 2 个 api 接口,和一个不依赖 librados api 的接口:
- RBD:基于内核模块 librbd 给系统作为块设备使用,或者直接给 qemu 作为虚拟机的块设备使用;
- RADOSGW:通过 http、https 协议提供对象存储。
- CEPH FS:这个接口不依赖于 librados,是 RADOS 集群的一部分,提供文件存储功能,J 版后才生产可用,可以直接挂载;

Ceph 集群的主要组件¶
- osd:通常情况下,主机上的每一块磁盘设备被称为一个 osd(Object Storage Device),而这个主机被称为 host,由多个 host 组成的集群被称之为 RADOS Cluster。在集群中,还有其他的节点,比如元数据服务器(mon)和 mgr;
- mon:用来记录集群有多少个 host,每个 host 中有多少个 osd,每个 osd 是否健康等等的信息,持有整个集群的运行状态图。所以 mon 节点是用来存放集群元数据,而非文件元数据,也称之为监视器。因此需要做高可用,内部使用 Paxos 协议实现;
- mgr:在 L 版之后引入了 mgr,负载监控 Ceph 集群。之前是由 mon 负责。
CRUSH 算法存数据的步骤¶
通过某一类客户端接入,接入的时候借助 ceph 的 api 接口,把一个文件切割成固定大小的对象,把对象的名字做 Hash,然后对所在 Pool 中的 PG 总数做一致性 Hash 计算,结果会落在某一个 PG 上。
PG 和 Pool 是逻辑概念,不存在实体,每一个 Pool 叫一个存储池,存储池的容量大小取决于底层的存储空间,而数据最终放在哪个 osd 上,是靠 CRUSH 完成的。
PG 根据副本数量和存储池的类型,找到足量的 osd 来存储,一个 PG 内的所有对象,都放在同一个 osd 中,数据第一次先写到主 osd 中,再由主 osd 同步给其他的从 osd。

推荐阅读:https://www.liukui.tech/2019/05/10/存储基础和Ceph/
Monitors 的主要作用¶
mon 是一个运行在主机上的守护进程,被称为 ceph-mon,维护着集群运行图(Cluster Map),包括 5 个集群运行图:
- monitor map
- manager map
- OSD map
- CRUSH map
- PG map
mon 节点还负责维护认证信息,并通过 CephX 协议进行认证。如果客户端规模大,mon 节点可能会成为瓶颈,不过好在 mon 是无状态的,可以部署多个,一般是 3 个起的奇数个。
Managers 的主要作用¶
manager 也是一个运行在主机上的守护进程,被称为 ceph-mgr,应该有两个或以上数量的节点。跟踪运行时的指标数据和 Ceph 集群的运行状态,包括存储空间利用率、性能指标、节点的负载等等。
Ceph OSDs 的主要作用¶
每个 OSD 都会有对应的守护进程,专用于管理一个 OSD。OSD 用于存储数据,负责数据的复制、恢复、平衡,给 Monitors 和 Managers 提供监视信息。
MDSs 的主要作用¶
Metadata Server 的作用是当使用 Ceph Filesystem 时,用来存储文件的元数据,不是必要组件。
当面向客户端提供服务时,CephFS 和 RADOSFS 都需要单独运行一个守护进程,而 ODS 则不需要,它是依靠在 libredos 上的一个模块来提供服务。
管理节点(Admin Host)¶
Ceph 的常用管理接口是一组命令行工具程序,例如 rados、ceph、rbd 等命令,管理员可以从某个特定的 Mon 节点执行管理操作,但也有人更倾向于使用专用的管理节点;
事实上,专用的管理节点有助于在 Ceph 相关的程序升级或硬件维护期间为管理员提供一个完整的、独立的并隔离于存储集群之外的操作环境,从而避免因重启或意外中断而导致维护操作异常中断。

二、部署 Ceph 集群¶
1. Ceph 部署工具¶
- ceph-depoy:是 ceph 原生的部署工具,借助 SSH、sudo 和一些 Python 模块,来完成 ceph 的部署和一些后期的维护。
- ceph-ansible:借助 ansible 完成部署,是功能最完整的工具,但是需要熟练的使用 ansible。
2. 部署架构¶
| 主机地址 | 主机名称 | 主机角色 |
|---|---|---|
| 192.168.50.11 | mon01.monster.com | mon、osd、mgr、mds |
| 192.168.50.12 | mon02.monster.com | mon、osd、mgr |
| 192.168.50.13 | mon03.monster.com | mon、osd、mgr |
| 192.168.50.14 | osd04.monster.com | osd、rgw、mgr |
| 192.168.50.15 | ceph-admin.monster.com | ceph-admin |
| 192.168.50.100 | client.monster.com | client |
-
硬盘:
192.168.50.11-14:为 osd 节点,各有 3 块硬盘;192.168.50.11-13:同时为 mon 节点;192.168.50.15:为 ceph-admin 管理节点,使用 ceph-deploy 程序通过 SSH 部署和控制其他节点,为了安全性,应该使用普通账户,通过 sudo 执行管理员操作。192.168.50.100:作为 ceph 的客户端使用 ceph 的各种存储服务。
-
网络:
- public network:
192.168.50.0/24,面向客户端提供服务的网络,南向网络; - cluster network:
10.0.0.0/24:专门处理集群内部工作的网络,东西网络;
- public network:

3. 准备工作¶
系统环境¶
注意配置好:
- 时间同步;
- 关闭 SELinux;
- 关闭防火墙。
并在所有节点配置本地 Hosts 文件如下:
1 | 192.168.50.11 mon01 osd01 mon01.monster.com osd01.monster.com |
Ceph 目前发布到 14.2.5 Nautilus 版本,版本信息参考 Ceph 官方 Version 页面:https://docs.ceph.com/docs/master/releases/
为了速度更快一些,这里安装时使用阿里云的镜像仓库,在类似这样的目录下 https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch/,有一个 ceph-release-XXX 的 rpm 包,能够在主机上自动创建 yum 仓库的配置文件。
复制文件链接,在 ceph-admin 主机上直接安装 rpm 包:
1 | # yum install https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch/ceph-release-1-1.el7.noarch.rpm |
自动创建了 yum 仓库的配置文件:
1 | # cat /etc/yum.repos.d/ceph.repo |
安装 epel,会依赖到 epel 中的程序:
1 | # yum install epel-release |
创建部署 Ceph 的特定用户账号¶
部署工具 ceph-deploy 必须以普通用户登录到 Ceph 集群的各目标节点,且此用户需要拥有无密码使用 sudo 命令的权限,以便在安装软件及生成配置文件的过程中无需中断配置过程。
不过,较新版的 ceph-deploy 也支持用 username 选项提供可无密码使用 sudo 命令的用户名(包括 root,但不建议这样做)。另外,使用 ceph-deploy --username {username} 命令时,指定的用户也需要能够通过 SSH 协议自动认证并连接到各 Ceph 节点,以免 ceph-deploy 命令在配置中途需要用户输入密码。
首先需要在所有节点以管理员的身份创建一个专用于 ceph-deploy 的特定用户账号,例如 cephadm。
在所有 Ceph 节点创建新用户 cephadm,并为其设置密码:
1 | useradd cephadm |
而后,确保这些节点上新创建的用户 cephadm 都有无密码运行 sudo 命令的权限。
1 | echo "cephadm ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/cephadm |
配置用户基于密钥的 ssh 认证¶
ceph-deploy 命令不支持运行中途的密码输入,因此,必须在管理节点 ceph-admin 上生成 SSH 密钥并将其公钥分发至 Ceph 集群的各节点上。
下面直接以 cephadm 用户的身份生成 SSH 密钥对:
1 | su - cephadm |
向自己认证密钥:
1 | [cephadm@ceph-admin ~]$ ssh-copy-id cephadm@localhost |
而后把密钥目录 .ssh 复制到其他 Ceph 节点:
1 | [cephadm@ceph-admin ~]$ scp ./ssh cephadm@osd01:/home/cephadm/ |
在管理节点安装 ceph-deploy¶
Ceph 存储集群的部署过程,可全程通过管理节点的 ceph-deploy 进行,这里首先在管理节点安装 ceph-deploy 及其依赖到的程序包:
1 | [root@ceph-admin ~]# yum update |
4. 部署 RADOS 存储集群¶
初始化 RADOS¶
1、首先在管理节点上以 cephadm 用户创建集群相关的配置文件目录,保存了第一个所维护的集群的所有配置信息:
1 | su - cephadm |
2、初始化集群,创建集群配置文件:
在初始化集群时,需要指定第一个 mon 节点,会自动生成集群的配置文件,命令格式为:
ceph-deploy new {initial-monitor-node(s)}。
在本示例中,mon01 即为第一个 mon 节点名称,其名称必须与节点当前实际使用的主机名称保存一致。可以同时指定多个 mon,也可以先只指定 1 个,以后再添加。
--public-network:指定对外提供服务的网络的网段(南北网络);--cluster-network:指定集群内部网络的网段(东西网络);
1 | 注意要在刚刚创建的 ceph-cluster 目录中执行 |
运行上面的命令即可生成初始配置,这个初始化过程 ceph-deploy new ... 会完成如下操作:
- 在本地生成集群的配置文件;
- 在本地生成密钥环;
- 在目标节点安装 yum 仓库的 rpm 包;
- 在目标节点安装 ceph 集群所需要的每一个程序包;
- 试图启动目标节点上的 ceph-mon 进程;
安装 Ceph 集群¶
ceph-deploy 命令能够以远程的方式连入 Ceph 集群各节点完成程序包安装等操作,安装的命令格式如下:
ceph-deploy install {ceph-node} [{ceph-node} ...]。
因此,若要将 mon01、mon02、mon03 和 osd04 配置为 Ceph 集群节点,则执行如下命令即可。
不过且慢,不要安装,先看看下面那条。
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy install --release nautilus mon01 mon02 mon03 osd04 |
考虑到 ceph-deploy 是串行安装软件,且访问国外仓库速度慢,且对软件版本不完全可控,还是建议提前在各节点,先手动安装 ceph 的程序包。
在各 ceph 节点安装:
1 | 安装 yum 配置文件 |
不过就算已经通过手动的方式在各节点安装了程序包,也需要在 ceph-admin 节点再执行一次 install 操作,来完成安装程序外的一些其他的配置。
但是默认情况下运行 install 时会重新下载 repo 文件并重新安装一次程序,所以要使用如下参数 --no-adjust-repos 明确告知不要调整 repo 文件,否则调整 repo 文件后可能会重新安装程序。
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy install --no-adjust-repos --release nautilus mon01 mon02 mon03 osd04 |
分发密钥¶
1、通过读取当前目录下的集群配置文件来初始化 mon 节点,并收集所有密钥,:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy mon create-initial |
如果没有报错,说明 mon01 节点已经初始化完成了,应该已经运行了 ceph-mon 守护进程。还会生成很多 KV 文件:
ceph.bootstrap-XXX:各组件引导启动的密钥;ceph.client.admin.keyring:客户端密钥,拥有使用整个集群所有资源的权限;
2、把配置文件 ceph.conf 和客户端密钥拷贝 Ceph 集群各节点,以免得每次执行 ceph 命令行时不得不明确指定 mon 节点地址和 ceph.client.admin.keyring 密钥的路径。
ceph-deploy admin:复制配置文件和客户端密钥文件;ceph-deploy config:只复制配置文件。
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy admin mon01 mon02 mon03 osd04 ceph-admin |
而后在需要运行 ceph 命令的的节点上,使用 root 去设定用户 cephadm 能够读取 /etc/ceph/ceph.client.admin.keyring 文件,否则 cephadm 用户将无法使用 ceph 命令管理集群,只能由 root 账户管理集群:
1 | setfacl -m u:cephadm:r /etc/ceph/ceph.client.admin.keyring |
安装 Manager¶
1、把 mons01 配置为 Manager 节点,启动 ceph-mgr 进程(仅 Luminious 以上版本):
1 | ceph-deploy mgr create mon01 |
2、在 Ceph 集群内的节点上以 cephadm 用户的身份运行如下命令,测试集群的健康状态:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph -s |
5. 向 RADOS 集群添加 OSD¶
列出并擦净磁盘¶
ceph-deploy disk list 命令可以检查并列出 OSD 节点上所有可用的磁盘的相关信息:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy disk list mon01 mon02 mon03 osd04 |
而后,在管理节点上使用 ceph-deploy disk zap 命令擦除计划专用于 OSD 磁盘上的所有分区表和数据以便用于 OSD。
命令格式为 ceph-deploy disk zap {osd-server-name} {disk-name},需要注意的是此步会清除目标设备上的所有数据。
下面分别擦净 mon01、mon02、mon03 和 osd04 上用于 OSD 的磁盘设备:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy disk zap mon01 /dev/sdb /dev/sdc /dev/sdd |
提示:若设备上此前有数据,则可能需要在相应节点上以 root 用户使用 ceph-volume lvm zap --destroy {DEVICE} 命令进行擦净。
添加 OSD¶
早期版本的 ceph-deploy 命令支持将添加 OSD 的过程分为两个步骤:“准备 OSD”和“激活OSD“,但新版本中,此种操作方式已经被废除,添加 OSD 的步骤只能由命令 ceph-deploy osd create {node} --data {data-disk} 一次完成,默认使用的存储引擎为 bluestore。
如下命令即可分别把 mon01、mon02、mon03 和 osd04 上的设备名为 sdb、sdc、sdd 的硬盘添加为 OSD:
1 | for i in {b..d}; do ceph-deploy osd create mon01 --data /dev/sd$i; done |
而后可使用 ceph-deploy osd list 命令列出指定节点上的 OSD:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy osd list mon01.moster.com mon02.moster.com mon03.moster.com osd04.moster.com |
管理员也可以使用 ceph 命令查看 OSD 的相关信息:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph osd stat |
6. 从 RADOS 集群移除 OSD¶
Ceph 集群中的一个 OSD 通常对应于一个设备,且运行于专用的守护进程。在某 OSD 设备出现故障,或管理员出于管理之需确实要移除特定的 OSD 设备时,需要先停止相关的守护进程,而后再进行移除操作。对于 Luminous 版及其之后的版本来说,停止和移除的命令格式分别如下所示:
- 停用设备:
ceph osd out {osd-num} - 停止进程:
sudo systemctl stop ceph-osd@{osd-num} - 移除设备:
ceph osd purge {id} --yes-i-really-mean-it
若在 ceph.conf 配置文件中,静态定义了类似如下的 OSD 配置信息时,管理员则需要在删除 OSD 之后手动将其删除。
1 | [osd.1] |
而对于 Luminous 之前的版本,管理员需要依次手动执行如下步骤删除 OSD 设备:
- 于 CRUSH 运行图中移除设备:
ceph osd crush remove {name} - 移除 OSD 的认证:
key:ceph auth del osd.{osd-num} - 最后移除 OSD 设备:
ceph osd rm {osd-num}
7. 测试上传/下载数据对象¶
存取数据时,客户端必须首先连接至 RADOS 集群上的某个存储池,而后根据对象名称由相关的 CRUSH 规则完成数据对象寻址。
于是,为了测试集群的数据存取功能,这里首先创建一个用于测试的存储池 mypool,并设定其 PG 数量为 32 个。
1 | 创建 pool |
在 ceph 中有高级命令和底层命令,像 ceph 就是高级命令,而 rados 就是底层命令。
而后即可将测试文件上传至存储池中,但是到目前我们还没有部署 CephFS 或 RadosGW,所以先使用底层的 rados 命令通过 rados 自己的 api 上传文件。
例如:使用 rados put 命令将 /etc/issue 文件上传至 mypool 存储池,对象名称依然保留为文件名 issue,而 rados ls 命令则可以列出指定存储池中的数据对象。
1 | rados put issue /etc/issue --pool=mypool |
使用 ceph osd map 命令可以获取到存储池中数据对象的具体位置信息:
1 | ceph osd map mypool issue |
删除数据对象,rados rm 命令是较为常用的一种方式:
1 | rados rm issue -p mypool |
直接删除存储池的命令存在数据丢失的风险,于是 Ceph 默认禁止此类操作。
管理员需要在 ceph.conf 配置文件中启用支持删除存储池的操作后,方可使用类似如下命令删除存储池。启用配置的方式 删除存储池
1 | ceph osd pool rm mypool mypool --yes-i-really-really-mean-it |
8. 扩展 Ceph 集群¶
扩展监视器节点¶
Ceph 存储集群需要至少运行一个 Ceph Monitor 和一个 Ceph Manager,但是在生产环境中,为了实现高可用性,Ceph 存储集群通常运行多个 Monitor,以免单监视器故障导致整个存储集群崩溃。Ceph 使用 Paxos 算法,该算法需要半数以上的监视器(大于 n/2,其中 n 为总监视器数量)才能形成法定人数。尽管此非必需,但奇数个监视器往往更好。
语法:使用 ceph-deploy mon add {ceph-nodes} 命令可以一次添加多个监视器节点到集群中。
例如,下面的命令可以将集群中的 mon02 和 mon03 也运行为监视器节点:
提示:之前已经初始化过 mon 了,不要再初始化,使用 add 添加即可。
1 | 这里使用短格式 |
设置完成后,可以在 ceph 客户端上查看监视器状态及法定人数的选举状态:
1 | ceph quorum_status --format json-pretty |
扩展 Manager 节点¶
Ceph Manager 守护进程以 Active/Standby 的模式运行,部署其它 ceph-mgr 守护程序可确保在 Active 节点或其上的 ceph-mgr 守护进程故障时,其中的一个 Standby 实例可以在不中断服务的情况下接管其任务。
语法:ceph-deploy mgr create {new-manager-nodes} 命令可以一次添加多个 Manager 节点。
下面的命令可以将 mon02 节点作为备用的 Manager 运行:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy mgr create mon02 |
三、开启 Ceph 存储集群的访问接口¶
使用块设备接口 RBD¶
Ceph 块设备,也称为 RADOS 块设备(简称 RBD),是一种基于 RADOS 存储系统支持超配(thin-provisioned)、可伸缩的条带化(Object)的数据存储系统,它通过 librbd 库与 OSD 进行交互。
RBD 为 KVM 等虚拟化技术和云 OS(如 OpenStack 和 CloudStack)提供高性能和无限可扩展性的存储后端。这些系统依赖于 libvirt 和 QEMU 程序,与 RBD 进行集成。
客户端基于 librbd 库即可将 RADOS 存储集群用作块设备,不过,用于 rbd 的存储池需要事先启用 rbd 功能并进行初始化。
例如,使用下面的命令创建一个名为 rbddata 的存储池,在启用 rbd 功能后对其进行初始化:
1 | ceph osd pool create rbdpool 64 |
不过,rbd 存储池并不能直接用于块设备,而是需要事先在其中按需创建映像(image),并把映像文件作为块设备使用。
rbd 命令可用于创建、查看及删除块设备相对的映像(image),以及克隆映像、创建快照、将映像回滚到快照和查看快照等管理操作。
例如,使用下面的命令能够创建一个名为 myimg 的映像:
1 | 有两种写法,效果一样 |
映像的相关信息则可以使用 rbd info 命令获取:
1 | [cephadm@ceph-admin ceph-cluster]$ rbd --image myimg --pool rbdpool info |
在客户端主机上,用户通过内核级的 rbd 驱动识别相关的设备,即可对其进行分区、创建文件系统并挂载使用。
启用 radosgw 接口¶
RGW 并非必须的接口,仅在需要用到与 S3 和 Swift 兼容的 RESTful 接口时才需要部署 RGW 实例。
语法:ceph-deploy rgw create {gateway-node}
例如,使用下面的命令用于把 osd04 部署为 rgw主机:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy rgw create osd04 |
部署完成后,使用 ceph -s 命令,其中 services 一段中会输出相关信息:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph -s |
默认情况下,RGW 实例监听于 TCP 协议的 7480 端口,需要修改时,可以通过在运行 RGW 的节点上编辑其主配置文件 ceph.conf 进行修改,相关参数如下所示:
1 | [client] |
而后需要重启相关的服务:
- 语法:
systemctl restart ceph-radosgw@rgw.{node-name}
例如重启 osd04 上的 RGW,可以以 root 用户运行如下命令:
1 | systemctl restart ceph-radosgw@rgw.osd03 |
RGW 会在 rados 集群上生成包括如下存储池的一系列存储池:
1 | ceph osd pool ls |
RGW 提供的是 REST 接口,客户端通过 http 与其进行交互,完成数据的增删改查等管理操作。
启用文件系统 CephFS 接口¶
CephFS 需要至少运行一个元数据服务器(MDS)守护进程(ceph-mds),此进程管理在 CephFS 上存储的文件相关的元数据,并协调对 Ceph 存储集群的访问。因此,若要使用 CephFS 接口,需要在存储集群中至少部署一个 MDS 实例。
语法:ceph-deploy mds create {ceph-node}:这个命令可以完成此功能。
例如,在 mon01 上启用 MDS:
1 | [cephadm@ceph-admin ceph-cluster]$ ceph-deploy mds create mon01 |
查看 MDS 的相关状态可以发现,刚添加的 MDS 处于 Standby 模式:
1 | ceph mds stat |
在使用 CephFS 之前需要事先于集群中创建一个文件系统,并为其分别指定元数据和数据相关的存储池。
下面创建一个名为 cephfs 的文件系统用于测试,它使用 cephfs-metadata 为元数据存储池,使用 cephfs-data 为数据存储池:
1 | ceph osd pool create cephfs-metadata 64 |
而后即可使用命令 ceph fs status 查看文件系统的相关状态,例如:
1 | ceph fs status cephfs |
此时,MDS 的状态已经发生了改变:
1 | ceph mds stat |
随后,客户端通过内核中的 cephfs 文件系统接口即可挂载使用 cephfs 文件系统,或者通过 FUSE 接口与文件系统进行交互。