Ceph 命令是"层级式"命名的,拆开看每个词就不需要死记:
ceph orch device zap <host> /dev/<disk> --force
│ │ │ │ │ │ │
│ │ │ │ │ │ └── 跳过确认提示
│ │ │ │ │ └── 磁盘路径
│ │ │ │ └── 主机名
│ │ │ └── 清零 / 擦除 LVM 数据
│ │ └── 磁盘设备
│ └── Orchestrator 编排器(cephadm 的控制层)
└── Ceph CLI 总入口
| 词 | 含义 | 记忆方法 |
|---|---|---|
ceph |
Ceph 集群 CLI 总入口 | 所有命令都从这个开始 |
orch |
Orchestrator 编排器 | 管服务的:加/删/启/停守护进程 |
osd |
Object Storage Daemon | 存数据的进程,一块盘一个 OSD |
device |
磁盘设备 | 物理层面的:查看磁盘、清磁盘 |
host |
集群中的主机节点 | 主机层面的:增删节点、驱逐服务 |
daemon |
守护进程(容器) | 进程层面的:启停单个进程 |
apply |
应用 spec 规则 | 用 yaml 描述目标,部署为托管形式 |
rm |
Remove 删除 | |
zap |
清零 / 擦除 | 干掉 Ceph 在磁盘上建的 LVM 分区 |
drain |
排干 / 驱逐 | 把一台主机上的所有服务迁到其他节点 |
replace |
替换 | 删旧盘 + 标记"这里要补一块新盘" |
purge |
彻底清除 | 从 CRUSH 表里把 OSD 记录踢出去 |
out / in |
暂停/恢复使用 | out 触发数据迁走;in 恢复使用 进程始终在跑 |
crush |
CRUSH 算法 / 拓扑表 | 集群的"地图"——哪个 OSD 在哪台机器上 |
--force |
跳过普通确认 | 常规操作的安全确认 |
--yes-i-really-mean-it |
"我真要这么干" | 危险操作的二次确认(删池、purge等) |
--dry-run |
预演不执行 | 只算匹配结果给你看,不实际创建 OSD |
命令层级——越靠左越宏观,越靠右越具体:
ceph --> 集群层(管一切)
ceph osd --> OSD 层(管 CRUSH、管状态)
ceph orch --> 编排层(管服务、管磁盘)
| 层面 | 命令入口 | 管的 | 视角 |
|---|---|---|---|
| CRUSH 拓扑层 | ceph osd ... |
CRUSH 地图、OSD 状态、数据放置规则 | CRUSH 全局视角——"数据该往哪放" |
| 编排器层 | ceph orch ... |
容器/进程、磁盘设备、主机节点 | cephadm 视角——"服务跑在哪" |
它决定了"删 OSD 后会不会自动补盘"
| 对比项 | 托管 OSD | 非托管 OSD |
|---|---|---|
| 创建方式 | ceph orch apply osd --all-available-devices 或 -i spec.yaml |
ceph orch daemon add osd |
| 删盘后 | ✅ 自动重建新 OSD | ❌ 需手动添加 |
ceph orch ls 区别在最右列 |
显示部署位置 | 显示 <unmanaged> |
| 适用场景 | 生产环境标准化 | 临时测试、手动干预 |
ceph orch ls |
ceph orch ps |
|
|---|---|---|
| 关注层面 | 服务级别(service) | 进程/容器级别(daemon) |
| 粒度 | 一个服务类型一行 最右列 PLACEMENT 区分托管/非托管 |
每个守护进程实例一行 |
| 关键信息 | 是否托管、部署位置、RUNNING 比值 |
每个 daemon 的详细运行状态 |
📌 一句话:
orch ls看服务整体的编排情况
orch ps看每个 daemon 进程的实际运行状态
手动 daemon add --> 非托管
怎么判断当前是哪种:
root@Ceph-201 ~# ceph orch ls | grep osd
NAME 'RUNNING' REFRESHED AGE 'PLACEMENT'
mgr 2/2 5m ago 25h count:2
mon 1/5 5m ago 25h count:5
osd.default 3 5m ago 5m 'Ceph-201' <-- '限定节点'
osd.all-available-devices 1 55s '*'
# 👆托管——最右列显示部署位置 '没有限定节点👆所有主机都匹配'
# 👇非托管——最右列显示 <unmanaged>:
osd 3 8m ago - '<unmanaged>'
RUNNING 列怎么读——实际在跑 / 预期目标:
3 --> 3/3 实际 = 预期 ✅️健康
1/3 --> 1个在跑,预期3个(其余没起来或挂了)
0/3 --> 全挂了
| RUNNING 的数字来源 | |
|---|---|
| 托管 | 预期数由 spec 决定——匹配到多少块符合条件的盘 |
| 非托管 | 没有 spec,没有"预期",就显示实际跑着的数量 |
PLACEMENT 列的三种值:
| PLACEMENT | 含义 |
|---|---|
Ceph-201 |
spec 里 placement: hosts: [Ceph-201] 限定只在这台节点部署 |
* |
没有限定节点,所有主机都匹配——--all-available-devices 就是这种 |
<unmanaged> |
非托管,没有 spec 规则在管它 |
托管 --> 非托管(只交管理权,不删数据):
root@Ceph-201 ~# ceph orch rm osd.default --force
'spec 规则被删除,OSD 进程和数据不受影响'
# 只是变成 <unmanaged>,不再自动补盘
root@Ceph-201 ~# ceph orch ls
osd.default 3 9m ago - '<unmanaged>' ✅️ 非托管
📌 创建托管 OSD 的两种写法
--all-available-devices |
-i spec.yaml |
|
|---|---|---|
| 选盘方式 | 自动——所有 AVAILABLE: Yes 的盘全上 |
手动——你挑:路径 / 属性 / 主机 |
| 范围 | 所有节点 | 按 placement 限定 |
| 服务名 | osd.default |
osd.<service_id> |
| 适用场景 | 快速部署、测试环境 | 生产环境精确控制 |
⚠️ 两种方式的大前提:磁盘必须
AVAILABLE: Yes已跑着非托管 OSD 的盘正被占用,
AVAILABLE为No,spec 不会去碰它
# 方式一:全自动——接管所有空闲盘
ceph orch apply osd --all-available-devices
# 方式二:精细化——按 spec 文件指定
ceph orch apply -i spec.yaml
"非托管 OSD 变成托管"的实际流程——不是魔法,是删旧补新:
非托管 OSD 在跑 --> 磁盘被占用 --> AVAILABLE: No --> spec 不理它
↓ 删除
ceph orch osd rm <id> --zap --> 磁盘空闲 --> AVAILABLE: Yes
↓ 👆完成停进程 + 清 CRUSH + 清磁盘
spec 自动检测到空闲盘 --> 自动部署新 OSD --> 变成托管了
root@Ceph-201 ~# ceph orch ls
osd.default 3 76s ago - <unmanaged>
'现在是非托管' --> 数量3个
root@Ceph-201 ~# ceph osd tree
0 hdd 0.48830 osd.0 up 1.00000 1.00000
1 hdd 0.29300 osd.1 up 1.00000 1.00000
2 hdd 1.00000 osd.2 up 1.00000 1.00000
root@Ceph-201 ~# ceph orch osd rm osd.1 --zap
Unable to find OSDs: ['osd.1'] ❌️
✅️ 直接删除的是 1
root@Ceph-201 ~# ceph orch osd rm 1 --zap
Scheduled OSD(s) for removal.
root@Ceph-201 ~# ceph osd tree
0 hdd 0.48830 osd.0 up 1.00000 1.00000
2 hdd 1.00000 osd.2 up 1.00000 1.00000
'没有 1 了'
root@Ceph-201 ~# ceph orch device ls
Ceph-201 /dev/sdb hdd 300G Yes ✅️
'可以加入OSD设备'
root@Ceph-201 ~# ceph orch apply osd --all-available-devices
Scheduled 'osd.all-available-devices' update...
📌 留意这个名称
root@Ceph-201 ~# ceph orch device ls
Ceph-201 /dev/sdb hdd 300G No ✅️ 过一会才会显示
root@Ceph-201 ~# ceph osd tree
'都加入进来了'
root@Ceph-201 ~# ceph orch ls
osd.all-available-devices 1 55s ago 71s *
osd.default 2 55s ago - <unmanaged>
'数量由原来 3 --> 2+1 '
📌
applyspec 不会把已有的非托管 OSD "转换"成托管,它只管在空闲盘上部署新 OSD
- 想让某个非托管 OSD 变成托管
- 流程是:删了它 --> zap --> spec 自动补一个新的
⚠️ 删除 spec ≠ 删除 OSD 删的是"自动管理规则",盘照样跑
1)查看当前 OSD 树(关注 CLASS 列)
root@Ceph-201 ~# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.78130 root default
-3 0.78130 host Ceph-201
0 hdd 0.48830 osd.0 up 1.00000 1.00000
1 hdd 0.29300 osd.1 up 1.00000 1.00000
# hdd --> 机械硬盘 ssd --> 固态硬盘
2)移除原有 class
root@Ceph-201 ~# ceph osd crush rm-device-class osd.1
done removing class of osd(s): 1
'这个是osd.1'
ceph orch osd rm 1 --zap
# 直接写ID即可
3)设置新 class
root@Ceph-201 ~# ceph osd crush set-device-class ssd osd.1
set osd(s) 1 to class 'ssd'
root@Ceph-201 ~# ceph osd tree | grep osd.1
1 ssd 0.29300 osd.1 up 1.00000 1.00000
# 由hdd --> ssd
💡 rm-device-class + set-device-class 仅用于实验环境
生产环境中设备类型由硬件自动识别
out 和 in 是一对可逆操作,跟 rm(真删除)是两回事:
ceph osd out --> 告诉 CRUSH:"现存的数据搬走,别往这块盘放数据了"
ceph osd in --> "行了,可以继续用了"
ceph osd rm --> 真删了,OSD 没了
⚠️ 注意区分两个层面的"可逆":
| 层面 | out --> in 之后 |
|---|---|
| OSD 本身 | ✅ 可恢复——盘还在、进程没停、in 后继续用 |
| 盘上的数据 | ❌ 不可逆——out 时数据已经被搬到其他 OSD 了,in 后是空盘 |
所以"可逆"说的是 OSD 这个盘没被销毁,还能继续服役
1)暂停使用 osd.1
root@Ceph-201 ~# ceph osd tree
ID CLASS WEIGHT NAME 'STATUS' 'REWEIGHT' PRI-AFF
0 hdd 0.48830 osd.0 up 1.00000 1.00000
1 hdd 0.29300 osd.1 up 1.00000 1.00000
2 hdd 1.00000 osd.2 up 1.00000 1.00000
'📌 重点注意状态 & 权重' 👆 👆
root@Ceph-201 ~# ceph osd out osd.1
marked out osd.1.
root@Ceph-201 ~# ceph osd tree
ID CLASS WEIGHT NAME 'STATUS' 'REWEIGHT' PRI-AFF
0 hdd 0.48830 osd.0 up 1.00000 1.00000
1 hdd 0.29300 osd.1 up '0' 1.00000
2 hdd 1.00000 osd.2 up 1.00000 1.00000
✅️ OSD 状态:osd.1 up <-- 进程还在跑
osd: 3 osds: 3 up (since 2h), 2 in (since 23s)
📌 3 up = 3个进程都在跑 2 in = 但只有2个在干活(osd.1 out了不参与)
进程在跑(up)≠ 参与干活(in)
✅️ CRUSH 权重 --> 0,不再接收新数据
✅️ PG 恢复:osd.1 不干活了 --> 从剩余副本盘拷贝数据到新盘,恢复副本数
📌 原来3副本 --> out一个 --> 只剩2副本 --> 触发恢复补回到3副本
root@Ceph-201 ~# ceph -s | grep 'pgs:'
pgs: 1 'active+clean'
⚠️ 等 PG 恢复完成 --> ceph -s 确认 'active+clean'
✅️ 恢复完成,osd.1 上只剩废数据(不再被使用)
⚠️ 旧数据物理还在盘上,但已是孤儿,不会被访问——会被后续回收/覆盖
2)恢复使用
═══════════════════════════════════════
out / in 全流程副本变化示意
═══════════════════════════════════════
out前:[osd.0 ✅] [osd.1 ✅] [osd.2 ✅] = 3/3 健康
out后:[osd.0 ✅] [osd.1 🈳] [osd.2 ✅] = osd.1 不干活了,PG 少一个副本
↓ 从 osd.0/osd.2(剩余副本) 拷贝数据到新盘
恢复后:[osd.0 ✅] [osd.2 ✅] = 2/2 osd.1 空盘,旧数据变孤儿
in后: [osd.0 ✅] [osd.1 🈳] [osd.2 ✅] = osd.1 回组但空的! PG 又缺副本
↓ 从 osd.0/osd.2(剩余副本) 拷贝数据到 osd.1
恢复后:[osd.0 ✅] [osd.1 ✅] [osd.2 ✅] = 3/3 osd.1 又是正常副本了
═══════════════════════════════════════
root@Ceph-201 ~# ceph osd in osd.1
marked in osd.1.
# 权重恢复 --> CRUSH 重新把 PG 分配到这块盘
📌 osd.1 回组但盘是空的,实际只剩2个有效副本,所以"缺一个"
root@Ceph-201 ~# ceph -s | grep 'pgs:'
pgs: 100.000% pgs not active
⚠️ PG 缺副本:osd.1 回组但空盘 --> '由空盘补成一个真正的副本'
root@Ceph-201 ~# ceph -s | grep 'pgs:'
pgs: 1 active+clean
✅️ 数据从其他盘拷贝完成,osd.1 又是正常副本了
📌 生产环境删 OSD 前先
out,等数据迁完再rm,保证不丢数据
🌰 语法
ceph orch daemon add osd <host>:<device_path>
📌中间👆有 '冒号:'
⚠️ 通过 `daemon add` 添加的 OSD 默认处于 '非托管 (unmanaged)' 状态
# 示例
root@Ceph-201 ~# ceph orch daemon add osd Ceph-201:/dev/sdb
推荐 ceph orch osd rm --> 一条命令完成停进程 + 清 CRUSH +(可选)清磁盘
ceph orch osd rm status --> 查看删除进度
⚠️ 防止单节点删除卡住:`.mgr` 池默认副本数 ≥ 2,单节点删 OSD 优先降副本
root@Ceph-201 ~# ceph osd pool ls detail
pool 1 '.mgr' replicated size 2 min_size 1 crush_rule 0
✅️ size=2 想要2副本 min_size=1 最少1副本就能IO
root@Ceph-201 ~# ceph osd pool set .mgr size 1 --yes-i-really-mean-it
Error EPERM: configuring pool size as 1 is disabled by default
❌️ 新版 Ceph 默认禁止设 size=1 --> 先开权限
root@Ceph-201 ~# ceph config set mon mon_allow_pool_size_one true
root@Ceph-201 ~# ceph osd pool set .mgr size 1 --yes-i-really-mean-it
set pool 1 size to 1
root@Ceph-201 ~# ceph osd pool ls detail
pool 1 '.mgr' replicated size 1 min_size 1 crush_rule 0
✅️ 副本数设置为 1
root@Ceph-201 ~# ceph orch daemon rm osd.0 --force
# 从集群中删除 OSD 守护进程
root@Ceph-201 ~# ceph osd purge osd.0 --yes-i-really-mean-it
# 从 CRUSH 表彻底删除 → 集群名单踢出
'后面的那个选项 --> 危险操作的二次确认'
root@Ceph-201 ~# ceph orch device zap Ceph-201 /dev/sdb --force
# 擦除磁盘上的 Ceph 数据(恢复为空盘) 主机名 👆 路径
'中间可没有 --> 冒号:'
=============以上三步的详细操作 --> 参考上一篇笔记📚
🌰 语法
ceph orch osd rm <OSD_ID> [--replace] [--force] --zap
⚠️ 直接删除的是 1 而不是 osd.1
1)保留磁盘数据 --> 不加 --zap选项
root@Ceph-201 ~# ceph osd rm 1
Error EBUSY: osd.1 is still up; must be down before removal.
❌️ ceph osd rm 删不了还在 up 的 OSD --> 必须先停进程
root@Ceph-201 ~# ceph osd rm 1 --force
Error EINVAL: osd.1 is still up; must be down before removal.
❌️ --force 也不行,up 状态就是不让删
'少加 orch(编排器)'
root@Ceph-201 ~# ceph orch osd rm 1
✅️ orch(编排器)自动停进程 + 清 CRUSH,不用管 up/down
Scheduled OSD(s) for removal.
VG/LV for the OSDs won't be zapped'
⚠️ 只是没加 --zap,VG/LV 没被摧毁,磁盘 LVM 还在,AVAILABLE 仍为 No
2)同时清除磁盘数据
root@Ceph-201 ~# ceph orch osd rm 1 --zap
Scheduled OSD(s) for removal.
✅️ 删除 + 清除磁盘数据(磁盘恢复为 AVAILABLE: Yes)
root@Ceph-201 ~# ceph orch osd rm status
'查看删除进度'
OSD HOST STATE PGS REPLACE FORCE ZAP DRAIN STARTED AT
1 Ceph-201 draining 0 False False True 2026-05-21 12:29:05
⚠️ 不要用
ceph orch daemon rm——只删容器进程,不清理 CRUSH,也不清理磁盘,会产生 stray daemon,还得手动purge+zap
🧱 为什么 daemon rm 会产生 stray daemon?——两个层面不一致:
ceph orch daemon rm osd.0 → 只清了编排器层 ✅ CRUSH 拓扑层纹丝不动 ❌
↓
cephadm:"osd.0 不归我管了" CRUSH:"osd.0 应该在线啊,去哪了?"
↓
两层不一致 → stray daemon 告警!
✅ 正确做法:用
ceph orch osd rm一条命令同时清两层(停进程 + 清 CRUSH + 可选 zap)
生产 vs 实验:
| 生产环境 | 实验环境 | |
|---|---|---|
| 步骤 | ceph osd out --> 等 PG 恢复 --> orch osd rm --zap |
直接 orch osd rm --zap |
| 原因 | out 先把数据迁走,保证安全 |
无数据,out 反而空跑恢复 |
# 语法
ceph orch osd rm <OSD_ID> --replace --zap
--replace 的核心作用就一句话:同一个 ID,同一个主机,原位补回
📌 决定"会不会重建"的是托管状态,
--replace决定的是重建时保不保留原 ID 和原位置
不加 --replace |
加 --replace |
|
|---|---|---|
| 托管 OSD | 自动重建 ✅️ | 自动重建 ✅️ |
| 非托管 OSD | ❌️不自动重建,需手动 daemon add |
❌️不自动重建,需手动 daemon add |
| ID | 递增出新号 | 保留原 ID |
| 主机 | 无约束,哪台都行 | 同一台主机 |
实例对比(托管场景):
# 不加 --replace:osd.2 永远消失 → spec 在空闲盘上建全新 osd.4
ceph orch osd rm 2 --zap
--> osd tree: osd.0, osd.1, osd.3, osd.4 <-- '换了张新面孔,换了台主机'
# 加 --replace:osd.2 被标记"等着补回来" → 新盘顶上还是 osd.2
ceph orch osd rm 2 --replace --zap
--> osd tree: osd.0, osd.1, osd.2, osd.3 <-- '同一个 ID,同一台主机'
为什么必须是同一台主机?
CRUSH 里 OSD ID 和主机是绑定的:
host Ceph-201
osd.2 # ← 位置写死了,osd.2 永远是 Ceph-201 的
保留 osd.2 这个 ID → 新盘只能在 Ceph-201 上补
ID 不变 = 主机不变,两个是捆绑的
📌 生产换盘一定加
--replace:同一个 ID、同一台主机,监控不告警,CRUSH 不乱
移除一整台主机及其上所有 OSD:
root@Ceph-201 ~# ceph orch host ls
HOST ADDR LABELS STATUS
Ceph-201 10.0.0.201 _admin
Ceph-202 10.0.0.202
Ceph-203 10.0.0.203
3 hosts in cluster
root@Ceph-201 ~# ceph orch ps Ceph-203
'PS查看各个进程的' --> 单独看 Ceph-203 主机的
⚠️ 不是ls ⚠️
NAME HOST PORTS STATUS
mon.Ceph-203 Ceph-203 running (51m)
osd.6 Ceph-203 running (51m)
osd.7 Ceph-203 running (51m)
osd.8 Ceph-203 running (51m)
=============================================
1)驱逐节点上所有服务(移除本机 daemon,OSD 数据靠剩余副本恢复)
root@Ceph-201 ~# ceph orch host drain Ceph-203
Scheduled to remove the following daemons from host 'Ceph-203'
type id
-------------------- ---------------
osd 8
osd 6
osd 7
mon Ceph-203
'多次执行直到输出为空,确认所有 daemon 移除任务已下发完毕'
📌 drain 输出为空 = 任务调度完成 ≠ 数据已搬完——这只是第一步
root@Ceph-201 ~# ceph orch host drain Ceph-203
Scheduled to remove the following daemons from host 'Ceph-203'
type id
-------------------- ---------------
'现在什么都没有了'
root@Ceph-201 ~# ceph orch host ls
HOST ADDR LABELS STATUS
Ceph-201 10.0.0.201 _admin
Ceph-202 10.0.0.202
Ceph-203 10.0.0.203 _no_schedule,_no_conf_keyring
👆 '变为不可调度'
2)等待数据恢复完成
📌 这才是真正等数据搬完:PG 从剩余副本拷贝数据到新位置需要时间
root@Ceph-201 ~# ceph -s | grep health
health: HEALTH_OK
✅️ 确认 HEALTH_OK 再继续
3)清理磁盘上的 LVM 残留
'drain 不自动 zap,只清磁盘用 device zap 即可'
📌 编排器命令,在集群任意节点执行,<hostname> 指定目标即可,不用 SSH 到被驱逐节点
root@Ceph-201 ~# ceph orch device zap <hostname> /dev/<disk> --force
root@Ceph-201 ~# ceph orch device zap Ceph-203 /dev/sdb --force
root@Ceph-201 ~# ceph orch device zap Ceph-203 /dev/sdc --force
root@Ceph-201 ~# ceph orch device zap Ceph-203 /dev/sdd --force
4)从 CRUSH 删除主机条目
root@Ceph-201 ~# ceph osd tree
-7 0 host Ceph-203
'现在还有它'
📌 CRUSH 拓扑层:删掉 CRUSH 地图里该主机的空 bucket(此时 OSD 已无,bucket 已空)
root@Ceph-201 ~# ceph osd crush remove <hostname>
root@Ceph-201 ~# ceph osd crush remove Ceph-203
removed item id -7 name 'Ceph-203' from crush map
5)从集群删除主机
root@Ceph-201 ~# ceph orch host ls | grep Ceph-203
Ceph-203 10.0.0.203 _no_schedule,_no_conf_keyring
📌 编排器层:把主机从 cephadm 管理名单中踢出去,集群不再知道这台机器
root@Ceph-201 ~# ceph orch host rm Ceph-203
Removed host 'Ceph-203'
root@Ceph-201 ~# ceph orch host ls | grep Ceph-203 | wc -l
0
root@Ceph-201 ~# ceph orch host ls
HOST ADDR LABELS STATUS
Ceph-201 10.0.0.201 _admin
Ceph-202 10.0.0.202
2 hosts in cluster
'现在在Ceph-201已经查看不到Ceph-203了'
📌
drain后 OSD 已被移除,磁盘上仍有 LVM 残留,需手动 zap⚠️ 不要在
drain前手动stopOSD——stop 后 OSD 处于暂停状态,drain 无法处理
| 误操作后的情况 | 如何补救 |
|---|---|
只是 stop 了 OSD |
ceph orch daemon start osd.<id> 恢复 → 正常 drain |
已经 daemon rm 了 |
ceph osd purge osd.<id> + ceph orch device zap 收场 |
清扫收尾(集群侧已清理完毕,以下是节点本地操作):
# 被驱逐节点:解除残留的 device mapper 映射(可能会)
'zap 后 LVM 已清,但内核的 dm 映射 可能 还在 ——> lsblk 看到的"幽灵"设备'
root@Ceph-203 ~# lsblk
# 无残留 dm 设备则跳过,有则继续
root@Ceph-203 ~# dmsetup remove <dm-name>
# 手动移除 dm 映射
OSD 创建时: /dev/sdb ──LVM──▶ dm-0 (OSD block)
↓ 写入内核 /proc/device-mapper
zap 之后: 磁盘上 LVM 已清除 ✅ 内核 dm 映射'可能'残留 ⚠️
↓
lsblk 若还能看到 dm-0 → dmsetup remove dm-0 清掉
# 被驱逐节点:删除 cephadm 数据目录(删的是配置文件,不是块设备数据)
'是被删除节点的数据' ⚠️ Ceph-203上执行
root@Ceph-203 ~# ls /var/lib/ceph/
fdc2219c-5344-11f1-8042-000c2990a57e
root@Ceph-203 ~# rm -rf /var/lib/ceph/
💡
rm -rf /var/lib/ceph/清的是 cephadm 的文件系统层配置(FSID 目录),不能替代device zap前者删文件,后者擦块设备上的 LVM 元数据
🧱 BlueStore 是 Ceph 默认的存储后端,直接管理裸设备,消除了传统 FileStore 的双写惩罚
🧱 非并置:'一个 OSD 进程'横跨'三块不同类型'的物理盘
┌─ osd.3 ─────────────────────────────────────────┐
│ │
┌─────────┐ │ WAL (预写日志) ──▶ Block.wal ──▶ nvme0n3 SSD │'低延迟'
│ 客户端IO │──▶ │ DB (元数据) ──▶ Block.db ──▶ nvme0n2 SSD │'加速'
└─────────┘ │ DATA (对象数据) ──▶ Block.data ─▶ sdb HDD │'容量层'
│ │
└─────────────────────────────────────────────────┘
📌 配对规则:一个 OSD 进程最多三块盘(data + db + wal)
| 组件 | 说明 | 放置 | 性能要求 |
|---|---|---|---|
data |
OSD 所有对象数据 | HDD | 大容量、低成本 |
db |
BlueStore 内部元数据 (RocksDB) | SSD/NVMe | 高 IOPS、低延迟 |
wal |
预写日志,保证数据一致性 | SSD/NVMe | 最低延迟 |
💡 将 WAL 和 DB 放在高速 SSD 上,data 放在廉价 HDD 上,是性能和成本的最佳平衡
'手动添加磁盘'
root@Ceph-201 ~# lsblk
NAME SIZE RO TYPE
sdb 300G 0 disk
└─ceph-xxx
sdc 500G 0 disk
└─ceph-xxx
sdd 1T 0 disk
└─ceph-xxx
'上面三个已经在集群种了'
sde 20G 0 disk
sdf 20G 0 disk
nvme0n1 20G 0 disk
nvme0n2 20G 0 disk
root@Ceph-201 ~# ceph orch device ls --refresh
--refresh # 绕开缓存直接触发一次新扫描
HOST PATH TYPE SIZE AVAILABLE
Ceph-201 /dev/nvme0n1 ssd 20.0G No
Ceph-201 /dev/nvme0n2 ssd 20.0G No
Ceph-201 /dev/sdb hdd 300G No
Ceph-201 /dev/sdc hdd 500G No
Ceph-201 /dev/sdd hdd 1024G No
Ceph-201 /dev/sde hdd 20.0G No
Ceph-201 /dev/sdf hdd 20.0G No
'触发强扫后,自动添加上去了'
root@Ceph-201 ~# ceph orch ls
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 6 7m ago 10h *
osd.default 1 7m ago 10m Ceph-201
'这些都是托管的所以他就会自动添加OSD了'
1)删 spec 规则 → 变非托管
root@Ceph-201 ~# ceph orch rm osd.all-available-devices --force
root@Ceph-201 ~# ceph orch rm osd.default --force
root@Ceph-201 ~# ceph orch ls
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 6 4m ago - '<unmanaged>'
osd.default 1 4m ago - '<unmanaged>'
2)删 OSD + zap → 磁盘变 AVAILABLE: Yes
root@Ceph-201 ~# ceph orch osd rm 3 --zap
root@Ceph-201 ~# ceph orch osd rm 4 --zap
root@Ceph-201 ~# ceph orch osd rm 5 --zap
root@Ceph-201 ~# ceph orch osd rm 6 --zap
'需要点时间⌚️'
root@Ceph-201 ~# ceph orch osd rm status
# 查看删除进度
root@Ceph-201 ~# ceph osd tree
'还剩三个'
root@Ceph-201 ~# ceph -s | egrep 'health:|osd:|pgs:'
health: HEALTH_OK
osd: 3 osds: 3 up (since 3m), 3 in (since 25m)
pgs: 1 active+clean
root@Ceph-201 ~# ceph orch device ls | grep Yes | wc -l
4
'这四个已经变为Yes状态'
3)写 spec 文件(data on HDD, db/wal on NVMe)
root@Ceph-201 ~# vim osd_spec.yaml
service_type: osd # 固定值,声明这是 OSD 服务
service_id: <随便起> # 名字后缀,最终服务名 osd.<service_id>
placement: # 限定在哪些主机上生效
hosts:
- Ceph-201 # 只在这台节点选盘
spec:
data_devices: # 对象数据盘 —— 存你的业务数据
all: true # 使用所有可用设备
db_devices: # RocksDB 元数据盘 —— 存 OSD 内部索引
wal_devices: # 预写日志盘 —— 写入缓冲
# ↑如果没有配置 --> 则复用 db
| key | 含义 | 类比 |
|---|---|---|
service_type |
固定 osd,声明管的是 OSD 服务 |
"我是 OSD 部署规则" |
service_id |
随便起名,服务名后缀 | 给这条规则起外号 |
placement |
限定在哪些主机上生效 (通配符 *匹配所有主机) |
圈定战场——只在这些机器选盘 |
data_devices |
对象数据盘,存业务数据all: true表示使用所有可用设备 |
仓库——存货物 |
db_devices |
RocksDB 元数据盘,存 OSD 内部索引 | 仓库地图——货在哪 |
wal_devices |
预写日志盘,写入缓冲不配 → WAL 自动塞到 db 盘连 db 也没配 → 全落到 data 盘 |
记账本——先记后入库 没单独给记账本就记在地图背面 |
📌 配对规则:一个 OSD 进程最多三块盘(data + db + wal)
paths 列表 → cephadm 一一配对,不是把所有盘合给一个 OSD
写两条 data + 两条 db: 写一条 data + 一条 db:
sde ──┐ nvme0n1 ──┐ sde ── nvme0n1 --> 一个 OSD
sdf ──┤ nvme0n2 ──┤
↓ ↓
osd.3: sde + nvme0n1 = '拆成两个独立 OSD,各配一对盘'
osd.4: sdf + nvme0n2
Spec 设备筛选 --> 常用属性
| 属性 | 说明 | 示例值 |
|---|---|---|
rotational |
0=SSD/NVMe, 1=HDD | 0 |
size |
设备容量范围 | '10G:' (≥10G) |
paths |
指定具体设备路径 | /dev/sda |
service_type: osd
service_id: osd_using_paths
placement:
hosts:
- Ceph-201
spec:
data_devices:
paths:
- /dev/sde
# 数据盘:SATA HDD
db_devices:
paths:
- /dev/nvme0n1
# 元数据盘:NVMe SSD
wal_devices:
paths:
- /dev/nvme0n2
# WAL盘:NVMe SSD
4)预演不执行
root@Ceph-201 ~# ceph orch apply -i osd_spec.yaml --dry-run
--dry-run # 干运行(预览)
'把 spec 匹配结果算出来给你看,但不会真的创建 OSD'
# 确认结果对了再拿掉 --dry-run 正式 apply
....xxx
Preview data is being generated.. Please re-run this command in a bit.
'关键是最后一句' --> 等几秒重新跑一次
root@Ceph-201 ~# ceph orch apply -i osd_spec.yaml --dry-run
################
OSDSPEC PREVIEWS
################
+---------+-----------------+----------+----------+--------------+--------------+
|SERVICE |NAME |HOST |DATA |DB |WAL |
+---------+-----------------+----------+----------+--------------+--------------+
|osd |osd_using_paths |Ceph-201 |/dev/sde |/dev/nvme0n1 |/dev/nvme0n2 |
+---------+-----------------+----------+----------+--------------+--------------+
5)应用 spec
# 确认无误后正式 apply
root@Ceph-201 ~# ceph orch ls
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 3 9m ago - '<unmanaged>'
'剩三个osd进程在跑' --> 非托管
root@Ceph-201 ~# ceph -s | egrep 'health:|osd:|pgs:'
health: HEALTH_OK
osd: 3 osds: 3 up (since 73m), 3 in (since 95m)
pgs: 1 active+clean
root@Ceph-201 ~# ceph orch apply -i osd_spec.yaml
Scheduled osd.osd_using_paths update...
root@Ceph-201 ~# ceph orch ls
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 3 3s ago - '<unmanaged>'
osd.osd_using_paths 1 3s ago 23s 'Ceph-201'
'三块盘合成一个进程'
root@Ceph-201 ~# ceph -s | egrep 'health:|osd:|pgs:'
health: HEALTH_OK
osd: 4 osds: 4 up (since 111s), 4 in (since 98m)
pgs: 1 active+clean
root@Ceph-201 ~# ceph osd tree
'多了一个osd的进程' --> osd.3
⚠️ 标签class列为 hdd --> ✅️ 以 data 设备为准
📌 非并置 OSD 的 CLASS 由 data 设备 的类型决定
💡 如果无法直接在宿主机使用 ceph 命令,可挂载 spec 文件到容器中:
cephadm shell --mount osd_spec.yaml:/var/lib/ceph/osd/osd_spec.yaml
# 删除 osd.3
root@Ceph-201 ~# ceph orch osd rm 3 --zap
Scheduled OSD(s) for removal.
1)初次查看 OSD 树
root@Ceph-201 ~# ceph osd tree
0 hdd 0.29300 osd.0 up
1 hdd 0.48830 osd.1 up
2 hdd 1.00000 osd.2 up
'没反应过来'
2)再次查看
root@Ceph-201 ~# ceph osd tree
0 hdd 0.29300 osd.0 up
1 hdd 0.48830 osd.1 up
2 hdd 1.00000 osd.2 up
3 hdd 0.03909 osd.3 up
'又回来了'
root@Ceph-201 ~# ceph -s | egrep 'health:|osd:|pgs:'
health: HEALTH_OK
osd: 4 osds: 4 up (since 14s), 4 in (since 2h)
pgs: 1 active+clean
'依旧是 4 个osd进程'
===================================
⚠️ 被 spec 规则托管的 OSD:
删除后磁盘被 zap,spec 规则发现可用磁盘满足条件,'自动重建了 OSD'
1)先删除 spec 服务规则
root@Ceph-201 ~# ceph orch rm osd.osd_using_paths --force
'只交管理权,不删数据'
Removed service osd.osd_using_paths
root@Ceph-201 ~# ceph orch ls | grep osd
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 3 8m ago - '<unmanaged>'
osd.osd_using_paths 1 8m ago - '<unmanaged>'
'此时服务变为 <unmanaged>,OSD 进程还在'
2)再删除具体的 OSD
root@Ceph-201 ~# ceph orch osd rm 3 --zap
Scheduled OSD(s) for removal.
root@Ceph-201 ~# ceph orch osd rm status
# 查看一下删除进度
No OSD remove/replace operations reported
root@Ceph-201 ~# ceph orch ls | grep osd
NAME RUNNING REFRESHED AGE PLACEMENT
osd.all-available-devices 3 3s ago - '<unmanaged>'
'确认服务规则已完全清理'
root@Ceph-201 ~# ceph osd tree
root@Ceph-201 ~# ceph osd tree
0 hdd 0.29300 osd.0 up
1 hdd 0.48830 osd.1 up
2 hdd 1.00000 osd.2 up
root@Ceph-201 ~# ceph -s | egrep 'health:|osd:|pgs:'
health: HEALTH_OK
osd: 3 osds: 3 up (since 2m), 3 in (since 2h)
pgs: 1 active+clean
'这次是彻底删除干净了'
root@Ceph-201 ~# ceph orch device ls | grep Yes | wc -l
4
1)编写新的spec文件
root@Ceph-201 ~# vim osd_spec2.yaml
service_type: osd
service_id: ssd_and_hdd
placement:
hosts:
- Ceph-201
spec:
data_devices:
rotational: 1
# HDD:rotational=1
size: '10G:'
# 容量 ≥ 10G
db_devices:
rotational: 0
# SSD:rotational=0
size: '10G:'
wal_devices:
rotational: 0
# SSD:rotational=0
size: '10G:'
root@Ceph-201 ~# ceph orch device ls --refresh
HOST PATH TYPE SIZE AVAILABLE
Ceph-201 /dev/nvme0n1 ssd 20.0G Yes
Ceph-201 /dev/nvme0n2 ssd 20.0G Yes
Ceph-201 /dev/sdb hdd 300G No
Ceph-201 /dev/sdc hdd 500G No
Ceph-201 /dev/sdd hdd 1024G No
Ceph-201 /dev/sde hdd 20.0G Yes
Ceph-201 /dev/sdf hdd 20.0G Yes
2)预览
Preview data is being generated.. Please re-run this command in a bit.
'执行完,稍微等一会... --> 再执行一遍'
root@Ceph-201 ~# ceph orch apply -i osd_spec2.yaml --dry-run
################
OSDSPEC PREVIEWS
################
+---------+-------------+----------+----------+----+-----+
|SERVICE |NAME |HOST |DATA |DB |WAL |
+---------+-------------+----------+----------+----+-----+
|osd |ssd_and_hdd |Ceph-201 |/dev/sde |- |- |
|osd |ssd_and_hdd |Ceph-201 |/dev/sdf |- |- |
+---------+-------------+----------+----------+----+-----+
'❌️ DB 和 WAL 全是 -,非并置失败——退化成纯 data OSD'
🧱 为什么会退化成纯 data❓️
spec 要的: 实际有的:
data_devices 2 块 HDD ✅ 2 块 HDD (sde, sdf)
db_devices 2 块 SSD ✅ 2 块 SSD (nvme0n1, nvme0n2)
wal_devices 2 块 SSD ❌ 0 块 —— 没多余的 SSD 了!
─────────────────────────────────────
共需 6 块,实有 4 块 → cephadm 凑不齐,全部降级成纯 data OSD
📌 解法一:
删掉 `wal_devices`,WAL 自动复用 db 盘——2 HDD + 2 SSD 刚好配 2 个非并置 OSD
# 我来手动删除
root@Ceph-201 ~# tail -4 osd_spec2.yaml
db_devices:
rotational: 0
# SSD:rotational=0
size: '10G:'
'已经把wal相关配置删除'
root@Ceph-201 ~# ceph orch apply -i osd_spec2.yaml --dry-run
'执行两遍' --> 再次预览结果
################
OSDSPEC PREVIEWS
################
+---------+-------------+----------+----------+--------------+-----+
|SERVICE |NAME |HOST |DATA |DB |WAL |
+---------+-------------+----------+----------+--------------+-----+
|osd |ssd_and_hdd |Ceph-201 |/dev/sde |/dev/nvme0n2 |- |
|osd |ssd_and_hdd |Ceph-201 |/dev/sdf |/dev/nvme0n1 |- |
+---------+-------------+----------+----------+--------------+-----+
✅️ 删除后 4 块盘都用上了
📌 解法二:
💡 如果再加 2 块 NVMe 盘(共 4 块 SSD):
data_devices 2 块 HDD ✅
db_devices 2 块 SSD ✅ nvme0n1, nvme0n2
wal_devices 2 块 SSD ✅ nvme0n3, nvme0n4(新加的)
─────────────────────────────────────
共需 6 块,实有 6 块 → 刚好配出 2 个完整非并置 OSD:
osd.X: sde (data HDD) + nvme0n1 (db SSD) + nvme0n3 (wal SSD)
osd.Y: sdf (data HDD) + nvme0n2 (db SSD) + nvme0n4 (wal SSD)
每个 OSD 独占三块盘,WAL/DB/DATA 全分离 ✅️
root@Ceph-201 ~# ceph orch device ls --refresh
'得强制刷新 2 次'
HOST PATH TYPE SIZE AVAILABLE
Ceph-201 /dev/nvme0n1 ssd 20.0G Yes
Ceph-201 /dev/nvme0n2 ssd 20.0G Yes
Ceph-201 /dev/nvme0n3 ssd 20.0G Yes ✅️
Ceph-201 /dev/nvme0n4 ssd 20.0G Yes ✅️
Ceph-201 /dev/sdb hdd 300G No
Ceph-201 /dev/sdc hdd 500G No
Ceph-201 /dev/sdd hdd 1024G No
Ceph-201 /dev/sde hdd 20.0G Yes
Ceph-201 /dev/sdf hdd 20.0G Yes
⚠️ 别忘记把spec 配置文件改回来
root@Ceph-201 ~# tail -4 osd_spec2.yaml
wal_devices:
rotational: 0
# SSD:rotational=0
size: '10G:'
'把wal相关配置加回来'
root@Ceph-201 ~# ceph orch apply -i osd_spec2.yaml --dry-run
'执行两遍' --> 再次预览结果
################
OSDSPEC PREVIEWS
################
+---------+-------------+----------+----------+----+-----+
|SERVICE |NAME |HOST |DATA |DB |WAL |
+---------+-------------+----------+----------+----+-----+
|osd |ssd_and_hdd |Ceph-201 |/dev/sde |- |- |
|osd |ssd_and_hdd |Ceph-201 |/dev/sdf |- |- |
+---------+-------------+----------+----------+----+-----+
📌 加了 2 块 NVMe(共 4 块 SSD)预览还是纯 data❓️
🧱 根因:db 和 wal 筛选条件一模一样(rotational: 0, size: '10G:')
cephadm 看到 4 块 SSD 全匹配 → 分不清哪块归 db、哪块归 wal
→ 同一个池子分不清 → 放弃,全降纯 data
✅ 解法:wal 和 db 用 paths 明确指盘
root@Ceph-201 ~# vim osd_spec2.yaml
service_type: osd
service_id: ssd_and_hdd
placement:
hosts:
- Ceph-201
spec:
data_devices:
rotational: 1
# HDD:rotational=1
size: '10G:'
# 容量 ≥ 10G
db_devices:
paths:
- /dev/nvme0n1
- /dev/nvme0n2
wal_devices:
paths:
- /dev/nvme0n3
- /dev/nvme0n4
root@Ceph-201 ~# ceph orch apply -i osd_spec2.yaml --dry-run
################
OSDSPEC PREVIEWS
################
+---------+-------------+----------+----------+--------------+--------------+
|SERVICE |NAME |HOST |DATA |DB |WAL |
+---------+-------------+----------+----------+--------------+--------------+
|osd |ssd_and_hdd |Ceph-201 |/dev/sde |/dev/nvme0n2 |- |
|osd |ssd_and_hdd |Ceph-201 |/dev/sdf |/dev/nvme0n1 |/dev/nvme0n4 |
+---------+-------------+----------+----------+--------------+--------------+
🐛 实测发现:cephadm paths 模式下多 OSD WAL 配对 bug
环境:Ceph 20.2.1 (tentacle),cephadm + docker
现象:无论
db_devices和wal_devices用 paths 指 2 块盘还是用属性筛选,cephadm 始终只给一个 OSD 分配独立 WAL,另一个 OSD 的 WAL 恒为-(退化到 DB 盘)即使 data + db + wal 全部用 paths 显式指定,结果依旧
排查过程:
- 所有 NVMe 盘均
AVAILABLE: Yes,无拒绝原因blkid/hexdump确认盘上无残留签名,全零- 换不同 NVMe 盘组合(nvme0n3/nvme0n4 → nvme0n5/nvme0n3),被跳过的盘跟着变
- 结论:不是盘的问题,是 cephadm 的配对算法 bug
💡 WAL 不可共用
-表示 WAL 数据合并写入 DB 盘,≠❌️ 两个 OSD 共用 WAL
ceph osd metadata <id> 拉取的是这个 OSD 的 "档案信息",与业务数据无关:
| 层面 | 存的什么 | 类比 |
|---|---|---|
| 业务数据 | 客户端写入的对象数据 | 仓库里的货物 |
| OSD metadata | OSD 自身的配置、硬件、部署信息 | 仓库门牌——"这台设备是什么、装在哪、用什么盘" |
grep device 常见字段:
root@Ceph-201 ~# ceph osd metadata 0 | grep device
"bluefs_single_shared_device": "1", # 1 = DB/WAL 和 data 在同一块盘(并置)
"bluestore_bdev_devices": "sdb", <--✅️盘的名称 # 数据盘(data)
"default_device_class": "hdd", # 设备类型
"device_ids": "", # 设备 ID 串
"device_paths": "sdb=/dev/disk/by-path/...", # 设备 by-path 路径映射
"devices": "sdb", <--✅️盘的名称 # 设备短名
"osdspec_affinity": "all-available-devices", # 由哪个 spec 规则创建
如果是非并置 OSD(DB 独立盘),还会多出:
"bluefs_dedicated_db": "1", # 1 = DB 在独立盘上
"bluefs_db_devices": "nvme0n3", # DB 盘(只有非并置才出现)
📌 并置 →
bluefs_single_shared_device": "1"非并置 →
bluefs_db_devices": "具体哪块盘"——这两个字段是判断 OSD 部署方式的关键
# ===================================
# 集群状态
# ===================================
ceph -s # 集群整体健康状态
ceph -w # 实时监控集群变化
ceph osd tree # OSD 树(含 class / 权重 / 状态)
ceph osd df # OSD 磁盘使用率
ceph orch host ls # 集群节点列表
ceph orch device ls # 可用磁盘设备
ceph orch ps # 所有服务运行状态
ceph orch ls # 服务编排状态(含 managed/unmanaged)
# ===================================
# OSD 管理
# ===================================
ceph orch daemon add osd <host>:/dev/<disk> # 手动添加 OSD(非托管)
ceph orch osd rm <id> # 删除 OSD
ceph orch osd rm <id> --zap # 删除 OSD + 清除数据
ceph orch osd rm <id> --replace --zap # 替换 OSD
ceph orch osd rm status # 查看删除/替换进度
ceph orch device zap <host> /dev/<disk> --force # 清理磁盘
ceph orch host drain <hostname> # 驱逐节点所有服务
ceph osd crush remove <hostname> # 从 CRUSH 删除主机
ceph orch host rm <hostname> # 从集群删除主机
# ===================================
# 设备类型 (Class) 管理
# ===================================
ceph osd crush rm-device-class <osd-id> # 移除设备 class
ceph osd crush set-device-class <class> <osd-id> # 设置设备 class
# ===================================
# Spec 规则管理
# ===================================
ceph orch apply -i spec.yaml # 应用 spec 规则
ceph orch apply -i spec.yaml --dry-run # 干运行(预览不执行)
ceph orch rm <service_name> --force # 删除 spec 服务规则
# ===================================
# OSD 元数据
# ===================================
ceph osd metadata <id> | grep device # 查看 OSD 对应物理设备