概述Ceph OSD运维管理实战,掌握托管与非托管OSD、设备擦除替换、主机驱逐及非并置部署等核心运维操作
时间2026-05-15
分类Ceph集群
标签Ceph OSD cephadm 设备管理 运维 非并置部署 托管与非托管

OSD运维管理 && 非并置部署


OSD设备管理

命令拆解

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 视角——"服务跑在哪"

托管 vs 非托管

它决定了"删 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 的盘正被占用,AVAILABLENo,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 '

📌 apply spec 不会把已有的非托管 OSD "转换"成托管,它只管在空闲盘上部署新 OSD

⚠️ 删除 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(暂停/恢复 OSD)

outin 是一对可逆操作,跟 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,保证不丢数据


添加 OSD

🌰 语法
ceph orch daemon add osd <host>:<device_path>
                        📌中间👆有 '冒号:'
⚠️ 通过 `daemon add` 添加的 OSD 默认处于 '非托管 (unmanaged)' 状态
# 示例
root@Ceph-201 ~# ceph orch daemon add osd Ceph-201:/dev/sdb

删除 OSD

推荐 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 反而空跑恢复

替换 OSD

# 语法
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 前手动 stop OSD——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 元数据


非并置 OSD 部署 (WAL && DB && DATA 分离)

BlueStore 存储架构

🧱 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

Spec 文件结构拆解

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

方式一:指定具体路径 (path)

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 的 CLASSdata 设备 的类型决定

💡 如果无法直接在宿主机使用 ceph 命令,可挂载 spec 文件到容器中:

cephadm shell --mount osd_spec.yaml:/var/lib/ceph/osd/osd_spec.yaml

删除被 spec 托管的 OSD 后自动恢复

# 删除 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'

正确删除 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

方式二:按属性筛选 (rotational / size)

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_deviceswal_devices 用 paths 指 2 块盘还是用属性筛选,cephadm 始终只给一个 OSD 分配独立 WAL,另一个 OSD 的 WAL 恒为 -(退化到 DB 盘)

即使 data + db + wal 全部用 paths 显式指定,结果依旧

排查过程


💡 WAL 不可共用

- 表示 WAL 数据合并写入 DB 盘,≠❌️ 两个 OSD 共用 WAL

OSD metadata 档案 / 详细信息

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 对应物理设备