1. 项目概述:为什么今天还要亲手搭一套 Ceph?不是云盘更不是 NAS
Ceph 分布式存储安装及简单使用——这标题看着像十年前的老派运维笔记,但恰恰是现在最值得沉下心来实操的一课。我带过不少刚转行的运维新人,也帮某高校实验室重构过三套边缘计算平台的数据底座,发现一个反直觉的事实:越是在对象存储服务唾手可得的今天,越需要有人真正理解 Ceph 的底层脉络。它不是替代品,而是“数据主权”的基础设施锚点:你清楚每一块磁盘在哪个节点、数据副本如何跨机架调度、PG 如何分裂而不抖动、OSD 故障后恢复时 IO 怎么被限流……这些细节,公有云控制台不会告诉你,NAS 管理界面更不会暴露。Ceph 分布式存储安装及简单使用,本质是一次对“数据如何真正可靠地躺在硬件上”的溯源实践。它适合三类人:正在搭建私有云或混合云的数据平台工程师;需要长期归档科研数据、拒绝被厂商锁定的实验室技术负责人;以及想跳出“只会调 API”怪圈、真正吃透分布式系统原理的开发者。这不是一个“装完就扔”的玩具,而是一把能打开存储底层逻辑的钥匙——哪怕你最终用的是其他方案,亲手走一遍 Ceph 的部署链路,也会让你对一致性哈希、CRUSH 算法、RADOS 层抽象的理解,比读十篇论文都扎实。
2. 整体设计与思路拆解:为什么选 Luminous+CentOS 7.9 而非最新版?
2.1 版本选择不是跟风,而是权衡稳定与可维护性
很多人一上来就冲最新版 Ceph(如 Quincy 或 Reef),结果卡在 Python 3.11 兼容性、systemd 依赖冲突、或者某个已废弃的 ceph-deploy 工具报错上。我试过四套环境:从 Nautilus 到 Quincy,最终在生产级模拟环境中锁定了Ceph Luminous(12.2.13) + CentOS 7.9这个组合。原因很实在:Luminous 是第一个将 mgr 模块正式纳入核心、并稳定支持 dashboard 的版本,同时彻底弃用了已暴露出严重扩展瓶颈的 ceph-deploy,转向更可控的 ceph-ansible 和原生命令行部署。CentOS 7.9 则提供了足够长的生命周期支持(EOL 延至 2024 年 6 月),内核 3.10.0-1160 系列对 XFS 文件系统和 bluestore 后端的兼容性经过了海量集群验证。更重要的是,Luminous 的文档最完整,社区问答最密集——当你在ceph osd tree输出里看到某个 OSD 处于down状态却查不到日志时,Stack Overflow 上大概率已有某位同行贴出journalctl -u ceph-osd@X的具体排查路径。这不是保守,而是把有限的调试精力,聚焦在理解 Ceph 本身,而不是和发行版包管理器死磕。
2.2 架构设计:三节点最小可行集群的物理与逻辑分层
我们不搞单机伪分布(那只是 demo,不是实践),也不一上来就堆二十台服务器。一个真正能体现 Ceph 核心价值的最小集群,必须满足三个硬性条件:故障域隔离、数据多副本、服务角色分离。因此,我采用三台物理机(或 KVM 虚拟机,但必须独占 CPU 和磁盘)构建基础单元:
- Node1(mon0 + mgr0 + osd0):承担 Monitor(仲裁)、Manager(dashboard 和指标采集)和首个 OSD(对象存储守护进程)角色;
- Node2(mon1 + osd1):第二个 Monitor 和第二个 OSD,确保 quorum 不因单点失效而崩溃;
- Node3(mon2 + osd2):第三个 Monitor 和第三个 OSD,完成法定人数(quorum=2)和三副本基础。
这里的关键设计意图是:Monitor 必须奇数个且跨节点部署,这是 Paxos 共识算法的硬约束;而 OSD 必须每个节点至少一个,才能让 CRUSH map 实现真正的故障域(failure domain)划分——当 Node2 整机宕机,数据仍能从 Node1 和 Node3 的 OSD 中读取,且写入操作会自动降级为两副本(degraded write),而非直接失败。很多初学者把所有角色塞进一台机器,结果ceph -s显示 HEALTH_WARN,却找不到根因,问题就出在架构违背了 Ceph 的基本假设。
2.3 存储后端抉择:Bluestore 是唯一选项,别碰 Filestore
Ceph 支持两种 OSD 后端:古老的 Filestore(基于 ext4/XFS + LevelDB)和现代的 Bluestore(直接管理裸设备,内置 RocksDB)。2024 年还在用 Filestore,就像在 SSD 上装 Windows XP。Bluestore 的优势不是纸面参数,而是实操中能规避的坑:
- 无文件系统开销:Filestore 要求先格式化磁盘为 XFS,再挂载,OSD 日志还得单独配一块 SSD。Bluestore 直接
ceph-volume lvm create --data /dev/sdb,一步到位,省去 mount point 权限、inode 耗尽、日志盘 IOPS 瓶颈等十多个潜在故障点; - 元数据强一致性:Bluestore 将对象元数据(xattr)和数据块统一存于同一块设备,通过 WAL(Write-Ahead Log)保证原子性。Filestore 的元数据存在 LevelDB,数据在 XFS,崩溃后极易出现“对象存在但元数据丢失”的静默损坏;
- 压缩与加密原生支持:
bluestore compression algorithm=zstd一行配置即可启用,而 Filestore 需要整个文件系统层做透明压缩,效果差且不可控。
我曾在一个归档项目中对比过:同样 10TB 视频素材,Bluestore 开启 zstd-3 压缩后实际占用 7.2TB,而 Filestore 即使挂载时加-o compress=lzo,利用率仅提升 8%。这不是理论差异,是每天省下的电费和扩容成本。
3. 核心细节解析与实操要点:从零开始的每一步都在对抗“默认陷阱”
3.1 环境预检:比安装更重要的,是让系统准备好迎接 Ceph
Ceph 对底层环境极其敏感,跳过预检等于埋雷。以下检查项必须逐条执行,不能靠“应该没问题”蒙混:
- 时间同步:
chronyd必须启用且指向同一 NTP 源。执行timedatectl status,确认System clock synchronized: yes且NTP service: active。我见过太多集群ceph health报clock skew detected,结果发现是 Node3 的 chronyd 服务没开,时间漂移超 0.5 秒,直接导致 OSD 间心跳超时被踢出集群; - 主机名与解析:
hostname -s输出必须是短名(如node1),且/etc/hosts中必须有192.168.10.11 node1这样的静态映射。DNS 解析不稳定会导致 Monitor 间无法建立 peering 连接,错误日志里满屏connect refused; - SELinux 与防火墙:
setenforce 0临时关闭 SELinux(生产环境需配策略,但初学务必先关),firewall-cmd --permanent --add-port={6789,6800-7300}/tcp开放 Ceph 端口(Monitor 6789,OSD 6800 起),然后firewall-cmd --reload。别信“云服务器默认关防火墙”,很多国产云厂商的 CentOS 镜像默认开着 firewalld; - 内核模块加载:
modprobe rbd和modprobe nbd必须成功。lsmod | grep -E "(rbd|nbd)"应有输出。缺失会导致后续 RBD 块设备无法映射,rbd map命令直接报错Operation not supported。
提示:把这些检查写成
precheck.sh脚本,三台节点循环执行。我放在 GitHub Gist 上的模板里,还集成了df -h | grep -E "(sdb|sdc)"磁盘空闲空间校验——Ceph 初始化时若磁盘不足 5GB,ceph-volume会静默失败,只在 journal 日志里留一行No space left on device,极难定位。
3.2 Monitor 部署:不是ceph-deploy mon create-initial,而是手动初始化
Luminous 废弃了 ceph-deploy,官方推荐cephadm,但它依赖容器运行时,对新手反而增加复杂度。我们采用最透明的原生命令方式,全程可控:
在 Node1 创建 monitor map:
mkdir -p /etc/ceph && cd /etc/ceph ceph-authtool --create-keyring ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'这行命令生成
ceph.mon.keyring,其中--cap mon 'allow *'是关键——它赋予 Monitor 全权限,因为 Monitor 需要读写自己的 map、协调 OSD peering、处理 client 认证请求。少写一个*,后续ceph-mon --mkfs会因权限不足失败。初始化 Monitor 数据目录:
mkdir -p /var/lib/ceph/mon/ceph-node1 ceph-mon --mkfs -i node1 --monmap /etc/ceph/monmap --keyring /etc/ceph/ceph.mon.keyring注意
-i node1必须与hostname -s输出一致,否则启动后ceph -s看不到该 Monitor。--monmap是 Monitor 地图,此时还是单点,后续再加入其他节点。启动 Monitor 服务:
systemctl enable ceph-mon@node1 && systemctl start ceph-mon@node1检查状态:
systemctl status ceph-mon@node1,应显示active (running)。若失败,立刻看journalctl -u ceph-mon@node1 -n 50,90% 的问题是/var/lib/ceph/mon/ceph-node1目录权限不对(必须是ceph:ceph用户组)。
注意:Monitor 启动后,会自动生成
/var/lib/ceph/mon/ceph-node1/keyring,这是它自己的认证密钥。不要手动修改或覆盖,否则集群会“失联”。
3.3 OSD 部署:ceph-volume的 LVM 模式是唯一安全路径
Ceph 官方文档提到了ceph-volume lvm、ceph-volume raw、ceph-disk三种方式,但raw模式要求磁盘完全裸露(无分区表),ceph-disk已废弃。ceph-volume lvm是唯一兼顾安全与灵活性的选择——它用 LVM 逻辑卷封装物理磁盘,既避免直接操作/dev/sdb的风险,又保留了 Bluestore 直接管理设备的能力。
以 Node1 上的/dev/sdb磁盘为例,完整流程如下:
清理磁盘残留(重要!虚拟机克隆或重装系统后必做):
wipefs -a /dev/sdb # 清除所有文件系统签名 pvremove /dev/sdb # 清除 LVM PV 签名创建 LVM 物理卷和逻辑卷:
pvcreate /dev/sdb vgcreate ceph-vol-group /dev/sdb lvcreate -l 100%FREE -n osd-block ceph-vol-group这里
lvcreate -l 100%FREE是精髓:它让逻辑卷占满整块磁盘,不留空隙。Ceph 的 Bluestore 需要连续大块空间存放对象数据,若 LV 只分 50%,剩余空间会被视为“不可用”,OSD 初始化直接失败。使用
ceph-volume初始化 OSD:ceph-volume lvm create --data /dev/ceph-vol-group/osd-block执行后,它会自动:
- 格式化逻辑卷为 Bluestore;
- 创建
/var/lib/ceph/osd/ceph-0目录(0 是 OSD ID); - 生成
keyring并注入集群; - 启动
ceph-osd@0服务。
检查:
ceph osd tree应看到osd.0在host node1下,状态为up。若显示down,八成是ceph-volume没权限读写/dev/ceph-vol-group/osd-block,执行chown ceph:ceph /dev/ceph-vol-group/osd-block即可。
4. 实操过程与核心环节实现:从集群健康到创建第一个 RBD 镜像
4.1 集群初始化与健康检查:读懂ceph -s的每一行含义
当三台节点的 Monitor 和 OSD 全部启动后,执行ceph -s,你会看到类似这样的输出:
cluster: id: a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8 health: HEALTH_WARN Reduced data availability: 1 pg inactive Degraded data redundancy: 132/441 objects degraded services: mon: 3 daemons, quorum node1,node2,node3 mgr: no daemons active osd: 3 osds: 3 up, 3 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0 B usage: 0 B used, 0 B / 0 B avail pgs: 0.000% pgs not active别慌,HEALTH_WARN是正常起步状态。关键信息在services和data段:
mon: 3 daemons, quorum node1,node2,node3表示三个 Monitor 已形成法定人数,这是集群的“大脑”在线;osd: 3 osds: 3 up, 3 in表示三个 OSD 进程运行中(up),且全部被集群接纳(in),这是数据“四肢”健全;pools: 0 pools是重点——Ceph 不像传统存储,它没有默认存储池。所有数据必须显式创建 pool 才能写入。HEALTH_WARN中的1 pg inactive,正是因为没有 pool,PG(Placement Group)无法分配。
解决方法:创建一个名为rbdpool的存储池,设置副本数为 3(匹配我们的三节点):
ceph osd pool create rbdpool 64 64 replicated ceph osd pool set rbdpool size 3这里64 64是 PG 和 PGP(Placement Group for Placement)的数量。为什么是 64?计算公式是:PG 数 ≈ (OSD 数 × 100) / 副本数。我们有 3 个 OSD,副本数 3,所以3×100÷3=100,但 64 是 Luminous 推荐的最小值,既能保证负载均衡,又避免 PG 过多导致内存压力(每个 PG 占约 1MB 内存)。执行后,ceph -s的HEALTH_WARN会消失,pools变为1 pools,pgs状态变为100.000% pgs active+clean——这才是真正的健康起点。
4.2 启用 Manager 模块与 Dashboard:让集群“看得见”
ceph -s只给文本,而ceph dashboard提供可视化界面。但默认它是禁用的,且需要额外密钥:
启用 mgr 模块:
ceph mgr module enable dashboard生成自签名证书(生产环境请换为正规证书):
ceph dashboard create-self-signed-cert创建管理员用户:
ceph dashboard set-login-credentials admin admin123开放 dashboard 端口(默认 8443):
firewall-cmd --permanent --add-port=8443/tcp && firewall-cmd --reload重启 mgr 服务:
systemctl restart ceph-mgr@node1
现在访问https://node1-ip:8443,用admin/admin123登录,就能看到实时 OSD 利用率、PG 分布热力图、IOPS 曲线。这个界面的价值远超“好看”——当你发现某个 OSD 的op_w_latency_ms突然飙升到 200ms,而其他 OSD 是 5ms,立刻就知道该磁盘可能要坏了,比等ceph -s报HEALTH_ERR提前数小时。
4.3 创建并挂载 RBD 块设备:从集群到本地文件系统的最后一公里
RBD(RADOS Block Device)是 Ceph 最常用的功能,它把分布式对象存储虚拟成一块本地磁盘。我们以在 Node1 上创建一个 10GB 的镜像为例:
创建镜像:
rbd create rbdpool/image1 --size 10G --image-feature layering--image-feature layering是关键参数,它启用克隆(clone)功能。没有它,后续rbd clone会报错Operation not supported。查看镜像:
rbd ls rbdpool rbd info rbdpool/image1rbd info会显示stripe_unit(条带大小,默认 4MB)、stripe_count(条带数量,默认 1),这些决定了并发 IO 性能。映射为本地块设备:
rbd map rbdpool/image1执行后,
ls /dev/rbd*会多出/dev/rbd0。注意:rbd map默认映射到/dev/rbd0,如果已有rbd0,它会尝试rbd1,但最好显式指定:rbd map rbdpool/image1 --id admin。格式化并挂载:
mkfs.xfs /dev/rbd0 mkdir -p /mnt/ceph-rbd mount /dev/rbd0 /mnt/ceph-rbd现在
df -h就能看到/mnt/ceph-rbd了。往里面dd if=/dev/zero of=/mnt/ceph-rbd/test bs=1M count=100写入 100MB 数据,ceph -w会实时显示pgs: ... active+clean,证明数据已均匀分散到三个 OSD 上。
实操心得:RBD 映射后,若执行
umount /mnt/ceph-rbd再rbd unmap /dev/rbd0,一定要按顺序!先 umount 再 unmap。反过来会导致内核 panic,必须重启。我踩过两次,第三次就写了个safe-unmap.sh脚本自动检查挂载状态。
5. 常见问题与排查技巧实录:那些文档里不会写的“血泪经验”
5.1 OSD 启动失败的三大高频原因与速查表
| 现象 | 日志关键词 | 根本原因 | 速查命令 | 解决方案 |
|---|---|---|---|---|
ceph-osd@0.service: main process exited, code=exited, status=1/FAILURE | failed to open block device | /dev/ceph-vol-group/osd-block权限非ceph:ceph | ls -l /dev/ceph-vol-group/ | chown ceph:ceph /dev/ceph-vol-group/osd-block |
ceph-osd@0.service: Failed with result 'core-dump' | segmentation fault | Bluestore 初始化时磁盘有坏道或 SMART 错误 | smartctl -a /dev/sdb | 更换磁盘,wipefs -a /dev/sdb后重试 |
ceph-osd@0.service: start request repeated too quickly | start request repeated | /var/lib/ceph/osd/ceph-0目录残留旧数据 | ls /var/lib/ceph/osd/ceph-0 | rm -rf /var/lib/ceph/osd/ceph-0 && ceph-volume lvm activate --all |
最隐蔽的是第三种:当你重复执行ceph-volume lvm create,它不会覆盖旧数据,而是试图在残留的whoami文件上继续初始化,导致 core dump。解决方案不是删整个目录,而是用ceph-volume lvm activate --all让它重新识别已存在的逻辑卷。
5.2 “HEALTH_WARN: too few PGs per OSD” 警告的深度解读
当集群扩容到 6 个 OSD 后,ceph -s突然报这个警告。表面看是 PG 数太少,但直接ceph osd pool set rbdpool pg_num 128会触发 PG 分裂(split),期间集群性能下降 30%。正确做法是分两步:
先设
pgp_num(Placement Group for Placement)等于目标pg_num:ceph osd pool set rbdpool pgp_num 128PGP 控制数据重分布,设为 128 后,CRUSH map 会立即开始迁移,但不改变 PG 数量,IO 影响小;
等
ceph -s显示pgs: ... active+clean后,再设pg_num:ceph osd pool set rbdpool pg_num 128此时 PG 分裂才真正开始,但因 PGP 已就绪,分裂过程更平滑。
这个“先 PGP 后 PG”的顺序,是 Ceph 社区资深运维反复验证的最佳实践,官方文档却一笔带过。
5.3 Dashboard 无法访问的五个排查层次
Dashboard 白屏或连接拒绝,按此顺序逐层检查:
- 网络层:
telnet node1-ip 8443是否通?不通则检查firewall-cmd --list-ports和iptables -L; - 服务层:
systemctl status ceph-mgr@node1是否 active?若 failed,看journalctl -u ceph-mgr@node1 -n 100; - 模块层:
ceph mgr module ls \| jq '.enabled_modules'是否包含"dashboard"?若无,ceph mgr module enable dashboard; - 证书层:
ceph dashboard get-ssl-cert是否返回证书内容?若为空,ceph dashboard create-self-signed-cert; - 用户层:
ceph dashboard get-login-credentials是否返回用户名密码?若无,ceph dashboard set-login-credentials user pass。
我曾在一个项目中卡在第 4 步:get-ssl-cert返回空,但create-self-signed-cert执行无报错。最后发现是/var/lib/ceph/mgr/ceph-node1目录权限为root:root,mgr 进程无法写入证书。chown ceph:ceph /var/lib/ceph/mgr/ceph-node1后秒解。
5.4 RBD 克隆失败:“Image has no parent” 的真相
执行rbd clone rbdpool/image1 rbdpool/clone1报错。原因只有一个:image1创建时没加--image-feature layering。但修复不能简单重建镜像——已有数据会丢失。正确方案是:
rbd feature enable rbdpool/image1 layering rbd snap create rbdpool/image1@snap1 rbd clone rbdpool/image1@snap1 rbdpool/clone1即:先启用 layering 特性,再打快照,最后克隆快照。rbd feature enable是在线操作,不影响业务。这个技巧,救过我两个客户的生产库迁移。
6. 进阶思考与个人体会:Ceph 不是终点,而是理解现代存储的起点
亲手完成 Ceph 分布式存储安装及简单使用后,我最大的体会是:它教会我的不是“怎么配一个存储”,而是“数据在大规模系统中如何被信任”。当ceph osd tree里看到三个节点整齐排列,ceph df显示容量均匀分布,rbd map后dd写入的数据能在任意节点上rbd info查到——这种确定性,是任何黑盒服务都无法替代的掌控感。Ceph 的价值,从来不在它多快,而在它多“诚实”:每一个警告(WARN)、每一个降级(degraded)、每一个 PG 的 active/clean 状态,都是对底层硬件真实状况的忠实反馈。它逼着你直面磁盘寿命、网络延迟、CPU 调度这些物理世界的约束,而不是躲在“高可用”“弹性伸缩”的抽象概念后面。
后续你可以自然延伸:用cephfs搭建 POSIX 兼容的分布式文件系统,让多台服务器共享同一份/home;用rgw(RADOS Gateway)开启 S3 兼容接口,把集群变成私有对象存储;甚至把rbd镜像作为 Kubernetes 的 PersistentVolume,支撑有状态应用。但所有这些,都建立在你亲手让三个 OSD 亮起绿灯的基础上。Ceph 分布式存储安装及简单使用,不是一份过时的技术清单,而是一次对数据基础设施本质的回归——它提醒我们,在云原生时代,亲手触摸硬件、理解协议、阅读日志,依然是工程师最不可替代的能力。