OSD运维管理&&非并置部署
OSD运维管理 && 非并置部署
[TOC]
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 osdNAME 'RUNNING' REFRESHED AGE 'PLACEMENT'mgr 2/2 5m ago 25h count:2mon 1/5 5m ago 25h count:5osd.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 lsosd.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 lsosd.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.00000root@Ceph-201 ~# ceph orch osd rm osd.1 --zapUnable to find OSDs: ['osd.1'] ❌️✅️ 直接删除的是 1root@Ceph-201 ~# ceph orch osd rm 1 --zapScheduled 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 lsCeph-201 /dev/sdb hdd 300G Yes ✅️'可以加入OSD设备'root@Ceph-201 ~# ceph orch apply osd --all-available-devicesScheduled 'osd.all-available-devices' update...📌 留意这个名称root@Ceph-201 ~# ceph orch device lsCeph-201 /dev/sdb hdd 300G No ✅️ 过一会才会显示root@Ceph-201 ~# ceph osd tree'都加入进来了'root@Ceph-201 ~# ceph orch lsosd.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 treeID 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)移除原有 classroot@Ceph-201 ~# ceph osd crush rm-device-class osd.1done removing class of osd(s): 1'这个是osd.1'ceph orch osd rm 1 --zap# 直接写ID即可
3)设置新 classroot@Ceph-201 ~# ceph osd crush set-device-class ssd osd.1set 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)
out 和 in 是一对可逆操作,跟 rm(真删除)是两回事:
ceph osd out --> 告诉 CRUSH:"现存的数据搬走,别往这块盘放数据了"ceph osd in --> "行了,可以继续用了"ceph osd rm --> 真删了,OSD 没了⚠️ 注意区分两个层面的”可逆”:
| 层面 | out —> in 之后 |
|---|---|
| OSD 本身 | ✅ 可恢复——==盘还在==、==进程没停==、in 后继续用 |
| 盘上的数据 | ❌ 不可逆——out 时数据已经被搬到其他 OSD 了,in 后是空盘 |
所以==“可逆”==说的是 OSD 这个盘没被销毁,还能继续服役
1)暂停使用 osd.1root@Ceph-201 ~# ceph osd treeID 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.1marked out osd.1.root@Ceph-201 ~# ceph osd treeID 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.1marked 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 +(可选)清磁盘
- 📌 删除后是否自动重建 OSD —> 看托管状态,不是看命令选项
ceph orch osd rm status —> 查看删除进度
⚠️ 防止单节点删除卡住:`.mgr` 池默认副本数 ≥ 2,单节点删 OSD 优先降副本
root@Ceph-201 ~# ceph osd pool ls detailpool 1 '.mgr' replicated size 2 min_size 1 crush_rule 0✅️ size=2 想要2副本 min_size=1 最少1副本就能IOroot@Ceph-201 ~# ceph osd pool set .mgr size 1 --yes-i-really-mean-itError 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 trueroot@Ceph-201 ~# ceph osd pool set .mgr size 1 --yes-i-really-mean-itset pool 1 size to 1root@Ceph-201 ~# ceph osd pool ls detailpool 1 '.mgr' replicated size 1 min_size 1 crush_rule 0✅️ 副本数设置为 1root@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 1Error EBUSY: osd.1 is still up; must be down before removal.❌️ ceph osd rm 删不了还在 up 的 OSD --> 必须先停进程root@Ceph-201 ~# ceph osd rm 1 --forceError 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/downScheduled 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 --zapScheduled OSD(s) for removal.✅️ 删除 + 清除磁盘数据(磁盘恢复为 AVAILABLE: Yes)root@Ceph-201 ~# ceph orch osd rm status'查看删除进度'OSD HOST STATE PGS REPLACE FORCE ZAP DRAIN STARTED AT1 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.4ceph orch osd rm 2 --zap--> osd tree: osd.0, osd.1, osd.3, osd.4 <-- '换了张新面孔,换了台主机'
# 加 --replace:osd.2 被标记"等着补回来" → 新盘顶上还是 osd.2ceph 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 lsHOST ADDR LABELS STATUSCeph-201 10.0.0.201 _adminCeph-202 10.0.0.202Ceph-203 10.0.0.2033 hosts in clusterroot@Ceph-201 ~# ceph orch ps Ceph-203'PS查看各个进程的' --> 单独看 Ceph-203 主机的⚠️ 不是ls ⚠️NAME HOST PORTS STATUSmon.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-203Scheduled to remove the following daemons from host 'Ceph-203'type id-------------------- ---------------osd 8osd 6osd 7mon Ceph-203'多次执行直到输出为空,确认所有 daemon 移除任务已下发完毕'📌 drain 输出为空 = 任务调度完成 ≠ 数据已搬完——这只是第一步root@Ceph-201 ~# ceph orch host drain Ceph-203Scheduled to remove the following daemons from host 'Ceph-203'type id-------------------- ---------------'现在什么都没有了'root@Ceph-201 ~# ceph orch host lsHOST ADDR LABELS STATUSCeph-201 10.0.0.201 _adminCeph-202 10.0.0.202Ceph-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> --forceroot@Ceph-201 ~# ceph orch device zap Ceph-203 /dev/sdb --forceroot@Ceph-201 ~# ceph orch device zap Ceph-203 /dev/sdc --forceroot@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-203removed item id -7 name 'Ceph-203' from crush map
5)从集群删除主机root@Ceph-201 ~# ceph orch host ls | grep Ceph-203Ceph-203 10.0.0.203 _no_schedule,_no_conf_keyring📌 编排器层:把主机从 cephadm 管理名单中踢出去,集群不再知道这台机器root@Ceph-201 ~# ceph orch host rm Ceph-203Removed host 'Ceph-203'root@Ceph-201 ~# ceph orch host ls | grep Ceph-203 | wc -l0root@Ceph-201 ~# ceph orch host lsHOST ADDR LABELS STATUSCeph-201 10.0.0.201 _adminCeph-202 10.0.0.2022 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-mapperzap 之后: 磁盘上 LVM 已清除 ✅ 内核 dm 映射'可能'残留 ⚠️ ↓ lsblk 若还能看到 dm-0 → dmsetup remove dm-0 清掉# 被驱逐节点:删除 cephadm 数据目录(删的是配置文件,不是块设备数据)'是被删除节点的数据' ⚠️ Ceph-203上执行root@Ceph-203 ~# ls /var/lib/ceph/fdc2219c-5344-11f1-8042-000c2990a57eroot@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 ~# lsblkNAME SIZE RO TYPEsdb 300G 0 disk└─ceph-xxxsdc 500G 0 disk└─ceph-xxxsdd 1T 0 disk└─ceph-xxx'上面三个已经在集群种了'sde 20G 0 disksdf 20G 0 disknvme0n1 20G 0 disknvme0n2 20G 0 diskroot@Ceph-201 ~# ceph orch device ls --refresh--refresh # 绕开缓存直接触发一次新扫描HOST PATH TYPE SIZE AVAILABLECeph-201 /dev/nvme0n1 ssd 20.0G NoCeph-201 /dev/nvme0n2 ssd 20.0G NoCeph-201 /dev/sdb hdd 300G NoCeph-201 /dev/sdc hdd 500G NoCeph-201 /dev/sdd hdd 1024G NoCeph-201 /dev/sde hdd 20.0G NoCeph-201 /dev/sdf hdd 20.0G No'触发强扫后,自动添加上去了'root@Ceph-201 ~# ceph orch lsNAME RUNNING REFRESHED AGE PLACEMENTosd.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 --forceroot@Ceph-201 ~# ceph orch rm osd.default --forceroot@Ceph-201 ~# ceph orch lsNAME RUNNING REFRESHED AGE PLACEMENTosd.all-available-devices 6 4m ago - '<unmanaged>'osd.default 1 4m ago - '<unmanaged>'
2)删 OSD + zap → 磁盘变 AVAILABLE: Yesroot@Ceph-201 ~# ceph orch osd rm 3 --zaproot@Ceph-201 ~# ceph orch osd rm 4 --zaproot@Ceph-201 ~# ceph orch osd rm 5 --zaproot@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+cleanroot@Ceph-201 ~# ceph orch device ls | grep Yes | wc -l4'这四个已经变为Yes状态'
3)写 spec 文件(data on HDD, db/wal on NVMe)root@Ceph-201 ~# vim osd_spec.yamlSpec 文件结构拆解
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 + nvme0n2Spec 设备筛选 —> ==常用属性==
| 属性 | 说明 | 示例值 |
|---|---|---|
rotational | 0=SSD/NVMe, 1=HDD | 0 |
size | 设备容量范围 | '10G:' (≥10G) |
paths | 指定具体设备路径 | /dev/sda |
方式一:指定具体路径 (path)
service_type: osdservice_id: osd_using_pathsplacement: hosts: - Ceph-201spec: data_devices: paths: - /dev/sde # 数据盘:SATA HDD db_devices: paths: - /dev/nvme0n1 # 元数据盘:NVMe SSD wal_devices: paths: - /dev/nvme0n2 # WAL盘:NVMe SSD4)预演不执行root@Ceph-201 ~# ceph orch apply -i osd_spec.yaml --dry-run--dry-run # 干运行(预览)'把 spec 匹配结果算出来给你看,但不会真的创建 OSD'# 确认结果对了再拿掉 --dry-run 正式 apply....xxxPreview 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# 确认无误后正式 applyroot@Ceph-201 ~# ceph orch lsNAME RUNNING REFRESHED AGE PLACEMENTosd.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+cleanroot@Ceph-201 ~# ceph orch apply -i osd_spec.yamlScheduled osd.osd_using_paths update...root@Ceph-201 ~# ceph orch lsNAME RUNNING REFRESHED AGE PLACEMENTosd.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+cleanroot@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删除被 spec 托管的 OSD 后自动恢复
# 删除 osd.3root@Ceph-201 ~# ceph orch osd rm 3 --zapScheduled 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_pathsroot@Ceph-201 ~# ceph orch ls | grep osdNAME RUNNING REFRESHED AGE PLACEMENTosd.all-available-devices 3 8m ago - '<unmanaged>'osd.osd_using_paths 1 8m ago - '<unmanaged>''此时服务变为 <unmanaged>,OSD 进程还在'
2)再删除具体的 OSDroot@Ceph-201 ~# ceph orch osd rm 3 --zapScheduled OSD(s) for removal.root@Ceph-201 ~# ceph orch osd rm status# 查看一下删除进度No OSD remove/replace operations reportedroot@Ceph-201 ~# ceph orch ls | grep osdNAME RUNNING REFRESHED AGE PLACEMENTosd.all-available-devices 3 3s ago - '<unmanaged>''确认服务规则已完全清理'root@Ceph-201 ~# ceph osd treeroot@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 -l4方式二:按属性筛选 (rotational / size)
1)编写新的spec文件root@Ceph-201 ~# vim osd_spec2.yamlservice_type: osdservice_id: ssd_and_hddplacement: hosts: - Ceph-201spec: 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 --refreshHOST PATH TYPE SIZE AVAILABLECeph-201 /dev/nvme0n1 ssd 20.0G YesCeph-201 /dev/nvme0n2 ssd 20.0G YesCeph-201 /dev/sdb hdd 300G NoCeph-201 /dev/sdc hdd 500G NoCeph-201 /dev/sdd hdd 1024G NoCeph-201 /dev/sde hdd 20.0G YesCeph-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.yamldb_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 AVAILABLECeph-201 /dev/nvme0n1 ssd 20.0G YesCeph-201 /dev/nvme0n2 ssd 20.0G YesCeph-201 /dev/nvme0n3 ssd 20.0G Yes ✅️Ceph-201 /dev/nvme0n4 ssd 20.0G Yes ✅️Ceph-201 /dev/sdb hdd 300G NoCeph-201 /dev/sdc hdd 500G NoCeph-201 /dev/sdd hdd 1024G NoCeph-201 /dev/sde hdd 20.0G YesCeph-201 /dev/sdf hdd 20.0G Yes⚠️ 别忘记把spec 配置文件改回来root@Ceph-201 ~# tail -4 osd_spec2.yamlwal_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.yamlservice_type: osdservice_id: ssd_and_hddplacement: hosts: - Ceph-201spec: data_devices: rotational: 1 # HDD:rotational=1 size: '10G:' # 容量 ≥ 10G db_devices: paths: - /dev/nvme0n1 - /dev/nvme0n2 wal_devices: paths: - /dev/nvme0n3 - /dev/nvme0n4root@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
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> # 删除 OSDceph orch osd rm <id> --zap # 删除 OSD + 清除数据ceph orch osd rm <id> --replace --zap # 替换 OSDceph 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> # 移除设备 classceph 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 对应物理设备文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!




