简介:一份面向云服务管理与存储架构运维人员的Ceph块存储实战指南,聚焦分布式存储中RBD块设备的部署与应用。内容基于三节点实验集群,在Ubuntu 18.04环境下完成数据池创建、块设备镜像生成,并演示将镜像映射为Linux块设备、执行mkfs格式化、挂载及读写验证,同时涵盖集群健康状况与映射状态的检查方法。文中围绕存储池、镜像、映射、监控等核心指令展开,特别适合具备一定存储基础、希望在虚拟化或生产环境中落地Ceph方案的技术人员使用。资源为单一PDF文档,约286KB,以精简的实验步骤和命令输出呈现完整操作流程,便于本地查阅或对照实验。已有70人学习下载,虽体量不大,但胜在步骤清晰、重点集中。读者可从中获得一条从集群规划、RBD池创建、镜像生成到系统挂载使用的贯通路径,并了解rbd map、rbd showmapped、mkfs.ext4、mount、df等关键命令的实际用法,为后续研究快照、克隆等高级特性或调整大规模生产参数提供可复用的操作基础。
1. Ceph 块存储系统部署:为什么自己做而不是买一套
存储选型这件事,到后期基本是在算空间和运维成本的账。CEPH 块存储系统这几年在公有云上几乎是隐形的,真正落到自建机房,它反而是团队绕不开的默认答案。这篇内容不停在「装完集群、Dashboard 变绿」,而是把 CEPH 块存储系统的部署与应用串成一条能走通的闭环:集群组件怎么理解、网络与磁盘怎么规划、cephadm 怎么初始化、RBD 映像怎么挂到主机和虚拟机、上线前哪几组参数必须调。适合两类人:刚接手存储的运维,想在一周内把三节点测试集群跑起来;另一类是开发人员,需要弄清数据为什么落在某几块盘上,以及为什么某些 IO 会比其他 IO 慢。读之前不需要使用 CEPH 的经验,但最好熟悉 Linux 分区、网卡聚合和常用文件系统操作。
2. 块存储、RBD 与 Ceph 核心组件的对应关系
2.1 四个核心组件里,块存储真正需要的是哪两个
Ceph 集群常被概括成四个组件:Monitor(MON)、OSD、MDS、RGW。MON 维护集群映射、选举主节点并负责认证,客户端读写数据之前必须先联系 MON;OSD 负责把副本保存到物理盘上,是容量与吞吐的主力;MDS 只服务于 CephFS 文件系统;RGW 对外提供 S3 兼容的对象存储接口。把组件的职责边界先划清楚,后面规划资源才不会被「全组件都要部署」的惯性带偏。
| 组件 | 是否必需 | 主要职责 | 常见部署数量 |
|---|---|---|---|
| MON | 必需 | 维护集群映射、选举主节点、提供认证 | 3 或 5 |
| OSD | 必需 | 保存数据副本、响应客户端读写 | 三节点各 1 个以上 |
| MDS | RBD 不需要 | 管理 CephFS 元数据 | 块存储场景可不部署 |
| RGW | RBD 不需要 | 提供对象存储网关 | 块存储场景可不部署 |
只靠 MON + OSD 这一结论直接影响规划思路:不需要为 MDS 预留内存,不需要开 RGW 缓存,集群资源可以全部压到 OSD 上。生产环境 MON 建议部署奇数个并分散在不同故障域,OSD 数量决定总容量与冗余能力。例如 9 块 8TB 盘、副本数 3 的集群,总空间是 9×8=72TB,扣除副本后可用容量约 24TB,还要再预留 10% 给 PG 迁移和后台均衡,实际可用在 20TB 出头。忘记这 10% 余量的集群,会在容量接近 85% 时出现明显 IO 抖动,这是许多存储事故的起点。
2.2 RBD 是把分布式存储伪装成一块普通磁盘
RADOS Block Device(RBD)是 Ceph 的块存储接口。它把多个 OSD 上的对象抽象成一个连续块设备,客户端通过内核模块 rbd 或用户态 librbd 访问,看到的就是「一块硬盘」。RBD 和本地盘最大的差异是数据被切碎后散落在多台机器上,每次读写都要经过网络,因此网络质量对延迟的影响往往超过磁盘本身的顺序写速度。
理解这一点对调参帮助很大:客户端与 OSD、OSD 与 OSD 之间的带宽决定块设备吞吐上限,从万兆降到千兆,顺序 IO 可能下跌 80% 以上。RBD 默认关闭写回缓存,写操作要等副本全部落盘才返回,这是它在掉电后仍能保证不丢数据的根本原因,也是机械盘上随机写延迟偏高的来源。看到 RBD IO 慢,先不要怀疑磁盘健康,先查网络队列和网卡中断是否均匀分配。
2.3 PG、副本策略与 CRUSH 决定数据到底在哪块盘
RBD 映像在 Ceph 内部不连续存储,而是按对象大小切成对象,再由 CRUSH 算法把每个对象映射到一组 OSD。放置组 PG 是对象到 OSD 之间的中间聚合层,它让对象不需要单独记录位置,只要知道属于哪个 PG、PG 落在哪些 OSD 上,就能定位数据。副本数由 pool 的 size 和 min_size 控制,size=3 表示三副本,min_size=2 表示最少两副本在线才能接受写入。
ceph osd pool create rbd 128 128 replicated ceph osd pool set rbd size 3 ceph osd pool set rbd min_size 2第一行创建名为 rbd、PG 数为 128 的复制型存储池;第三、四行把副本策略设为三副本并允许两副本时保持写入。PG 数不能拍脑袋:单节点实验环境用 32,三节点每节点三块盘的测试集群取 128,生产建议把 PG 数设为 OSD 总数与每 OSD 期望 PG 数的乘积,再就近靠 2 的幂。PG 太多会让 OSD 内存占用升高,太少则数据分布不均,某些盘可能比其他盘多出 30% 负载。
存储池准备好以后,数据最终落盘由 CRUSH 规则决定。规则按主机、机架、机房划分故障域,副本会尽量分开,例如三副本默认拒绝把三个副本都放到同一台物理机上。部署时如果用了错误的 CRUSH 规则,会看到集群状态健康,但某台机器故障时所有 PG 同时失去副本,这是比容量估算更隐蔽的风险。
3. 用 cephadm 从头部署三节点 Ceph 集群
3.1 部署前的网络、磁盘与内核参数规划
Ceph 部署失败的最大来源不在命令难度,而在前置规划。生产环境建议公共网络与集群网络分离:公共网络承载客户端到 MON/OSD 的读写,集群网络承载 OSD 之间的副本同步、数据再均衡和心跳,两者用独立网卡,万兆起步。三节点测试环境至少要把 IP 分开,再把cluster_network指向独立网段,否则副本流量会挤占客户端 IO 带宽,表现就是 RBD 吞吐正常但延迟飘高。
| 规划项 | 建议值 | 说明 |
|---|---|---|
| 系统盘 | 100GB 以上 | 安装操作系统与容器运行时 |
| OSD 数据盘 | 每 OSD 独立整盘 | 不分区,避免与系统共享 IO |
| 公共网络 | 万兆 | 客户端挂载、Dashboard 访问 |
| 集群网络 | 万兆 | 副本同步、恢复、心跳 |
| 内存 | 每 OSD 4GB 以上 | MON 单独 2GB,OSD 尽量多于 4GB |
| 内核参数 | vm.swappiness=10 | 降低 swap 造成 IO 抖动 |
cephadm 以容器方式拉起 MON、OSD、MGR 等守护进程,宿主机只需要 Docker 或 Podman。没有外网镜像源的内网机房,提前把 cephadm 所需的容器镜像导出到内部 registry,再在 bootstrap 时指向内部仓库,就是日常说的离线安装,测试环境里能省掉大量拉取超时等待。还有一个容易被忽略的参数:osd_memory_target默认随总内存自动收敛,多 OSD 场景要确认它不会超过主机物理内存一半,否则多个 OSD 挤在一台机器上会互相抢缓存,延迟反而上升。
3.2 cephadm bootstrap 初始化集群的最小命令序列
先在每台主机写清 /etc/hosts,配好 SSH 免密,然后选中第一个节点执行 bootstrap。下面命令以 root 身份运行,会在当前节点创建 MON、MGR 和辅助组件,并输出 Dashboard 访问地址和初始密码。
cephadm bootstrap --mon-ip 192.168.1.10 --cluster-network 192.168.2.0/24 ceph orch host add node1 192.168.1.10 ceph orch host add node2 192.168.1.11 ceph orch host add node3 192.168.1.12 ceph orch apply mon node1,node2,node3--mon-ip指定当前节点对外提供 MON 服务的 IP;--cluster-network把副本流量引到独立网段。后面四条命令把另外两个节点加进集群,并把 MON 扩展到三台。bootstrap 完成后先执行ceph -s,看到HEALTH_OK再继续,否则后续所有操作都会在一个异常集群上反复报错,排查成本远比停下来修复高。
OSD 加入有两种方式:人工指定磁盘或用过滤器批量识别。三节点测试环境人工指定更可控,我一般会这么做:
ceph orch apply osd all-available-devices --unmanaged=true ceph orch device zap node1 /dev/sdb --force ceph orch device zap node2 /dev/sdb --force ceph orch daemon add osd node1:/dev/sdb ceph orch daemon add osd node2:/dev/sdb ceph orch daemon add osd node3:/dev/sdb--unmanaged=true让 cephadm 只识别磁盘不自动创建,防止它把系统盘或还在使用的数据盘当成空盘加进集群。device zap会擦除整个磁盘并重写分区表,执行前必须核对主机名和盘符,这个操作不可逆。每台机器只放一个 OSD 时,副本会跨主机分布,单机故障后的数据恢复依赖剩余两台主机的带宽,因此生产环境不要用双节点,至少三节点起步。
3.3 创建块存储专属存储池并验证副本策略
集群健康后,创建块存储池并固定副本策略。pool 名、PG 数、副本数这三个参数是后续所有 RBD 操作的前提,一旦改错,客户端挂载会立即报集群不健康。
ceph osd pool create rbd 128 128 rbd pool init rbd ceph osd pool set rbd size 3 ceph osd pool set rbd min_size 2 ceph osd pool application enable rbd rbdrbd pool init在池内生成 rbd 元数据对象,没有这一步,之后创建 RBD 映像会报 pool 未初始化;application enable rbd rbd告知集群这个 pool 承载 RBD 设备,让 Dashboard 能识别其类型。创建完成后用ceph osd pool ls detail检查 size、min_size 和 pg_num,确认 PG 状态为active+clean。如果长时间处于creating或peering,先确认所有 OSD 的时钟偏移,再查集群网络是否存在丢包,这两个原因占了 PG 卡住的大多数情况。
4. 把 RBD 映像挂进主机、虚拟机和容器
4.1 创建 RBD 映像并用内核模块映射成块设备
块存储池就绪后,第一步创建映像并映射到客户端主机。以下命令在客户端执行,使用集群管理员 keyring 认证。
rbd create image1 --size 10240 --pool rbd rbd feature disable rbd/image1 object-map fast-diff deep-flatten rbd map rbd/image1 mkfs.xfs /dev/rbd0 mkdir /data && mount /dev/rbd0 /data--size单位是 MB,10240 表示 10GB。第二行关闭与旧内核存在兼容问题的三个 feature,这是内核模块映射时最常见的失败原因。rbd map成功后,客户端会出现 /dev/rbd0,后面就是普通块设备流程:mkfs.xfs、mount、挂载使用。若 map 报 Permission denied,把集群节点的/etc/ceph/ceph.client.admin.keyring复制到客户端,并确认文件权限为 600。
| 命令 | 作用 | 常用参数 |
|---|---|---|
rbd create | 创建映像 | --sizeMB、--pool、--image-feature |
rbd map | 内核映射 | 默认读取 /etc/ceph 配置 |
rbd snap create | 创建快照 | pool/image@snap命名 |
rbd clone | 生成可写副本 | 指定源快照与目标名 |
内核映射方案适合裸金属业务或容器主机。容器场景里客户端主机的 rbd 模块如果加载不出来,可以退一步通过 rbd-nbd 访问,性能低于内核模块但可用性更好,所以能切内核优先切内核。
4.2 在 KVM 环境中把 RBD 作为虚拟磁盘
裸金属主机用内核,虚拟化环境更推荐让 QEMU 直接通过 librbd 访问 RBD,IO 路径不经过宿主机文件系统,性能与稳定性都更好。libvirt 虚拟机 XML 中把 disk type 设为 network、protocol 设为 rbd,或在运行中执行:
virsh attach-disk vm1 rbd:rbd/image1 /dev/vda --driver qemu --targetbus virtio这条命令把rbd:rbd/image1作为 virtio 磁盘挂给虚拟机,源地址写法是rbd:pool名称/映像名称。生产环境建议把 MON 地址写全,例如rbd:rbd/image1:mon_host=192.168.1.10:6789,192.168.1.11:6789,否则客户端只连一个 MON,该节点重启时重连时间会明显变长。宿主机需要提前安装qemu-block-rbd对应的 librbd 组件,否则 libvirt 报 driver 不存在。
本地文件虚拟磁盘的快照把镜像写入同一目录,管理零散、故障恢复也麻烦;RBD 把快照、克隆都放在集群侧,容量调度以 pool 为边界,扩容时不需要迁移虚拟机文件,这是私有云把 Ceph 块存储系统当作 KVM 默认后端的原因之一。
4.3 快照、克隆与回滚的日常维护
RBD 快照是时间点级别的只读镜像,升级系统或安装软件前打一个快照,出事快速回退。快照本身不占容量,只有写新数据产生差异时才累积空间占用。
rbd snap create rbd/image1@pre-upgrade rbd snap protect rbd/image1@pre-upgrade rbd clone rbd/image1@pre-upgrade rbd/image1-temp rbd flatten rbd/image1-tempsnap protect将快照置于保护状态,因为 clone 要求源快照不可删除;rbd clone基于快照生成可写副本,rbd flatten去掉副本与快照的依赖,让数据独立落盘。非保护快照可以直接用rbd snap rm删除,受保护快照必须先用rbd snap unprotect解除保护。执行rbd snap rollback前最好先卸载对应设备,滚回旧快照会覆盖当前写入数据,虚拟机场景里先停机再操作,避免文件系统不一致。
5. Ceph 上线前必调的参数与一次典型卡顿排查
5.1 客户端缓存与恢复流量的取舍
RBD 内核模块默认关闭写回缓存,数据库场景下安全,但测试和一般应用场景延迟偏高。打开缓存:
echo 1 > /sys/module/rbd/parameters/rbd_cache ceph config set osd osd_max_backfills 2 ceph config set osd osd_recovery_max_active 3第一行打开内核模块写缓存,把顺序写延迟压低一个量级,代价是主机掉电可能丢少量未落盘数据。第二、三行控制坏盘后的恢复速度,osd_max_backfills调大恢复快,但会挤占业务 IO,生产环境保持在 2 或 3 更稳。更稳妥的做法是用定时任务在业务低峰期调高恢复参数,白天恢复为 0,避免大半夜被恢复任务拖垮整条链路。
5.2 用 prometheus 指标判断瓶颈在哪一端
Ceph 自带 prometheus exporter,开启 mgr prometheus 模块后从 9283 端口抓取数据,配合 prometheus 监控部署与 Grafana,很快能看到节点级延迟与 PG 状态。重点看ceph_pg_degraded与ceph_osd_utilization两个指标:前者非零先处理 PG,不要调客户端参数;后者超过 0.85 说明容量接近上限,需要扩充 OSD 而不是排查延迟。ceph_rbd_read_latency偏高但前两个指标正常,问题多半在网络或客户端,优先排查网卡多队列与中断绑定。
5.3 卡在 active+undersized 时的单步验证
PG 状态出现active+undersized说明副本数不足。按顺序执行:
ceph osd tree ceph pg dump | grep stuck ceph osd safe-to-destroy <osd_id>ceph osd tree定位掉线 OSD;ceph pg dump | grep stuck输出长时间卡住的 PG,把 pgid 与失败 OSD 对上;最后一条命令判断下线盘是否能直接移除。返回 safe 就换盘,返回 not safe 说明该 OSD 上仍有数据未完成复制,等集群补完副本后再操作。整个过程不需要重启客户端,集群会自动进入恢复流程,期间 IO 抖动属于正常现象,先核对 OSD 日志确认是硬件故障还是网络抖动,再决定是否人工介入。
本文还有配套的精品资源,点击获取