# 第 06 册 · ceph-volume 磁盘管理篇 > 基于 Ceph 官方文档整理 | 文档版本:**Tentacle v20.2.4** | 抓取日期:2026-09-17 | 源文:ceph/ceph@v20.2.4 `doc/ceph-volume/` > 官网入口:https://docs.ceph.com/en/tentacle/ceph-volume/ --- ## 本册导读 ### 本册覆盖的官方页面(共 24 个 rst 源文) | # | 源文路径 | 页面标题 | 本册章节 | |---|---------|---------|---------| | 1 | `ceph-volume/index.rst` | ceph-volume | 一、本册导读 | | 2 | `ceph-volume/intro.rst` | Overview | 一 | | 3 | `ceph-volume/systemd.rst` | systemd | 二 · systemd 集成 | | 4 | `ceph-volume/inventory.rst` | inventory | 五 | | 5 | `ceph-volume/drive-group.rst` | drive-group | 六 | | 6 | `ceph-volume/lvm/index.rst` | lvm | 二 | | 7 | `ceph-volume/lvm/prepare.rst` | prepare | 二 | | 8 | `ceph-volume/lvm/activate.rst` | activate | 二 | | 9 | `ceph-volume/lvm/create.rst` | create | 二 | | 10 | `ceph-volume/lvm/batch.rst` | batch | 二 | | 11 | `ceph-volume/lvm/list.rst` | list | 二 | | 12 | `ceph-volume/lvm/scan.rst` | scan | 二 | | 13 | `ceph-volume/lvm/zap.rst` | zap | 二 | | 14 | `ceph-volume/lvm/migrate.rst` | migrate | 二 | | 15 | `ceph-volume/lvm/newdb.rst` | new-db | 二 | | 16 | `ceph-volume/lvm/newwal.rst` | new-wal | 二 | | 17 | `ceph-volume/lvm/encryption.rst` | Encryption | 二 · 加密 | | 18 | `ceph-volume/lvm/systemd.rst` | systemd(lvm) | 二 · systemd 集成 | | 19 | `ceph-volume/simple/index.rst` | simple | 三 | | 20 | `ceph-volume/simple/scan.rst` | scan(simple) | 三 | | 21 | `ceph-volume/simple/activate.rst` | activate(simple) | 三 | | 22 | `ceph-volume/simple/systemd.rst` | systemd(simple) | 三 | | 23 | `ceph-volume/zfs/index.rst` | zfs | 四 | | 24 | `ceph-volume/zfs/inventory.rst` | inventory(zfs) | 四 | ### 建议阅读顺序 | 阶段 | 读什么 | 目的 | |------|--------|------| | 1 | 本册第一章「ceph-volume 是什么」 | 建立定位:它替代谁、有哪些后端、处在 OSD 生命周期哪一段 | | 2 | `inventory`(第五章) | 先学会「看清这台机器上有哪些盘、哪些能用」,这是所有操作的前提 | | 3 | `lvm prepare` → `lvm activate` → `lvm create` | 理解 OSD 部署的两步模型与一步模型 | | 4 | `lvm batch` + `drive-group`(第六章) | 学会多盘批量部署与预演 | | 5 | `lvm list` / `scan` / `zap` | 日常巡检、发现与回收 | | 6 | `lvm migrate` / `new-db` / `new-wal` | 运维期的 db/wal 迁移与扩容 | | 7 | `encryption` + `systemd` | 加密原理与开机自启动机制 | | 8 | `simple` / `zfs` | 历史兼容与边缘平台,按需了解 | > 💡 补充:如果你只打算做「临时验证」或「单盘快速起一个 OSD」,最短路径是 `ceph-volume lvm inventory` → `ceph-volume lvm batch --report ...`(预演)→ 去掉 `--report` 实跑。 ### ceph-volume 与 cephadm 的关系(重要) - **日常部署由 cephadm 调用,你通常不需要直接敲 `ceph-volume`。** 现代 Ceph 集群(Octopus 之后)通过 `cephadm` / `orch` 管理 OSD,`cephadm` 在内部调用 `ceph-volume` 完成实际的设备准备与激活;`ceph-volume lvm activate` 页面明确写着「For information about OSDs deployed by cephadm, refer to :ref:`cephadm-osd-activate`」,即 cephadm 部署的 OSD 激活要看 cephadm 那一侧。 - **但理解底层很重要**,原因有三: 1. **排障需要**:OSD 起不来、设备被跳过、db/wal 没按预期分配,最终都要落到 `ceph-volume` 的日志与 LVM tag 上去判断。 2. **运维动作仍在 ceph-volume 层**:`zap`、`migrate`、`new-db`、`new-wal`、`list` 这些子命令,很多场景需要人工直接执行(例如换盘、迁移 db、擦除设备)。`newdb.rst` 中的 spillover 修复流程甚至混用了 `cephadm shell` + `ceph-bluestore-tool`。 3. **概念复用**:drive group 最终会被翻译成「一次 `ceph-volume lvm batch` 调用」(`drive-group.rst`、`batch.rst` 均如此表述),不理解 `batch` 就看不懂 drive group 实际做了什么。 - **边界提示**:由 cephadm 部署的 OSD,激活相关操作请优先使用 cephadm 提供的入口,不要混用 `ceph-volume lvm activate`。 > 引自:[ceph-volume](https://docs.ceph.com/en/tentacle/ceph-volume/) --- ## 一、ceph-volume 是什么 ### 1.1 定位 `ceph-volume` 是一个**单一用途的命令行工具**,用来把逻辑卷(logical volume)部署成 OSD,并在 prepare / activate / create OSD 这些动作上尽量保持与老工具 `ceph-disk` 相似的 API。 它的设计目标: - 用**可插拔的 tool/plugin** 来支持不同的设备技术(LVM、裸盘/GPT 分区、ZFS 等);`lvm` 本身就被当作一个 plugin 对待。 - 走一条**可预测、健壮**的 prepare → activate → start OSD 的路径。 - **刻意不依赖 udev 规则**:这一点与 `ceph-disk` 根本不同。`ceph-disk` 依赖随 Ceph 安装的 udev 规则来自动发现此前已配置好的设备并回喂给自身去激活。 ### 1.2 它替代了什么:为什么 `ceph-disk` 被替换 `ceph-disk` 诞生于需要同时支持 upstart、sysvinit 等多种 init 系统、又要能发现设备的年代,因此它把全部重心压在了 **GPT 分区(尤其 GPT GUID)** 上,用 GUID 来回答: - 这个设备是 Journal 吗? - 是一个加密的数据分区吗? - 这个设备是不是处于「部分 prepared」的半途状态? 它用 `UDEV` 规则匹配这些 GUID,规则回调 `ceph-disk`,而 `ceph-disk` 又与自己的 systemd unit 来回交互。官方对该机制的评价是: > 这个过程非常不可靠、非常耗时(**每个 OSD** 不得不设置接近三小时的超时),并且会导致节点启动过程中 OSD 完全起不来。由于 UDEV 的异步行为,这些问题很难调试、甚至很难复现。 此外,因为 `ceph-disk` 的世界观只能是 GPT 分区,它**无法与 LVM 或其他 device mapper 设备协作**。最终社区决定做一个模块化的东西,从 LVM 起步,并保留扩展其他技术的能力。 ### 1.3「GPT 分区很简单」其实是个误解 虽然「分区」本身容易理解,但 `ceph-disk` 的分区一点都不简单——它需要大量特殊标志配合设备发现流程。创建一个数据分区的实际调用长这样: ```bash /sbin/sgdisk --largest-new=1 --change-name=1:ceph data \ --partition-guid=1:f0fc39fd-eeb2-49f1-b922-a11939cf8a0f \ --typecode=1:89c57f98-2fe5-4dc0-89c1-f3ad0ceff2be --mbrtogpt -- /dev/sdb ``` 更难的是,这些分区要求设备被 Ceph **独占**。例如加密时还要额外建一个存放未加密密钥的特殊分区(lockbox): ```bash /sbin/sgdisk --new=5:0:+10M --change-name=5:ceph lockbox \ --partition-guid=5:None --typecode=5:fb3aabf9-d25f-47cc-bf5e-721d181642be \ --mbrtogpt -- /dev/sdad ``` 这些都属于 `ceph-disk` 的领域知识,无法被简化成「GPT 分区很简单」的理解。 ### 1.4 模块化设计与支持的后端 `ceph-volume` 被设计成模块化工具,因为可以预见到「人们配置硬件设备的方式」会越来越多。官方点名的几种: | 后端(plugin) | 子命令 | 适用场景 | 本册章节 | |---------------|--------|---------|---------| | `lvm` | `ceph-volume lvm` | **新部署的推荐后端**。可用任意 logical volume 作为 data OSD 输入,也可以从一块设备自动建一个 minimal/naive 的 logical volume | 二 | | `simple` | `ceph-volume simple` | 接管此前由 `ceph-disk` 部署的、带 GPT 分区的遗留 OSD。扫描 data device 或 OSD 目录后彻底禁用 `ceph-disk`。**完全支持加密** | 三 | | `zfs` | `ceph-volume zfs` | 用于运行 FreeBSD 集群(index.rst:「zfs support is available for running a FreeBSD cluster」) | 四 | | SPDK | 文档未明确子命令 | 官方称「直接在用户态管理 NVMe 设备的 SPDK 已在近期地平线上」,因为完全不经过内核,LVM 在那里行不通 | 见「文档未明确项」 | > 引自:[Overview](https://docs.ceph.com/en/tentacle/ceph-volume/intro/) ### 1.5 迁移路径(从 ceph-disk 到 ceph-volume) 从 Ceph **13.0.0** 起 `ceph-disk` 已废弃(deprecated),废弃警告会链接到 ceph-volume 文档页。官方强烈建议用户改用 `ceph-volume`。两条迁移路径: | 路径 | 做法 | 说明 | |------|------|------| | 保留原 OSD | 用 `ceph-volume simple` 接管管理 | 接管的同时禁用 `ceph-disk` 的触发器(triggers) | | 重新部署 | 用 `ceph-volume` 重新部署既有 OSD | 详见 `rados-replacing-an-osd`(本册范围外) | ### 1.6 新部署 / 既有 OSD 的官方建议 - **新部署**:推荐 `ceph-volume lvm`。 - **已有 OSD**(由 `ceph-disk` 配置):用 `ceph-volume simple` 接管,对 data device 或 OSD 目录做一次 scan,之后 `ceph-disk` 被完全禁用,加密也完全支持。 ### 1.7 LVM tags:ceph-volume 的元数据基石 `ceph-volume lvm` 子命令通过 **LVM tags** 存储、并能在之后重新发现和查询与 OSD 关联的设备,从而完成激活。这是它与 `ceph-disk`(靠 GPT GUID + udev)最本质的技术分野。 ### 1.8 LVM 的性能代价 官方的表述非常直接: > 简而言之:我们没有发现任何与改用 LVM 相关的显著性能损失。并且由于能与 LVM 紧密协作,与其他 device mapper 技术协作的能力是顺理成章的——任何能位于 Logical Volume 之下的东西,在技术上都没有难度。 ### 1.9 与 OSD 生命周期的关系 | 生命周期阶段 | 由谁负责 | 对应子命令 | |-------------|---------|-----------| | 设备发现 / 可用性判断 | `ceph-volume inventory` | 见第五章 | | 规划与批量选择 | `ceph-volume lvm batch`(drive group 翻译而来) | `--report` 预演 | | 准备(写元数据、建 LV、`ceph-osd --mkfs`) | `lvm prepare` | 写 LVM tags,**不改动卷的其他内容** | | 激活(挂载、建 tmpfs、起 unit) | `lvm activate` | enable systemd unit | | 一步到位 | `lvm create` = `prepare` + `activate` | | | 运行期巡检 | `lvm list` | | | 运行期调整 db/wal | `lvm migrate` / `lvm new-db` / `lvm new-wal` | | | 退役 / 回收 | `lvm zap`(`--destroy`) | | | 遗留接管 | `simple scan` → `simple activate` | | > 引自:[ceph-volume](https://docs.ceph.com/en/tentacle/ceph-volume/)、[Overview](https://docs.ceph.com/en/tentacle/ceph-volume/intro/) --- ## 二、lvm 后端(重点) `lvm` 子命令实现了从 LVM 部署 OSD 所需的全部功能:`ceph-volume lvm`。 官方列出的用户可见子命令:`prepare`、`activate`、`create`、`list`、`migrate`、`new-db`、`new-wal`。 (`scan` 在 `lvm/index.rst` 的 toctree 中被注释为 `not yet implemented`,见 2.9。) > 引自:[lvm](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/) ### 2.1 四个核心动作:prepare / activate / create / batch 的区别与选择 | 子命令 | 干什么 | 是否立即 up/in | 是否联系 monitor 申请 OSD ID | 幂等 | 典型场景 | |--------|--------|---------------|---------------------------|------|---------| | `prepare` | 给 LV 打上 Ceph 元数据(LVM tags),创建 OSD 目录与符号链接,取 monmap,用 `ceph-osd --mkfs` 填充目录。**不改动卷的其他内容** | 否 | 是(除非显式给 `--osd-id`/`--osd-fsid`) | 文档未明确 | 想**逐步**把新 OSD 引入集群、避免一次性大量数据 rebalance | | `activate` | 启用 systemd unit,把 OSD ID + UUID 持久化;挂载设备、确保设备就绪、启动 `ceph-osd@` | 是 | 否(消费已有 ID/UUID) | **是(fully idempotent)** | 与 `prepare` 配合的两步流程第二步 | | `create` | 把 `prepare` + `activate` 包成一次调用 | **是,命令结束即 up and in** | 同 `prepare` | 文档未明确 | 单盘/少量盘、不在意瞬时 rebalance 的场合 | | `batch` | 基于 `create` 的同一套代码路径,额外负责**计算所有卷的合适大小**并**跳过已创建的卷**;一次部署多个 OSD | 是 | 同 `create` | **是(设计为幂等)** | 多盘批量部署;drive group 的实际执行者 | **怎么选:** - 想**平滑扩容**(一次只放一个 OSD 进集群,控制 rebalance 速率)→ `prepare` 然后 `activate`。 - 想**一条命令搞定**、且能接受 OSD 立刻 up/in → `create`。 - 有**一批盘**要一起上,或你其实在用 drive group → `batch`,并且**先用 `--report` 预演**。 - 关于 `create` 的官方提醒:`prepare` + `activate` 分开做的价值在于「逐步引入新 OSD,避免大量数据被 rebalance」。`create` 除了「OSD 会在完成后立刻 up and in」之外,过程与两步完全一致。 > 引自:[prepare](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/prepare/)、[activate](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/activate/)、[create](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/create/)、[batch](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/batch/) --- ### 2.2 `prepare`:参数逐项说明 `prepare` 会给 logical volume **添加元数据,但不会以任何其他方式改动它**。官方建议:先自行 provision 一个 logical volume,再在其上跑 `prepare`。 `prepare` 用 **LVM tags** 给 LV 打上若干元数据,被这样打标的卷更容易识别、也更容易被 Ceph 使用;tags 用来标识 LV 在集群中扮演的角色(例如:BlueStore data 或 BlueStore WAL+DB)。 #### 2.2.1 通用 / bluestore 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | `--bluestore` | **默认后端**(文档称 BlueStore 是新 OSD 的默认后端) | 指定 OSD 后端为 bluestore。Ceph 允许改后端,可通过此 flag 显式指定 | `ceph-volume lvm prepare --bluestore --data vg/lv` | | `--data` | 无(必填) | 指定 `block` 设备(即主数据设备)。可接受**物理块设备**、**物理设备上的分区**、或 **logical volume** 三种形态 | `--data vg/lv`、`--data /path/to/device` | | `--block.db` | 无(bluestore 下可选) | 指定 `block.db` 设备。可为物理设备、分区或 logical volume | `--block.db /dev/sda1` | | `--block.wal` | 无(bluestore 下可选) | 指定 `block.wal` 设备。可为物理设备、分区或 logical volume | `--block.wal /dev/ceph/osd-wal-0` | | `--dmcrypt` | 关闭 | 启用 dmcrypt 加密。启用加密时**必须**带此 flag | `--dmcrypt --data vg/lv` | | `--with-tpm` | 关闭 | **自 Ceph Squid 起可用**:为创建的 LUKS2 设备选择 TPM2 token enrollment。需与 `--dmcrypt` 同用 | `--dmcrypt --with-tpm --data vg/lv` | | `--crush-device-class` | 文档未明确 | 设置该 OSD 的 CRUSH device class | `--crush-device-class foo` | | `--osd-id` | 由 monitor 分配 | 指定 OSD ID。给定后命令行**不会**去联系 monitor 生成 OSD ID | `--osd-id 0` | | `--osd-fsid` | 运行时生成 UUID | 指定 OSD FSID(UUID) | `--osd-fsid E3D291C1-E7BF-4984-9794-B60D9FA139CB` | | `--filestore` | 非默认 | 指定 filestore 后端(**Reef 起已废弃且不再支持**) | `--filestore --data ` | | `--journal` | 无(filestore 下可选) | filestore 的 journal 设备。可为物理块设备、分区、logical volume | `--journal /dev/sdc1` | #### 2.2.2 bluestore 支持的配置组合 | 组合 | 说明 | |------|------| | block + block.wal + block.db | 三者齐全 | | block + block.wal | 有 WAL 无独立 DB | | block + block.db | 有 DB 无独立 WAL | | block(单设备) | 只有一个 block 设备 | #### 2.2.3 关于设备形态的重要规则 - 对 `--data`:如果给的是**物理块设备**,会**自动创建 logical volume**。 - 如果提供的 volume group 名字以 `ceph` 开头:不存在则创建,已存在则**被 clobber 并复用**。这让 LVM 用法更简单,但代价是不灵活——**没有任何选项或配置可以改变 logical volume 的创建方式**。 - 对 `--block.db` / `--block.wal`:**分区可以原样使用**,因此不会被做成 logical volume。 - 命名约定(当传入设备、由 ceph-volume 自建 VG/LV 时): - volume group 名:`ceph-{cluster fsid}`;若该 VG 已存在,则为 `ceph-{random uuid}` - logical volume 名:`osd-block-{osd_fsid}` #### 2.2.4 典型命令 ```bash # 最简:在已有 LV 上准备 ceph-volume lvm prepare --bluestore --data vg/lv # 直接给裸设备(会自动创建 VG/LV) ceph-volume lvm prepare --bluestore --data /path/to/device # 启用 dmcrypt 加密 ceph-volume lvm prepare --bluestore --dmcrypt --data vg/lv # 启用 dmcrypt + TPM2 token enrollment(Squid+) ceph-volume lvm prepare --bluestore --dmcrypt --with-tpm --data vg/lv # 指定 CRUSH device class ceph-volume lvm prepare --bluestore --data vg/lv --crush-device-class foo ``` #### 2.2.5 OSD 目录与符号链接 创建 OSD 目录时,流程使用一个 **`tmpfs` 挂载**来存放 OSD 所需文件;这些文件由 `ceph-osd --mkfs` 创建,是**临时(ephemeral)**的。 `block` 设备会创建符号链接,`block.db` 与 `block.wal` 的符号链接是可选的。默认集群名 + OSD ID 为 0 时: ```bash ls -l /var/lib/ceph/osd/ceph-0 ``` ```text lrwxrwxrwx. 1 ceph ceph 93 Oct 20 13:05 block -> /dev/ceph-be2b6fbd-bcf2-4c51-b35d-a35a162a02f0/osd-block-25cf0a05-2bc6-44ef-9137-79d65bd7ad62 lrwxrwxrwx. 1 ceph ceph 93 Oct 20 13:05 block.db -> /dev/sda1 lrwxrwxrwx. 1 ceph ceph 93 Oct 20 13:05 block.wal -> /dev/ceph/osd-wal-0 -rw-------. 1 ceph ceph 37 Oct 20 13:05 ceph_fsid -rw-------. 1 ceph ceph 37 Oct 20 13:05 fsid -rw-------. 1 ceph ceph 55 Oct 20 13:05 keyring -rw-------. 1 ceph ceph 6 Oct 20 13:05 ready -rw-------. 1 ceph ceph 10 Oct 20 13:05 type -rw-------. 1 ceph ceph 2 Oct 20 13:05 whoami ``` OSD 数据目录命名约定: ```text /var/lib/ceph/osd/- ``` #### 2.2.6 filestore(已废弃,仅供历史理解) > ⚠️ 官方 warning:**Filestore 在 Reef 版本已废弃,不再被支持。** - filestore 用一个 logical volume 存 OSD 数据,用物理设备/分区/logical volume 存 journal。 - 若用物理设备创建 filestore 后端,会在该设备上创建 logical volume。 - 若提供的 VG 名以 `ceph` 开头:不存在则建,已存在则 clobber 并复用。 - 对这些卷无需特殊准备,但要满足 OSD 数据与 journal 的**最小容量要求**(具体数值文档未明确)。 ```bash # 基本 filestore OSD ceph-volume lvm prepare --filestore --data # 带外部 journal ceph-volume lvm prepare --filestore --data --journal # 启用加密(--dmcrypt 必需) ceph-volume lvm prepare --filestore --dmcrypt --data --journal ``` **filestore 的形态约束:** - 用 logical volume 部署时,传入值**必须**是 `volume_group/logical_volume_name` 格式。因为 LV 名不强制唯一,这个格式是防止选错卷(并 clobber 掉数据)的重要保障。 - 用分区部署时,分区**必须**含有一个能被 `blkid` 发现的 `PARTUUID`,以确保无论设备名/路径如何变化都能被正确识别。 ```bash # LV 存数据 + 分区做 journal ceph-volume lvm prepare --filestore --data volume_group/logical_volume_name --journal /dev/sdc1 # 裸设备存数据 + LV 做 journal ceph-volume lvm prepare --filestore --data /dev/sdc --journal volume_group/journal_lv ``` 向集群申请新 OSD 时会使用一个**生成的 UUID**。OSD ID 与 OSD UUID 这两项信息是识别某个 OSD 的必要条件,并会在后续整个 activation 流程中使用。 filestore 手工流程(文档给出的完整步骤): ```bash # 1. 把 journal 卷链接到已挂载的数据卷 ln -s /path/to/journal /var/lib/ceph/osd/-/journal # 2. 用 OSD 的 bootstrap key 抓取 monmap /usr/bin/ceph --cluster ceph --name client.bootstrap-osd --keyring \ /var/lib/ceph/bootstrap-osd/ceph.keyring mon getmap -o \ /var/lib/ceph/osd/-/activate.monmap # 3. 填充已挂载的 OSD 目录 ceph-osd --cluster ceph --mkfs --mkkey -i --monmap \ /var/lib/ceph/osd/-/activate.monmap --osd-data \ /var/lib/ceph/osd/- --osd-journal \ /var/lib/ceph/osd/-/journal --osd-uuid \ --keyring /var/lib/ceph/osd/-/keyring --setuser ceph \ --setgroup ceph ``` #### 2.2.7 分区(Partitioning) **`ceph-volume lvm` 目前不会从整块设备创建分区。** 如果你要用分区,唯一要求是它含有 `PARTUUID` 且能被 `blkid` 发现——`fdisk` 和 `parted` 新建分区时都会自动带上。 用 `parted` 在一块全新未格式化的盘(此处为 `/dev/sdd`)上建分区的完整过程: ```bash # 1) 先看看设备信息 parted --script /dev/sdd print ``` ```text Model: VBOX HARDDISK (scsi) Disk /dev/sdd: 11.5GB Sector size (logical/physical): 512B/512B Disk Flags: ``` ```bash # 2) 设备还没有 label,先建 gpt label 并复查 parted --script /dev/sdd mklabel gpt parted --script /dev/sdd print ``` ```text Model: VBOX HARDDISK (scsi) Disk /dev/sdd: 11.5GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: ``` ```bash # 3) 建一个分区,并确认 blkid 能找到 ceph-volume 需要的 PARTUUID parted --script /dev/sdd mkpart primary 1 100% blkid /dev/sdd1 ``` ```text /dev/sdd1: PARTLABEL="primary" PARTUUID="16399d72-1e1f-467d-96ee-6fe371a7d0d4" ``` #### 2.2.8 对既有 OSD 使用 prepare > ⚠️ 官方 warning:**该过程会强制格式化数据设备,销毁其上的既有数据(如果有的话)。** 需要注意: - OSD 路径应遵循约定 `/var/lib/ceph/osd/-` - 最好不要存在其他挂载该卷的机制,已有的应移除(如 fstab 挂载点) 对 ID 为 0、集群名为 `ceph` 的既有 OSD,一次性过程如下(**会销毁该 OSD 中所有数据**): ```bash ceph-volume lvm prepare --filestore --osd-id 0 --osd-fsid E3D291C1-E7BF-4984-9794-B60D9FA139CB ``` 命令行工具此时**不会**联系 monitor 生成 OSD ID,并且除了格式化 LVM 设备外,还会把元数据存储其上,以便之后能启动。 #### 2.2.9 multipath 支持 `multipath` 设备在 `lvm` 配置正确的前提下是被支持的。 | 方式 | 说明 | |------|------| | **交给 LVM** | 大多数 Linux 发行版的 LVM2 包默认配置中带 `multipath_component_detection = 1`。有了这个设置,LVM 会忽略任何属于 multipath 组成部分的设备,`ceph-volume` 也就不会去碰这些设备。 | | **使用 filters** | 如果该设置不可用,则必须在 `lvm.conf` 中提供正确的 `filter` 表达式。`ceph-volume` **绝不能**同时使用 multipath 设备及其成员设备。 | #### 2.2.10 prepare 阶段写入的 LVM tags 无论卷类型(journal 或 data)或 OSD objectstore 是什么,准备过程都会打上以下 tags: - `cluster_fsid` - `encrypted` - `osd_fsid` - `osd_id` - `crush_device_class` 对 **bluestore**,还会额外添加: - `block_device` - `block_uuid` - `db_device` - `db_uuid` - `wal_device` - `wal_uuid` > 💡 补充:在 `lvm list --format=json` 的实际输出中,可以看到 tags 的真实书写形式为 `ceph.` 前缀,例如 `ceph.osd_id=0`、`ceph.cluster_fsid=...`、`ceph.data_device=...`、`ceph.data_uuid=...`、`ceph.journal_device=...`、`ceph.journal_uuid=...`、`ceph.osd_fsid=...`、`ceph.type=data`。即 `osd_id` 在可读报告里显示为 `osd id`,实际 tag 名是 `ceph.osd_id`。(依据:`lvm/list.rst` 的 json 输出样例与 note。) #### 2.2.11 prepare 流程小结(bluestore) 1. 接受原始物理设备、物理设备上的分区或 logical volume 作为参数。 2. 在任何原始物理设备上创建 logical volume。 3. 为 OSD 生成一个 UUID。 4. 用生成的 UUID 向 monitor 申请一个 OSD ID。 5. 在 tmpfs 挂载上创建 OSD 数据目录。 6. `block`、`block.wal`、`block.db` 若已定义则建立符号链接。 7. 抓取 monmap 以备激活。 8. 由 `ceph-osd` 填充数据目录。 9. 用 lvm tags 给 Logical Volume 打上全部 Ceph 元数据。 > 引自:[prepare](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/prepare/) --- ### 2.3 `activate`:参数逐项说明 `prepare` 跑完后,卷就可以被激活了。激活包括启用一个 systemd unit,该 unit 会持久化 `OSD ID` 与其 `UUID`(也就是 Ceph CLI 工具里的 `fsid`)。这些信息持久化后,集群就能判断哪个 OSD 被启用、必须被挂载。 > ⚠️ 注意:该调用**完全幂等**(fully idempotent)——可以重复执行,不会改变首次成功执行的结果。 > ⚠️ 注意:由 cephadm 部署的 OSD,请参考 cephadm 的 OSD activate 文档,而不是直接用本子命令。 #### 2.3.1 参数表 | 参数 / 位置参数 | 默认值 | 含义 | 示例 | |---------------|--------|------|------| | ``(位置参数) | 无 | 要激活的 OSD ID | `0` | | ``(位置参数) | 无 | 要激活的 OSD UUID(fsid) | `0263644D-0BF1-4D6D-BC34-28BD98AE3BC8` | | `--all` | 关闭 | 一次性激活所有已存在(由 ceph-volume 创建但处于 inactive)的 OSD。已运行的会被报告出来并跳过,因此可安全重跑(幂等) | `ceph-volume lvm activate --all` | | `--bluestore` | 文档未明确(示例中使用) | 指定后端为 bluestore | `ceph-volume lvm activate --bluestore 0 0263644D-...` | | `--dmcrypt` | **不可用** | `activate` 子命令**没有**这个 flag。若 OSD 由 ceph-volume 以 dmcrypt 方式 prepare,激活时无需再次指定,加密 OSD 会被**自动检测** | — | #### 2.3.2 命令示例 ```bash # 激活新准备的 OSD(需同时给出 OSD id 与 OSD uuid) ceph-volume lvm activate --bluestore 0 0263644D-0BF1-4D6D-BC34-28BD98AE3BC8 # 激活全部 ceph-volume lvm activate --all ``` UUID 存放在 OSD 路径下的 `fsid` 文件中,该文件在 `prepare` 时生成。 #### 2.3.3 为什么必须提供 UUID 要求提供 **OSD uuid** 是一道额外的保险,用来确保激活的是正确的 OSD:完全有可能存在一个 ID 相同的旧 OSD,如果只按 ID 匹配就会激活到错误的那个。 #### 2.3.4 Discovery(发现)机制 对于此前由 `ceph-volume` 创建的 OSD,会借助 **LVM tags** 执行一个 discovery 过程来启用 systemd unit。systemd unit 会捕获 OSD id 与 OSD uuid 并持久化,内部会这样 enable: ```bash systemctl enable ceph-volume@lvm-$id-$uuid ``` 例如: ```bash systemctl enable ceph-volume@lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 ``` 该 unit 会寻找匹配的 OSD 设备,查看其 LVM tags,然后: 1. 把设备挂载到约定位置 `/var/lib/ceph/osd/-/` 2. 确保该 OSD 所需的所有设备都就绪 3. 启动 `ceph-osd@0` systemd unit > 注意:系统通过检查施加在 OSD 设备上的 LVM tags 来推断 objectstore 类型(无需显式指定)。 #### 2.3.5 既有 OSD 对于此前用 `ceph-disk` 部署的既有 OSD,需要用 `simple` 子命令做 scan 并 activate。如果当初用的是别的工具,那么移植到新机制的唯一办法就是**重新 prepare(会丢数据)**。 #### 2.3.6 activate 流程小结(bluestore) 1. 需要 OSD id 与 OSD uuid 两者。 2. 用匹配的 id 与 uuid 启用 systemd unit。 3. 在 `/var/lib/ceph/osd/$cluster-$id/` 创建 `tmpfs` 挂载。 4. 用 `ceph-bluestore-tool prime-osd-dir` 指向 OSD 的 `block` 设备,重建所有需要的文件。 5. systemd unit 确保所有设备就绪并已链接。 6. 启动对应的 `ceph-osd` systemd unit。 > 引自:[activate](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/activate/) --- ### 2.4 `create` `create` 把「provision 一个新 OSD」的两步过程(先 `prepare` 再 `activate`)包装成**一步**。 - 与两步完全相同的流程,**唯一区别是 OSD 会在命令完成后立刻 up and in**。 - 支持的后端 flag:`--bluestore`。 - **所有命令行 flags 与 options 均与 `ceph-volume lvm prepare` 相同**,参数请参照 2.2 的 prepare 参数表(含 `--data`、`--block.db`、`--block.wal`、`--journal`、`--dmcrypt`、`--with-tpm`、`--osd-id`、`--osd-fsid`、`--crush-device-class`、`--filestore`)。 > 💡 补充:因为 `create` 与 `prepare` 参数完全一致,本册不再重复列一遍表格;实际使用时把 `ceph-volume lvm prepare` 换成 `ceph-volume lvm create` 即可,例如 `ceph-volume lvm create --bluestore --data /dev/sdb`。 > 引自:[create](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/create/) --- ### 2.5 `batch`:批量部署 `batch` 允许给定一组设备输入,**同时创建多个 OSD**。它与 drive-groups 紧密相关:**一个单独的 drive group 规格会翻译成一次 `batch` 调用**。 `batch` 基于 `ceph-volume lvm create`,走**完全相同的代码路径**。`batch` 额外做的只有两件事: 1. 计算所有卷的合适大小(sizing) 2. 跳过已经创建过的卷 `ceph-volume lvm create` 支持的**所有特性**,`batch` 都支持,包括:`dmcrypt`、避免 systemd unit 被启动、定义 bluestore。 #### 2.5.1 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | ``(位置参数) | 无 | 作为 data device 的设备列表 | `/dev/sdb /dev/sdc /dev/sdd` | | `--db-devices` | 无 | 显式指定用于 `block.db` 的设备列表 | `--db-devices /dev/nvme0n1` | | `--auto` | 见下方「自动排序」 | 显式启用设备的自动排序(按 rotational 属性) | `--auto` | | `--no-auto` | 见下方「自动排序」 | 无论旋转盘还是固态盘,所有设备都用作独立 OSD | `--no-auto` | | `--block-db-slots` | 文档未明确 | **隐式 sizing 提示**:告诉 ceph-volume 应有多少个 data device 的外部卷(db)落在给定的快速设备上 | `--block-db-slots 5` | | `--block-wal-slots` | 文档未明确 | 同上,针对 wal | `--block-wal-slots 5` | | `--journal-slots` | 文档未明确 | 同上,针对 journal(filestore) | `--journal-slots 5` | | `--block-db-size` | 无 | **显式 sizing**:指定 db 卷大小 | `--block-db-size 60G`(格式文档未明确) | | `--block-wal-size` | 无 | 显式 sizing:指定 wal 卷大小 | `--block-wal-size 10G`(格式文档未明确) | | `--journal-size` | 无 | 显式 sizing:指定 journal 大小 | `--journal-size 10G`(格式文档未明确) | | `--report` | 关闭 | 只打印计算出的 OSD 布局报告,然后**退出**,不实际部署。适合多次试跑 | `ceph-volume lvm batch --report /dev/sdb ...` | | `--yes` | 关闭 | 覆盖默认行为(打印报告并等待用户确认),直接部署 | `--yes` | | `--format` | 文档未明确(有 `pretty` 默认报告形态) | 报告格式,支持 `json` 与 `json-pretty` | `--format json-pretty` | | `--dmcrypt` | 关闭 | 批量部署加密 OSD(`batch` 支持 `create` 的全部特性,含 dmcrypt) | `--dmcrypt` | | `--bluestore` | 文档未明确是否可显式传 | 定义 bluestore(文档表述为「defining bluestore」被支持) | `--bluestore` | > ⚠️ 关于 `--no-systemd`:`batch.rst` 只写了「avoiding ``systemd`` units from starting」这一**特性**被支持,**没有给出该 flag 的字面名称**。因此 `--no-systemd` 这个具体参数名在本册涵盖的 rst 源文中**未明确出现**。其存在性与拼写请以 `ceph-volume lvm batch --help` 为准。 > ⚠️ 关于 `--wal-devices` / `--journal-devices`:`batch.rst` 只出现了 `--db-devices`。是否存在同族的 `--wal-devices` 参数,**文档未明确**。 #### 2.5.2 自动排序规则(Automatic sorting of disks) 如果 `batch` 只收到一个 data device 列表而**没有其他相关选项**传入,`ceph-volume` 会按设备的 **rotational 属性**自动排序,并根据所用 objectstore,把非旋转盘(SSD/NVMe)用作 `block.db` 或 `journal`。 若要让所有设备都用作独立 OSD(无论旋转盘还是固态盘),传 `--no-auto`。 以 bluestore 且未传 `--no-auto` 为例,**已被废弃的旧行为**会根据传入设备产生如下部署: | 传入设备情况 | 旧(deprecated)默认行为 | |-------------|------------------------| | 全是旋转 HDD | 每个设备创建 1 个 OSD | | 全是 SSD | 每个设备创建 2 个 OSD | | HDD 与 SSD 混合 | data 放在旋转设备上,`block.db` 建在 SSD 上,且**尽可能大** | > ⚠️ 重要变更:这个默认的自动排序行为**现在已被 DEPRECATED,未来版本会改变**。取而代之的是:**除非显式传入 `--auto` 选项,否则设备不会被自动排序**。 > > ✅ 官方建议:**使用显式的 `block.db`、`block.wal` 和 `journal` 设备列表**。 > ⚠️ 限制:虽然 `ceph-volume lvm create` 允许使用 `block.wal`,但 **`auto` 行为不支持 `block.wal`**。 #### 2.5.3 Reporting(报告 / 预演) 默认情况下 `batch` 会**打印计算出的 OSD 布局报告并要求用户确认**。可用 `--yes` 覆盖(跳过确认直接部署)。 如果想试跑多次而不被反复询问是否部署,可传 `--report`——`ceph-volume` 打印完报告就退出。 ```bash ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 ``` 上例会在一块 NVMe 设备上部署三个带外部 `db` 与 `wal` 卷的 OSD。 **pretty 报告示例(默认格式):** ```text $ ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 --> passed data devices: 3 physical, 0 LVM --> relative data size: 1.0 --> passed block_db devices: 1 physical, 0 LVM Total OSDs: 3 Type Path LV Size % of device ---------------------------------------------------------------------------------------------------- data /dev/sdb 300.00 GB 100.00% block_db /dev/nvme0n1 66.67 GB 33.33% ---------------------------------------------------------------------------------------------------- data /dev/sdc 300.00 GB 100.00% block_db /dev/nvme0n1 66.67 GB 33.33% ---------------------------------------------------------------------------------------------------- data /dev/sdd 300.00 GB 100.00% block_db /dev/nvme0n1 66.67 GB 33.33% ``` **报告字段解读:** | 字段 | 含义 | |------|------| | `passed data devices: N physical, M LVM` | 传入的 data device 中,N 个是物理设备、M 个是 LVM 卷 | | `relative data size` | 相对数据大小系数(示例为 `1.0`)。文档未给出进一步定义 | | `passed block_db devices: N physical, M LVM` | 传入的 db device 中物理/LVM 各多少 | | `Total OSDs` | 本次将创建的 OSD 总数 | | `Type` | `data` / `block_db` / `block_wal` / `journal` | | `Path` | 设备路径 | | `LV Size` | 计算出的 logical volume 大小 | | `% of device` | 占用该设备的百分比 | **JSON 报告:** ```bash ceph-volume lvm batch --report --format json-pretty /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 ``` ```text --> passed data devices: 3 physical, 0 LVM --> relative data size: 1.0 --> passed block_db devices: 1 physical, 0 LVM [ { "block_db": "/dev/nvme0n1", "block_db_size": "66.67 GB", "data": "/dev/sdb", "data_size": "300.00 GB", "encryption": "None" }, { "block_db": "/dev/nvme0n1", "block_db_size": "66.67 GB", "data": "/dev/sdc", "data_size": "300.00 GB", "encryption": "None" }, { "block_db": "/dev/nvme0n1", "block_db_size": "66.67 GB", "data": "/dev/sdd", "data_size": "300.00 GB", "encryption": "None" } ] ``` #### 2.5.4 Sizing(容量规划) 不传任何 sizing 参数时,`ceph-volume` 会从传入的设备列表(或自动排序后的列表)**推导**出大小;`ceph-volume batch` 会尝试**充分利用设备的可用容量**。官方建议:**依赖自动 sizing**。 如果确实需要不同的 wal/db/journal 容量策略,`ceph-volume` 提供**隐式**与**显式**两类 sizing 规则。 | 类别 | 参数 | 用法 | |------|------|------| | 隐式 sizing | `--block-db-slots` / `--block-wal-slots` / `--journal-slots` | 在「设备未足额配置」或「部分 data device 暂不可用(如坏盘待换)」的场景下,给 ceph-volume 一个**提示**:应有多少个 data device 的外部卷落在这批快速设备上。省去手工计算显式大小。 | | 显式 sizing | `--block-db-size` / `--block-wal-size` / `--journal-size` | 直接给定大小。`ceph-volume` 会尝试在给定磁盘前提下满足这些大小请求;**若无法满足,则不会部署任何 OSD**。 | 隐式 sizing 示例:一台 OSD 主机规划 5 块 data device + 1 块 wal/db 设备,但其中一块 data device 当前损坏待更换。此时不必计算 wal/db 的显式大小,只需: ```bash ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd /dev/sde --db-devices /dev/nvme0n1 --block-db-slots 5 ``` #### 2.5.5 幂等性与换盘(Idempotency and disk replacements) `ceph-volume lvm batch` **意图做到幂等**:重复调用同一条命令必须得到相同结果。 ```bash ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 ``` - 第一次调用(所有盘可用)会得到三个已部署的 OSD。 - 再次调用同一命令:**仍然只有三个 OSD**,`ceph-volume` 以返回码 0 退出。 **换盘场景:** 假设 `/dev/sdc` 坏了需要更换。销毁该 OSD 并更换硬件后,**再次调用同一条命令**,`ceph-volume` 会检测到三个期望 OSD 中只有两个已就位,于是**重新创建缺失的那个 OSD**。 > 💡 补充:这个幂等性与 drivegroups 紧密耦合、并被 drivegroups 大量使用——这正是「同一份 drive group spec 反复 apply 不会重复建 OSD、换盘后能自动补齐」的底层依据。 > 引自:[batch](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/batch/) --- ### 2.6 `list`:设备与 OSD 关联报告 `list` 会列出**任何可能与 Ceph 集群关联的设备(logical 与 physical)**,前提是它们带有足够的可发现元数据。 - 输出按设备关联的 **OSD ID** 分组。 - 与 `ceph-disk` 不同,它**不会**输出任何与 Ceph 无关的设备信息。 #### 2.6.1 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | `--format` | `pretty` | 允许 `json` 或 `pretty`。`pretty` 以人类可读格式分组展示设备信息 | `ceph-volume lvm list --format=json` | | ``(位置参数) | 无(不给则为完整报告) | 单个报告:可为设备全路径,或 `vg/lv` 形式的 logical volume | `ceph-volume lvm list test_group/data-lv2`、`ceph-volume lvm list /dev/sdd1` | #### 2.6.2 Full Reporting(完整报告) 不使用位置参数时给出完整报告,即展示系统中发现的**所有**设备和 logical volume。 两个 OSD(一个用 lv 作 journal,另一个用物理设备)的 `pretty` 完整报告示例: ```bash ceph-volume lvm list ``` ```text ====== osd.1 ======= [journal] /dev/journals/journal1 journal uuid C65n7d-B1gy-cqX3-vZKY-ZoE0-IEYM-HnIJzs osd id 1 cluster fsid ce454d91-d748-4751-a318-ff7f7aa18ffd type journal osd fsid 661b24f8-e062-482b-8110-826ffe7f13fa data uuid SlEgHe-jX1H-QBQk-Sce0-RUls-8KlY-g8HgcZ journal device /dev/journals/journal1 data device /dev/test_group/data-lv2 devices /dev/sda [data] /dev/test_group/data-lv2 journal uuid C65n7d-B1gy-cqX3-vZKY-ZoE0-IEYM-HnIJzs osd id 1 cluster fsid ce454d91-d748-4751-a318-ff7f7aa18ffd type data osd fsid 661b24f8-e062-482b-8110-826ffe7f13fa data uuid SlEgHe-jX1H-QBQk-Sce0-RUls-8KlY-g8HgcZ journal device /dev/journals/journal1 data device /dev/test_group/data-lv2 devices /dev/sdb ====== osd.0 ======= [data] /dev/test_group/data-lv1 journal uuid cd72bd28-002a-48da-bdf6-d5b993e84f3f osd id 0 cluster fsid ce454d91-d748-4751-a318-ff7f7aa18ffd type data osd fsid 943949f0-ce37-47ca-a33c-3413d46ee9ec data uuid TUpfel-Q5ZT-eFph-bdGW-SiNW-l0ag-f5kh00 journal device /dev/sdd1 data device /dev/test_group/data-lv1 devices /dev/sdc [journal] /dev/sdd1 PARTUUID cd72bd28-002a-48da-bdf6-d5b993e84f3f ``` #### 2.6.3 输出字段解读 | 字段 | 含义 | |------|------| | `====== osd.N =======` | 分组标题,按 OSD ID | | `[journal]` / `[data]` | 该设备在此 OSD 中扮演的角色(type) | | `journal uuid` | journal 卷/分区的 UUID(LV 为 lv_uuid,分区为 PARTUUID) | | `osd id` | OSD ID(实际 tag 为 `ceph.osd_id`) | | `cluster fsid` | 集群 FSID(tag `ceph.cluster_fsid`) | | `type` | `data` / `journal` / `block` / `db` / `wal` 等(tag `ceph.type`) | | `osd fsid` | OSD FSID(tag `ceph.osd_fsid`) | | `data uuid` | 数据卷 UUID(tag `ceph.data_uuid`) | | `journal device` | journal 设备路径(tag `ceph.journal_device`) | | `data device` | 数据设备路径(tag `ceph.data_device`) | | `devices` | 与该 logical volume 关联的**物理设备**。因为 LVM 允许多个物理设备组成一个 LV,`pretty` 下该值为**逗号分隔**,而 `json` 下是**数组** | | `PARTUUID` | 当对象是物理分区时列出其 PARTUUID | #### 2.6.4 Single Reporting(单个报告) 单个报告既能接受设备也能接受 logical volume 作为位置参数。**对 logical volume,必须同时使用卷组名和逻辑卷名**(即 `vg/lv`)。 ```bash ceph-volume lvm list test_group/data-lv2 ``` ```text ====== osd.1 ======= [data] /dev/test_group/data-lv2 journal uuid C65n7d-B1gy-cqX3-vZKY-ZoE0-IEYM-HnIJzs osd id 1 cluster fsid ce454d91-d748-4751-a318-ff7f7aa18ffd type data osd fsid 661b24f8-e062-482b-8110-826ffe7f13fa data uuid SlEgHe-jX1H-QBQk-Sce0-RUls-8KlY-g8HgcZ journal device /dev/journals/journal1 data device /dev/test_group/data-lv2 devices /dev/sdc ``` 对普通磁盘,需要设备完整路径: ```bash ceph-volume lvm list /dev/sdd1 ``` ```text ====== osd.0 ======= [journal] /dev/sdd1 PARTUUID cd72bd28-002a-48da-bdf6-d5b993e84f3f ``` #### 2.6.5 json 输出 所有 `--format=json` 的输出会展示系统为这些设备存储的**全部**元数据,**包括 tags**。json 报告**不做任何可读性加工**,信息原样呈现。完整报告和单设备报告都支持。 ```bash ceph-volume lvm list --format=json test_group/data-lv1 ``` ```json { "0": [ { "devices": ["/dev/sda"], "lv_name": "data-lv1", "lv_path": "/dev/test_group/data-lv1", "lv_tags": "ceph.cluster_fsid=ce454d91-d748-4751-a318-ff7f7aa18ffd,ceph.data_device=/dev/test_group/data-lv1,ceph.data_uuid=TUpfel-Q5ZT-eFph-bdGW-SiNW-l0ag-f5kh00,ceph.journal_device=/dev/sdd1,ceph.journal_uuid=cd72bd28-002a-48da-bdf6-d5b993e84f3f,ceph.osd_fsid=943949f0-ce37-47ca-a33c-3413d46ee9ec,ceph.osd_id=0,ceph.type=data", "lv_uuid": "TUpfel-Q5ZT-eFph-bdGW-SiNW-l0ag-f5kh00", "name": "data-lv1", "path": "/dev/test_group/data-lv1", "tags": { "ceph.cluster_fsid": "ce454d91-d748-4751-a318-ff7f7aa18ffd", "ceph.data_device": "/dev/test_group/data-lv1", "ceph.data_uuid": "TUpfel-Q5ZT-eFph-bdGW-SiNW-l0ag-f5kh00", "ceph.journal_device": "/dev/sdd1", "ceph.journal_uuid": "cd72bd28-002a-48da-bdf6-d5b993e84f3f", "ceph.osd_fsid": "943949f0-ce37-47ca-a33c-3413d46ee9ec", "ceph.osd_id": "0", "ceph.type": "data" }, "type": "data", "vg_name": "test_group" } ] } ``` #### 2.6.6 Synchronized information(信息同步 / 设备改名自愈) 在任何 listing 之前,会先查询 lvm API,以确认在用的物理设备**没有发生改名**——像 `/dev/sda1` 这类非持久化命名完全可能变成 `/dev/sdb1`。 之所以能检测到,是因为 `PARTUUID` 作为元数据的一部分被存放在 data lv 中;**即使 journal 是物理设备,该信息也仍存放在与之关联的 data logical volume 上**。 若(用 `PARTUUID` 询问 `blkid` 得到的)名字已不再相同,tag 会被更新,报告会使用刷新后的新信息。 > 💡 补充:这条机制解释了为什么 `ceph-volume` 比 `ceph-disk` 更抗设备改名——元数据锚点是 PARTUUID / lv_uuid,而不是 `/dev/sdX` 这种不稳定的内核命名。 > 引自:[list](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/list/) --- ### 2.7 `zap`:擦除设备以复用 `zap` 用来擦除**已被 Ceph OSD 使用过的** lvs、分区或裸设备,使它们可以被重新使用。 - 如果给的是 logical volume 路径,**必须是 `vg/lv` 格式**。 - 给定 lv 或分区上存在的任何文件系统都会被移除,**所有数据都会被清除**。 - ⚠️ 注意:**lv 或分区本身会被保留完整(kept intact)**。 - ⚠️ 注意:如果该 logical volume、裸设备或分区正被任何 Ceph 相关的挂载点使用,它们会被**卸载**。 #### 2.7.1 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | ``(位置参数) | 无 | 要擦除的目标;可以是裸设备、分区,或 `vg/lv` 形式的 logical volume。**可同时接受多个设备** | `/dev/sdc`、`/dev/sdc1`、`osd-vg/data-lv` | | `--destroy` | 关闭 | 在擦除的同时**完全移除**该设备(lv、vg 或 partition)。当你用整块裸设备部署过 OSD、之后想复用该设备再部署另一个 OSD 时,**必须**使用此 flag,否则 ceph-volume 在该裸设备上建的 vgs 与 lvs 不会被移除 | `--destroy` | | `--osd-id` | 无 | 按 OSD ID 过滤要擦除的设备(可与 `--osd-fsid` 同时给) | `--osd-id 1` | | `--osd-fsid` | 无 | 按 OSD FSID 过滤。文档特别指出:**用 FSID 过滤更严格**,可能不会匹配到那些(可能已无效的)与某 ID 关联的其他设备 | `--osd-fsid 2E8FBE58-0328-4E3B-BFB7-3CACE4E9A6CE` | #### 2.7.2 示例 ```bash # 擦除一个 logical volume ceph-volume lvm zap {vg name/lv name} # 擦除一个分区 ceph-volume lvm zap /dev/sdc1 # 擦除裸设备并销毁其上的 vgs / lvs ceph-volume lvm zap /dev/sdc --destroy # --destroy 同样可用于分区与 logical volume ceph-volume lvm zap /dev/sdc1 --destroy ceph-volume lvm zap osd-vg/data-lv --destroy # 按 OSD ID 过滤 ceph-volume lvm zap --destroy --osd-id 1 # 按 OSD FSID 过滤 ceph-volume lvm zap --destroy --osd-fsid 2E8FBE58-0328-4E3B-BFB7-3CACE4E9A6CE # 两者同时使用 ceph-volume lvm zap --destroy --osd-fsid 2E8FBE58-0328-4E3B-BFB7-3CACE4E9A6CE --osd-id 1 ``` > ⚠️ 官方 warning:**如果检测到待 zap 的 OSD ID 所对应的 systemd unit 正在运行,工具会拒绝执行 zap,直到该守护进程被停止。** > 💡 补充:这条 warning 的实践含义是——zap 之前必须先停 OSD(例如 `systemctl stop ceph-osd@`,cephadm 部署的则用 `cephadm unit --fsid $cid --name osd. stop`),否则命令会被拒绝。 > 引自:[zap](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/zap/) --- ### 2.8 `migrate`:把 BlueFS 数据搬到目标卷 `migrate` 把 **BlueFS 数据**从源卷搬到目标卷;成功时**源卷(除主卷,即 data / block 卷之外)会被移除**。 - **Target 只允许 LVM 卷**,可以是已挂载的,也可以是新卷。 - 若是新卷,它会被挂到该 OSD 上,**替换掉某个源设备**。 #### 2.8.1 替换规则(按优先级顺序,命中即停) | 优先级 | 条件 | 结果 | |--------|------|------| | 1 | 源列表中有 **DB volume** | target 设备替换它 | | 2 | 源列表中有 **WAL volume** | target 设备替换它 | | 3 | 源列表中**只有 slow volume** | **不允许该操作**,需要先用 `new-db` / `new-wal` 显式分配 | #### 2.8.2 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | `--osd-id` | 无 | 目标 OSD 的 ID | `--osd-id 1` | | `--osd-fsid` | 无 | 目标 OSD 的 FSID(UUID) | `--osd-fsid ` | | `--from` | 无 | 源卷列表,取值 `data` / `db` / `wal`,**可给多个**(空格分隔) | `--from data db wal` | | `--target` | 无 | 目标 LVM 卷,格式 `vg/lv` | `--target vgname/new_db` | #### 2.8.3 全部官方示例(逐条对照) | # | 命令 | 效果 | |---|------|------| | 1 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data --target vgname/db` | 把 BlueFS 数据从主设备搬到**已作为 DB 挂载的 LV** | | 2 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data --target vgname/new_db` | 把 BlueFS 数据从**共享的主设备**搬到一个将作为**新 DB** 挂载的 LV | | 3 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from db --target vgname/new_db` | 把 BlueFS 数据从 DB 设备搬到新 LV,**DB 被替换** | | 4 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data db --target vgname/new_db` | 把 BlueFS 数据从主设备与 DB 设备搬到新 LV,**DB 被替换** | | 5 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data db wal --target vgname/new_db` | 从主、DB、WAL 三个设备搬到新 LV,**WAL 被移除、DB 被替换** | | 6 | `ceph-volume lvm migrate --osd-id 1 --osd-fsid --from db wal --target vgname/data` | 从主、DB、WAL 搬到**主设备**,**WAL 与 DB 都被移除** | > 引自:[migrate](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/migrate/) --- ### 2.9 `new-db` / `new-wal`:挂载新的 DB / WAL 卷 | 子命令 | 作用 | 失败条件 | |--------|------|---------| | `new-db` | 把给定的 logical volume 作为 **DB** 挂到 OSD 上 | 若该 OSD **已挂载 DB** 则失败 | | `new-wal` | 把给定的 logical volume 作为 **WAL** 挂到 OSD 上 | 若该 OSD **已挂载 DB** 则失败(源文原文如此) | 两者的 logical volume 名格式均为 **`vg/lv`**。 #### 2.9.1 参数表 | 参数 | 默认值 | 含义 | 示例 | |------|--------|------|------| | `--osd-id` | 无 | 目标 OSD 的 ID | `--osd-id 1` | | `--osd-fsid` | 无 | 目标 OSD 的 FSID(UUID) | `--osd-fsid 55BD4219-16A7-4037-BC20-0F158EFCC83D` | | `--target` | 无 | 要挂载的 logical volume,格式 `vg/lv` | `--target vgname/new_db` | #### 2.9.2 示例 ```bash # 把 vgname/lvname 作为 DB 卷挂到 OSD 1 ceph-volume lvm new-db --osd-id 1 --osd-fsid 55BD4219-16A7-4037-BC20-0F158EFCC83D --target vgname/new_db # 把 vgname/lvname 作为 WAL 卷挂到 OSD 1 ceph-volume lvm new-wal --osd-id 1 --osd-fsid 55BD4219-16A7-4037-BC20-0F158EFCC83D --target vgname/new_wal ``` #### 2.9.3 Reversing BlueFS Spillover to Slow Devices(回退 BlueFS 溢出) 在某些情形下,OSD 的 RocksDB 数据库会**溢出(spill over)到慢速存储**上,Ceph 集群会给出具体的 BlueFS spillover 警告,`ceph health detail` 会返回这些警告。示例: ```text osd.76 spilled over 128 KiB metadata from 'db' device (56 GiB used of 60 GiB) to slow device ``` 要把这部分 DB 元数据从慢设备搬回快设备,按以下步骤: 1. **扩容数据库的 logical volume(LV):** ```bash lvextend -l ${size} ${lv}/${db} ${ssd_dev} ``` 2. **停止该 OSD:** ```bash cephadm unit --fsid $cid --name osd.${osd} stop ``` 3. **执行 `bluefs-bdev-expand`:** ```bash cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-expand --path /var/lib/ceph/osd/ceph-${osd} ``` 4. **执行 `bluefs-bdev-migrate`:** ```bash cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-migrate --path /var/lib/ceph/osd/ceph-${osd} --devs-source /var/lib/ceph/osd/ceph-${osd}/block --dev-target /var/lib/ceph/osd/ceph-${osd}/block.db ``` 5. **重启该 OSD:** ```bash cephadm unit --fsid $cid --name osd.${osd} start ``` > 📌 官方 note:以上流程由 **Chris Dunlop** 在 [ceph-users] 邮件列表上提出,原始出处为 `[ceph-users] Re: Fixing BlueFS spillover (pacific 16.2.14)`。 > > 💡 补充:注意这套 spillover 修复流程用的是 `cephadm` + `ceph-bluestore-tool`,而不是 `ceph-volume lvm new-db`——它属于「就地扩容 db LV 后让 BlueFS 认识到新容量并搬回数据」的路径,与「给 OSD 新挂一个 DB 卷」的 `new-db` 是两回事。 > 引自:[new-db](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/newdb/)、[new-wal](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/newwal/) --- ### 2.10 `scan`(lvm):尚未实现 `lvm/scan.rst` 全文极短:该子命令本意是「通过查看系统的 logical volumes 及其 tags 来发现此前由本工具配置过的 Ceph 卷」。作为 `prepare` 过程的一部分,logical volume 会被打上若干带重要信息的 tags。 > ⚠️ **官方 note:This sub-command is not yet implemented(该子命令尚未实现)。** 在 `lvm/index.rst` 中,`scan` 也确实出现在被注释掉的 `.. not yet implemented` 列表里。 > 💡 补充:因此不要指望用 `ceph-volume lvm scan` 做发现;当前可用的「发现/查看」手段是 `ceph-volume lvm list`(2.6)与 `ceph-volume inventory`(第五章)。 > 引自:[scan](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/scan/) --- ### 2.11 加密(Encryption) Logical volume 可以通过在创建 OSD 时指定 **`--dmcrypt`** flag 来使用 **dmcrypt** 加密。用 LVM 时,logical volume 有多种加密方式;`ceph-volume` 提供的选项没有 LVM 那么多,但它以一种**一致且健壮(consistent and robust)**的方式加密 logical volume。 `ceph-volume lvm` 遵循的约束: - **非 LVM 设备(例如分区)使用与 OSD 相同的 key 加密。** #### 2.11.1 LUKS 版本 LUKS 目前有两个版本,1 和 2。版本 2 实现起来稍容易一些,但**并非 Ceph 支持的所有 Linux 发行版都广泛提供**。 | 文档中的称呼 | 实际版本 | |-------------|---------| | "LUKS" | LUKS 版本 1 | | "LUKS2" | LUKS 版本 2 | #### 2.11.2 LUKS on LVM(在 LV 之上加密) 加密是在**已有 logical volume 之上**进行的(这与「加密物理设备」不是一回事)。任何单个 logical volume 都可以被加密,其他卷保持不加密。这种方式也允许灵活的 LV 布局,因为**加密发生在 LV 创建之后**。 #### 2.11.3 密钥管理与工作流 搭建 OSD 时会创建一个 secret key。该 secret key 以 **JSON 格式通过 `stdin` 传给 monitor**,以防止 key 被日志记录捕获。 JSON payload 形如: ```json { "cephx_secret": CEPHX_SECRET, "dmcrypt_key": DMCRYPT_KEY, "cephx_lockbox_secret": LOCKBOX_SECRET, } ``` **三个 key 的命名约定是严格(strict)的**,之所以叫这些名字,是为了沿用 `ceph-disk` 使用的**硬编码(legacy)名称**: | key 名 | 含义 | |--------|------| | `cephx_secret` | 用于认证的 cephx key | | `dmcrypt_key` | 用于解锁加密设备的 secret(private)key | | `cephx_lockbox_secret` | 用于取回 `dmcrypt_key` 的认证 key。之所以叫 *lockbox*,是因为 `ceph-disk` 过去有一个同名的**未加密分区**,用来存放公钥和其他 OSD 元数据 | 命名约定之所以严格,是因为 Monitor 支持 `ceph-disk` 的这套命名。为了保持兼容、避免破坏 `ceph-disk`,`ceph-volume` **沿用了同样的命名约定——尽管它对新加密工作流而言并没有意义**。 #### 2.11.4 加解密的时机 - 在 **prepare 阶段**(bluestore)完成 OSD 搭建的公共步骤之后,logical volume 就处于「随时可激活」的状态,**与设备当前是加密还是解密状态无关**。 - 到**激活时**,logical volume 才被解密。解密过程正确完成后 OSD 才启动。 #### 2.11.5 新建加密 OSD 的加密流程小结 1. OSD 被创建。**lockbox 与 dmcrypt 两个 key 都被创建**,并以 JSON 格式发送给 monitors,以此表明这是一个加密 OSD。 2. 所有配套设备(如 journal、db、wal)被创建,并**用同一个 OSD key 加密**。Key 存储在 OSD 的 **LVM 元数据**中。 3. 激活流程继续:确保设备被挂载、**从 monitors 取回 dmcrypt secret key**、在 OSD 启动前完成解密。 #### 2.11.6 加密相关命令回顾 ```bash # 准备时启用加密(--dmcrypt 必需) ceph-volume lvm prepare --bluestore --dmcrypt --data vg/lv # Squid 起:为 LUKS2 设备启用 TPM2 token enrollment ceph-volume lvm prepare --bluestore --dmcrypt --with-tpm --data vg/lv # filestore 场景(已废弃,仅作对照) ceph-volume lvm prepare --filestore --dmcrypt --data --journal # 激活时无需再次指定 --dmcrypt:加密 OSD 会被自动检测 ceph-volume lvm activate --bluestore 0 0263644D-0BF1-4D6D-BC34-28BD98AE3BC8 ``` > 引自:[Encryption](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/encryption/) --- ### 2.12 systemd 集成 #### 2.12.1 通用约定(`ceph-volume/systemd.rst`) 作为激活流程的一部分(无论是 `lvm activate` 还是 `simple activate`),会启用若干 **systemd unit**,这些 unit 的名字中带有 **OSD id 与 uuid**。这些 unit 会在系统启动时运行,并通过各自子命令的实现去激活对应的卷。 激活的 API 比较松散,只要求两部分:要用的**子命令**,以及用短横线分隔的**额外元信息**。约定使 unit 形如: ```text ceph-volume@{command}-{extra metadata} ``` *extra metadata* 可以是实现处理的子命令所需的任何东西。对 `lvm` 与 `simple` 而言,两者都需要消费 **OSD id** 与 **OSD uuid**——但这不是硬性要求,只是这两个子命令的实现方式如此。 command 与 extra metadata 都会被 systemd 作为 unit 的**「instance name」**持久化。例如一个 ID 为 0 的 OSD,在 `lvm` 子命令下是: ```bash systemctl enable ceph-volume@lvm-0-0A3E1ED2-DA8A-4F0E-AA95-61DEC71768D6 ``` 被启用的 unit 是一个 **systemd oneshot** 服务,设计为在**本地文件系统就绪之后**、随系统启动运行。 #### 2.12.2 unit 命名规则汇总 | 后端 | unit 命名 | 启用示例 | |------|----------|---------| | 通用形式 | `ceph-volume@{command}-{extra metadata}` | — | | `lvm` | `ceph-volume@lvm-$id-$uuid` | `systemctl enable ceph-volume@lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41` | | `simple` | `ceph-volume@simple-$id-$uuid` | `systemctl enable ceph-volume@simple-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41` | #### 2.12.3 失败与重试(Failure and Retries) 系统上线时失败很常见——设备有时尚未完全可用,这种不可预测的行为可能导致某个 OSD 没能就绪。 有两个可配置的环境变量用于设置重试行为: | 环境变量 | 默认值 | 含义 | |---------|-------|------| | `CEPH_VOLUME_SYSTEMD_TRIES` | **30** | *"tries"*:unit 在放弃之前尝试激活某个 OSD 的**最大次数** | | `CEPH_VOLUME_SYSTEMD_INTERVAL` | **5** | *"interval"*:发起下一次激活尝试前的**等待秒数** | #### 2.12.4 lvm 侧的 systemd 流程(`lvm/systemd.rst`) 启动时,它会用 **LVM tags** 识别 logical volume,找到匹配的 ID,再用 **OSD uuid** 确认找对了。 识别到正确的卷之后,按 OSD 目标约定挂载: ```text /var/lib/ceph/osd/- ``` 对我们的示例(OSD id 为 `0`),即挂载到: ```text /var/lib/ceph/osd/ceph-0 ``` 该过程完成后,调用启动 OSD: ```bash systemctl start ceph-osd@0 ``` 这一 systemd 部分由 **`ceph-volume lvm trigger`** 子命令处理,它只负责解析来自 systemd 与启动过程的元数据,然后分发给 `ceph-volume lvm activate` 去完成激活。 #### 2.12.5 启停操作速查 ```bash # 启用(开机自启)——lvm systemctl enable ceph-volume@lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 # 启用——simple systemctl enable ceph-volume@simple-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 # 启动 OSD 本体 systemctl start ceph-osd@0 # 停止 OSD 本体(zap 前需要) systemctl stop ceph-osd@0 ``` > 💡 补充:文档只给出了 `enable` 与 `start` 的示例,没有给出 `disable`/`stop` `ceph-volume@` 这一 oneshot unit 的示例;`systemctl stop ceph-osd@0` 是根据 zap 前「必须停止守护进程」的要求推导出的常规做法。cephadm 部署的集群请用 `cephadm unit --fsid $cid --name osd. stop/start`。 > 引自:[systemd](https://docs.ceph.com/en/tentacle/ceph-volume/systemd/)、[systemd(lvm)](https://docs.ceph.com/en/tentacle/ceph-volume/lvm/systemd/) --- ## 三、simple 后端(接管遗留 ceph-disk OSD) `simple` 子命令实现了从 `simple` 子命令管理 OSD 所需的功能:`ceph-volume simple`。 **用户可见子命令:** `scan`、`activate`、`systemd`。 **「接管(taking over)」管理的含义:** 它禁用所有 `ceph-disk` 用来在启动时触发设备的 systemd unit,转而依赖**基础(可定制的)JSON 配置**与 systemd 来启动 OSD。 **两步流程:** 1. `scan` 运行中的 OSD 或 data device 2. `activate` 已被扫描的 OSD 扫描会推断出 `ceph-volume` 启动该 OSD 所需的**一切**信息,这样在需要激活时,OSD 可以正常启动,而不会受到 `ceph-disk` 的干扰。 作为激活流程的一部分,负责响应 udev 事件的 `ceph-disk` systemd unit 会被**链接到 `/dev/null`**,从而彻底失效。 ### 3.1 `scan`(simple) 扫描可以捕获一个**已部署 OSD** 的重要细节,使 `ceph-volume` 能在**不需要任何其他启动工作流或工具(如 udev 或 ceph-disk)**的情况下管理它。**LUKS 或 PLAIN 格式的加密完全支持。** 该命令可以: - 通过检查存放 OSD 数据的目录来检视一个运行中的 OSD; - 或消费 data partition 来检视; - 或者,如果不提供任何路径或设备,则**扫描所有运行中的 OSD**。 扫描后,信息(默认)会作为 JSON **持久化到 `/etc/ceph/osd` 下的一个文件中**。JSON 文件命名约定为 `{OSD ID}-{OSD FSID}.json`。例如 id 为 1、FSID 为 `86ebd829-1405-43d3-8fd6-4cbc9b6ecf96` 的 OSD,绝对路径为: ```text /etc/ceph/osd/1-86ebd829-1405-43d3-8fd6-4cbc9b6ecf96.json ``` #### 3.1.1 参数表 | 参数 / 位置参数 | 默认值 | 含义 | 示例 | |---------------|--------|------|------| | ``(位置参数) | 无(不给则扫描所有运行中的 OSD) | OSD 目录路径,或 OSD 的 data partition 设备(**必须是 data partition**) | `/var/lib/ceph/osd/ceph1`、`/dev/sda1` | | `--force` | 关闭 | `scan` 子命令在该文件已存在时**拒绝写入**;如需覆盖内容,必须使用此 flag | `ceph-volume simple scan --force {path}` | | `--stdout` | 关闭 | 无需持久化 JSON 元数据时,把内容发到 `stdout`(**不会写文件**) | `ceph-volume simple scan --stdout {path}` | #### 3.1.2 Running OSDs scan(扫描运行中的 OSD) 不带 OSD 目录或设备参数使用该命令,会扫描**当前正在运行的** OSD 的目录。**如果某个运行中的 OSD 不是由 ceph-disk 创建的,它会被忽略、不被扫描。** ```bash ceph-volume simple scan ``` #### 3.1.3 Directory scan(目录扫描) 目录扫描会从若干「有趣的文件」中捕获 OSD 文件内容。以下文件**必须存在**才能成功扫描: - `ceph_fsid` - `fsid` - `keyring` - `ready` - `type` - `whoami` 如果 OSD 是加密的,还会额外添加以下 key: - `encrypted` - `encryption_type` - `lockbox_keyring` 对于任何其他文件,**只要不是二进制文件或目录**,也会被捕获并作为 JSON 对象的一部分持久化。 JSON 对象 key 的约定:**任何文件名就是一个 key,其内容就是它的值**。 - 若内容只有一行(如 `whoami`),内容会被 trim,换行被丢弃。例如 OSD id 为 1 时:`"whoami": "1",` - 可能多行的文件内容保持原样,但 **keyring 会被特殊处理并解析以提取 keyring**。例如读到的 keyring 为: ```text [osd.1]\n\tkey = AQBBJ/dZp57NIBAAtnuQS9WOS0hnLVe0rZnE6Q==\n ``` 会被存为: ```text "keyring": "AQBBJ/dZp57NIBAAtnuQS9WOS0hnLVe0rZnE6Q==", ``` 对于 `/var/lib/ceph/osd/ceph-1` 这样的目录,命令形如: ```bash ceph-volume simple scan /var/lib/ceph/osd/ceph1 ``` #### 3.1.4 Device scan(设备扫描) 当 OSD 目录不可用时(OSD 未运行,或设备未挂载),`scan` 能够内省设备以捕获所需数据。与目录扫描一样,它仍然需要若干文件存在——这意味着**被扫描的设备必须是该 OSD 的 data partition**。 只要传入的是 OSD 的 data partition,该子命令就能扫描其内容。 - 若设备**已挂载**,工具能检测到这种情形,并从该目录捕获文件内容。 - 若设备**未挂载**,会创建一个临时目录,把设备临时挂载上仅用于扫描内容;内容扫描完成后设备会被卸载。 对于 `/dev/sda1`(**必须是 data partition**),命令形如: ```bash ceph-volume simple scan /dev/sda1 ``` #### 3.1.5 JSON 内容 JSON 对象的内容非常简单。扫描不仅会持久化来自特殊 OSD 文件及其内容的信息,还会**校验路径和设备 UUID**。 与 `ceph-disk` 把它们存放在 `{device type}_uuid` 文件里的做法不同,本工具会把它们作为 **device type key 的一部分**持久化。例如一个 `block.db` 设备: ```json "block.db": { "path": "/dev/disk/by-partuuid/6cc43680-4f6e-4feb-92ff-9c7ba204120e", "uuid": "6cc43680-4f6e-4feb-92ff-9c7ba204120e" }, ``` 但它**同时也会**持久化 `ceph-disk` 生成的特殊文件,如: ```json "block.db_uuid": "6cc43680-4f6e-4feb-92ff-9c7ba204120e", ``` 这种**重复(duplication)**的存在是为了确保三件事: 1. 支持那些可能没有 ceph-disk 特殊文件的 OSD 2. 通过查询 LVM 与 `blkid`,检查设备上**最新的**信息 3. 同时支持 logical volume 与 GPT 设备 一个使用 `bluestore` 的 OSD 的 JSON 元数据样例: ```json { "active": "ok", "block": { "path": "/dev/disk/by-partuuid/40fd0a64-caa5-43a3-9717-1836ac661a12", "uuid": "40fd0a64-caa5-43a3-9717-1836ac661a12" }, "block.db": { "path": "/dev/disk/by-partuuid/6cc43680-4f6e-4feb-92ff-9c7ba204120e", "uuid": "6cc43680-4f6e-4feb-92ff-9c7ba204120e" }, "block.db_uuid": "6cc43680-4f6e-4feb-92ff-9c7ba204120e", "block_uuid": "40fd0a64-caa5-43a3-9717-1836ac661a12", "bluefs": "1", "ceph_fsid": "c92fc9eb-0610-4363-aafc-81ddf70aaf1b", "cluster_name": "ceph", "data": { "path": "/dev/sdr1", "uuid": "86ebd829-1405-43d3-8fd6-4cbc9b6ecf96" }, "fsid": "86ebd829-1405-43d3-8fd6-4cbc9b6ecf96", "keyring": "AQBBJ/dZp57NIBAAtnuQS9WOS0hnLVe0rZnE6Q==", "kv_backend": "rocksdb", "magic": "ceph osd volume v026", "mkfs_done": "yes", "ready": "ready", "systemd": "", "type": "bluestore", "whoami": "3" } ``` ### 3.2 `activate`(simple) 一旦 `scan` 完成、某个 OSD 的全部元数据都持久化到 `/etc/ceph/osd/{id}-{uuid}.json`,该 OSD 就可以被「激活」了。 **该激活过程会通过 masking 禁用所有 `ceph-disk` systemd unit**,以防止 UDEV / ceph-disk 交互在开机时尝试启动它们。 > ⚠️ 注意:禁用 `ceph-disk` unit **只在直接调用 `ceph-volume simple activate` 时发生**;当系统启动过程中由 systemd 调用时,**不会**执行禁用动作。 激活过程需要同时使用 **OSD id** 与 **OSD uuid**。 #### 3.2.1 参数表 | 参数 / 位置参数 | 默认值 | 含义 | 示例 | |---------------|--------|------|------| | ``(位置参数) | 无 | 要激活的 OSD ID | `0` | | ``(位置参数) | 无 | 要激活的 OSD UUID | `6cc43680-4f6e-4feb-92ff-9c7ba204120e` | | `--file` | 无 | 直接指定 JSON 文件路径,替代「id + uuid」的位置参数形式 | `--file /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json` | #### 3.2.2 示例 ```bash # 用 id + uuid(工具会去找 /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json) ceph-volume simple activate 0 6cc43680-4f6e-4feb-92ff-9c7ba204120e # 直接给 JSON 文件 ceph-volume simple activate --file /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json ``` **为何必须提供 uuid:** 这是一道额外的保险,确保激活的是正确的 OSD——完全可能存在一个 ID 相同的旧 OSD,只按 ID 匹配就会激活到错误的那个。 #### 3.2.3 Discovery(发现)机制 对于此前已被 `ceph-volume` 扫描过的 OSD,会借助 **`blkid` 与 `lvm`** 执行发现过程。目前**只支持**带 GPT 分区的设备和 LVM logical volume。 - GPT 分区会有一个可被 `blkid` 查询的 `PARTUUID`; - logical volume 则会有一个可针对 `lvs`(LVM 的列出逻辑卷工具)查询的 `lv_uuid`。 该发现过程确保:即使设备被挪用到另一台系统、或其名称发生变化(如 `/dev/sda1` 这类非持久化命名),设备也能被正确检测出来。 用于映射「哪些设备属于哪个 OSD」的 JSON 配置文件,会在激活过程中协调挂载与符号链接操作。 为确保符号链接始终正确:**如果 OSD 目录中已存在符号链接,它们会被重新创建(re-done)。** systemd unit 会捕获 OSD id 与 OSD uuid 并持久化,内部会这样 enable: ```bash systemctl enable ceph-volume@simple-$id-$uuid ``` 例如: ```bash systemctl enable ceph-volume@simple-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 ``` 该 systemd 流程会调用 activate 并传入识别 OSD 及其设备所需的信息,然后: 1. 把设备挂载到约定位置 `/var/lib/ceph/osd/-/` 2. 确保该 OSD 所需的所有设备就绪且正确链接。**符号链接总是会被重新创建**,以确保链接到正确的设备。 3. 启动 `ceph-osd@0` systemd unit ### 3.3 `systemd`(simple) 启动时,它会通过加载 `/etc/ceph/osd/{id}-{uuid}.json`(对应 systemd unit 的 instance name)来识别 logical volume。 识别到正确的卷之后,按 OSD 目标约定挂载: ```text /var/lib/ceph/osd/{cluster name}-{osd id} ``` 对示例(OSD id 为 `0`),即: ```text /var/lib/ceph/osd/ceph-0 ``` 过程完成后调用启动 OSD: ```bash systemctl start ceph-osd@0 ``` 这一 systemd 部分由 **`ceph-volume simple trigger`** 子命令处理,它只负责解析来自 systemd 与启动过程的元数据,然后分发给 `ceph-volume simple activate` 去完成激活。 > 引自:[simple](https://docs.ceph.com/en/tentacle/ceph-volume/simple/)、[scan(simple)](https://docs.ceph.com/en/tentacle/ceph-volume/simple/scan/)、[activate(simple)](https://docs.ceph.com/en/tentacle/ceph-volume/simple/activate/)、[systemd(simple)](https://docs.ceph.com/en/tentacle/ceph-volume/simple/systemd/) --- ## 四、zfs 后端(仅限 FreeBSD) `zfs` 子命令实现了从 `zfs` 子命令部署 OSD 所需的功能:`ceph-volume zfs`。 > ⚠️ **现状(重要):当前实现只适用于 FreeBSD 上的 ZFS。**(`zfs/index.rst` 原文:"The current implementation only works for ZFS on FreeBSD") ### 4.1 用户可见子命令 | 子命令 | 状态 | |--------|------| | `inventory` | ✅ 可用(**仅 FreeBSD 平台**) | | `prepare` | ❌ not yet implemented(源文中被注释掉) | | `activate` | ❌ not yet implemented(源文中被注释掉) | | `create` | ❌ not yet implemented(源文中被注释掉) | | `list` | ❌ not yet implemented(源文中被注释掉) | | `scan` | ❌ not yet implemented(源文中被注释掉) | ### 4.2 `inventory`(zfs) `inventory` 子命令**通过 GEOM** 查询主机的磁盘清单,提供每个物理设备的硬件信息与元数据。 > ⚠️ **只在 FreeBSD 平台上工作。** - 默认情况下,命令返回所有物理磁盘的**简短、人类可读**报告。 - 需要程序化消费该报告时,传 **`--format json`** 生成 JSON 格式报告。该报告包含物理驱动器的丰富信息,例如磁盘元数据(如 model 和 size)、logical volumes、它们是否被 ceph 使用,以及该盘是否能被 ceph 使用、不能用的原因。 - 可以指定一个设备路径,以 plain 或 json 两种格式获取该设备的详细信息。 #### 4.2.1 参数表 | 参数 / 位置参数 | 默认值 | 含义 | 示例 | |---------------|--------|------|------| | ``(位置参数) | 无(不给则报告所有物理磁盘) | 指定设备路径,获取该设备的详细信息 | 文档未给出具体示例 | | `--format json` | 默认 plain(人类可读短报告) | 生成 JSON 格式报告,供程序化消费 | `ceph-volume zfs inventory --format json` | ### 4.3 限制小结 | 限制项 | 说明 | |--------|------| | 平台 | 仅 FreeBSD | | 发现机制 | 通过 **GEOM**(与 Linux 侧的实现路径不同) | | 可用能力 | 仅有 `inventory`,**不能部署 OSD**(prepare/activate/create/list/scan 均未实现) | > 💡 补充:从源文看,`zfs` 后端目前只具备「看盘」能力,不具备「建 OSD」能力。因此在生产 Linux 环境中它没有任何实用价值;本册范围外的 Linux 部署请一律使用 `lvm` 后端。 > 引自:[zfs](https://docs.ceph.com/en/tentacle/ceph-volume/zfs/)、[inventory(zfs)](https://docs.ceph.com/en/tentacle/ceph-volume/zfs/inventory/) --- ## 五、`inventory`:设备清单报告 `inventory` 子命令查询主机的磁盘清单(disc inventory),并提供**每个物理设备的硬件信息与元数据**。 - 默认情况下,该命令返回**所有物理磁盘的简短、人类可读报告**。 - 需要程序化消费该报告时,传 **`--format json`** 生成 JSON 格式报告。该报告包含物理驱动器的丰富信息,例如: - 磁盘元数据(如 **model** 和 **size**) - **logical volumes** - 它们**是否被 ceph 使用** - 该盘**是否能被 ceph 使用**,以及**不能用的原因** - 可以指定一个**设备路径**,以 plain 和 json 两种格式获取该设备的详细信息。 ### 5.1 参数表 | 参数 / 位置参数 | 默认值 | 含义 | 示例 | |---------------|--------|------|------| | ``(位置参数) | 无(不给则报告所有物理磁盘) | 指定设备路径,报告该设备的详细信息(plain 与 json 均支持) | 文档未给出具体示例路径 | | `--format json` | 默认 plain(简短人类可读报告) | 生成 JSON 格式报告,供程序化消费 | `ceph-volume inventory --format json` | ### 5.2 输出解读要点 | 关注点 | 说明 | |--------|------| | 设备是否被 Ceph 使用 | 报告会标明 logical volume 是否被 ceph 占用——这是判断「这块盘能不能动」的第一道依据 | | 设备是否**可用**(usable) | 报告会给出该盘能否被 ceph 使用;如果不能用,会给出**原因**。这是排查「为什么我的盘没被 drive group / batch 选中」的关键字段 | | model / size | 用于确认物理盘型号与容量,避免选错盘 | | logical volumes | 列出盘上已有的 LV 及其与 Ceph 的关系 | > 💡 补充:官方文档对 `inventory` 的描述很短,**没有给出实际的样例输出文本**,因此本册不臆造输出样例。实际字段请以 `ceph-volume inventory --format json` 的真实输出为准。它的典型用法是:在跑 `batch` / drive group 之前,先用它确认「哪些盘会被认为是 available」,避免部署时才发现设备被跳过。 > 💡 补充:`zfs` 后端也有同名的 `inventory` 子命令,但走 GEOM、仅限 FreeBSD(见第四章)。Linux 上使用的是顶层 `ceph-volume inventory`。 > 引自:[inventory](https://docs.ceph.com/en/tentacle/ceph-volume/inventory/) --- ## 六、`drive-group`:drive group spec 与 ceph-volume 的关系 `drive-group` 子命令允许把 **drivegroups 规格(specification)以 json 形式直接传给 ceph-volume**。之后 ceph-volume 会尝试**通过 `batch` 子命令**来部署这些 drive group。 ### 6.1 核心关系(一句话) > **一个 drive group 规格 → 一次 `ceph-volume lvm batch` 调用。** `batch.rst` 中的对应表述:「The `batch` subcommand is closely related to drive-groups. One individual drive group specification translates to a single `batch` invocation.」 并且,`batch` 的幂等性设计与 drivegroups **紧密耦合、并被 drivegroups 大量使用**——这就是 drive group 可以反复 apply、且换盘后能自动补齐 OSD 的底层机制。 ### 6.2 规格的传入方式 | 传入方式 | 说明 | |---------|------| | 文件 | 通过一个文件传入 spec | | 字符串参数 | 作为 string argument 传入 | | stdin | 从标准输入传入 | ### 6.3 用法 ```bash ceph-volume drive-group --help ``` > ⚠️ 注意:`drive-group.rst` 全文只有上述内容,**没有给出具体的 spec 字段定义、示例 JSON 或具体的命令行 flag 名称**,并明确写着「See the subcommand help for further details」,即让你去看 `ceph-volume drive-group --help`。 ### 6.4 与 batch 的能力对应关系 | drive group 想做的事 | 落到 ceph-volume 的什么能力 | |---------------------|---------------------------| | 按设备属性(SSD/HDD)筛选 | `batch` 的自动排序(按 rotational 属性)/ `--no-auto`、`--auto` | | 指定 db / wal 落在哪些盘 | `--db-devices` 等显式设备列表(官方推荐做法) | | 控制 db/wal 大小 | `--block-db-size` / `--block-wal-size` / `--journal-size`,或 slots 类隐式提示 | | 加密 | `--dmcrypt`(`batch` 支持 `create` 的全部特性) | | 反复 apply、换盘补齐 | `batch` 的幂等性设计 | > 💡 补充:drive group spec 本身的**字段语法**(如 `data_devices`、`db_devices`、`osds_per_device` 等)定义在 `doc/cephadm/drivegruops.rst`(属本册范围外),本册不展开;本册只覆盖它「如何落到 ceph-volume」这一层。 > 引自:[drive-group](https://docs.ceph.com/en/tentacle/ceph-volume/drive-group/) --- ## 七、常见工作流示例 > ⚠️ 以下流程中的命令均由本册覆盖的官方页面中的真实命令组合而成;凡官方文档未给出的具体取值(如路径、大小格式),均已在表格/说明中标注「文档未明确」。 ### 7.1 新增 OSD(单盘,一步到位) ```bash # 1) 先看清楚这台机器上有哪些盘、哪些可用 ceph-volume inventory # 2) 一步创建并激活(OSD 会立刻 up and in) ceph-volume lvm create --bluestore --data /dev/sdb ``` ### 7.2 新增 OSD(单盘,两步、平滑引入) ```bash # 1) 只做 prepare,此时 OSD 不会 up/in,便于控制 rebalance 节奏 ceph-volume lvm prepare --bluestore --data /dev/sdb --crush-device-class foo # 2) 确认 fsid(prepare 时生成,存放在 OSD 路径下的 fsid 文件) cat /var/lib/ceph/osd/ceph-0/fsid # 3) 激活(需 id + uuid) ceph-volume lvm activate --bluestore 0 0263644D-0BF1-4D6D-BC34-28BD98AE3BC8 ``` ### 7.3 批量新增 OSD(推荐:先预演) ```bash # 1) 预演:只打印计算出的布局,不部署 ceph-volume lvm batch --report /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 # 2) 用 JSON 预演,便于脚本化校验 ceph-volume lvm batch --report --format json-pretty /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 # 3) 确认无误后实跑(--yes 跳过确认;不加则会打印报告并等待你确认) ceph-volume lvm batch --yes /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 ``` ### 7.4 替换故障盘 ```bash # 1) 停止故障 OSD(cephadm 环境用 cephadm unit) systemctl stop ceph-osd@1 # 2) 按 OSD ID(或 FSID)擦除;裸盘必须加 --destroy 才会移除 vgs/lvs ceph-volume lvm zap --destroy --osd-id 1 # 更严格:同时给 FSID ceph-volume lvm zap --destroy --osd-fsid 2E8FBE58-0328-4E3B-BFB7-3CACE4E9A6CE --osd-id 1 # 3) 更换硬件后,重跑与当初完全相同的 batch 命令 # ceph-volume 会发现期望的 3 个 OSD 只存在 2 个,从而重建缺失的那个 ceph-volume lvm batch --yes /dev/sdb /dev/sdc /dev/sdd --db-devices /dev/nvme0n1 ``` > ⚠️ 注意:zap 时如果对应的 systemd unit 仍在运行,工具会**拒绝执行**,必须先停守护进程。 ### 7.5 迁移 db / wal ```bash # A) 把主设备上的 BlueFS 数据搬到已挂载的 DB LV ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data --target vgname/db # B) 把主设备上的 BlueFS 数据搬到一个将作为新 DB 挂载的 LV ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data --target vgname/new_db # C) 把 DB 设备上的数据搬到新 LV(DB 被替换) ceph-volume lvm migrate --osd-id 1 --osd-fsid --from db --target vgname/new_db # D) 从主 + DB 搬到新 LV(DB 被替换) ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data db --target vgname/new_db # E) 从主 + DB + WAL 搬到新 LV(WAL 被移除,DB 被替换) ceph-volume lvm migrate --osd-id 1 --osd-fsid --from data db wal --target vgname/new_db # F) 从 DB + WAL 搬回主设备(WAL 与 DB 都被移除) ceph-volume lvm migrate --osd-id 1 --osd-fsid --from db wal --target vgname/data # G) 给还没有 DB 的 OSD 新挂一个 DB / WAL 卷(若已挂 DB 会失败) ceph-volume lvm new-db --osd-id 1 --osd-fsid 55BD4219-16A7-4037-BC20-0F158EFCC83D --target vgname/new_db ceph-volume lvm new-wal --osd-id 1 --osd-fsid 55BD4219-16A7-4037-BC20-0F158EFCC83D --target vgname/new_wal ``` ### 7.6 修复 BlueFS spillover(db 溢出到慢设备) ```bash # 1) 扩容 db LV lvextend -l ${size} ${lv}/${db} ${ssd_dev} # 2) 停 OSD cephadm unit --fsid $cid --name osd.${osd} stop # 3) bluefs-bdev-expand cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-expand --path /var/lib/ceph/osd/ceph-${osd} # 4) bluefs-bdev-migrate cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-migrate --path /var/lib/ceph/osd/ceph-${osd} --devs-source /var/lib/ceph/osd/ceph-${osd}/block --dev-target /var/lib/ceph/osd/ceph-${osd}/block.db # 5) 起 OSD cephadm unit --fsid $cid --name osd.${osd} start ``` ### 7.7 擦除设备(退役 / 复用) ```bash # 只擦内容,保留 lv / 分区本身 ceph-volume lvm zap osd-vg/data-lv ceph-volume lvm zap /dev/sdc1 # 完全移除(裸盘复用必须加 --destroy) ceph-volume lvm zap /dev/sdc --destroy ceph-volume lvm zap /dev/sdc1 --destroy ceph-volume lvm zap osd-vg/data-lv --destroy # 按 OSD 过滤(可一次擦多个设备) ceph-volume lvm zap --destroy --osd-id 1 ceph-volume lvm zap --destroy --osd-fsid 2E8FBE58-0328-4E3B-BFB7-3CACE4E9A6CE ``` ### 7.8 接管遗留 ceph-disk OSD ```bash # 1) 扫描所有运行中的 ceph-disk OSD(非 ceph-disk 创建的会被忽略) ceph-volume simple scan # 或扫描指定目录 / data partition ceph-volume simple scan /var/lib/ceph/osd/ceph1 ceph-volume simple scan /dev/sda1 # 需要覆盖已有 JSON 时 ceph-volume simple scan --force /dev/sda1 # 只想看看不落盘 ceph-volume simple scan --stdout /dev/sda1 # 2) 激活(会 mask 掉所有 ceph-disk systemd unit) ceph-volume simple activate 0 6cc43680-4f6e-4feb-92ff-9c7ba204120e # 或 ceph-volume simple activate --file /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json # 3) 开机自启 systemctl enable ceph-volume@simple-0-6cc43680-4f6e-4feb-92ff-9c7ba204120e ``` ### 7.9 查看 / 巡检 ```bash # 全量 pretty 报告(按 OSD ID 分组) ceph-volume lvm list # 单个 LV(必须 vg/lv 形式) ceph-volume lvm list test_group/data-lv2 # 单个分区 ceph-volume lvm list /dev/sdd1 # JSON 全量(含原始 tags,适合脚本) ceph-volume lvm list --format=json # 设备清单(Linux) ceph-volume inventory ceph-volume inventory --format json ``` ### 7.10 创建加密 OSD ```bash # 1) 准备(--dmcrypt 必需) ceph-volume lvm prepare --bluestore --dmcrypt --data vg/lv # 1') Squid 起可启用 TPM2 token enrollment ceph-volume lvm prepare --bluestore --dmcrypt --with-tpm --data vg/lv # 2) 激活时无需再指定 --dmcrypt(没有这个 flag,加密 OSD 自动检测) ceph-volume lvm activate --bluestore 0 0263644D-0BF1-4D6D-BC34-28BD98AE3BC8 ``` ### 7.11 用分区部署(先建带 PARTUUID 的分区) ```bash parted --script /dev/sdd print parted --script /dev/sdd mklabel gpt parted --script /dev/sdd print parted --script /dev/sdd mkpart primary 1 100% blkid /dev/sdd1 # 确认输出中带 PARTUUID,例如: # /dev/sdd1: PARTLABEL="primary" PARTUUID="16399d72-1e1f-467d-96ee-6fe371a7d0d4" # 然后即可把该分区用作设备参数 ceph-volume lvm prepare --bluestore --data /dev/sdd1 ``` > 💡 补充:再次强调——`ceph-volume lvm` 本身**不会**从整块设备创建分区,分区需要你先用 `parted` / `fdisk` 建好(它们会自动写入 `PARTUUID`)。 --- ## 八、命令速查表 ### 8.1 顶层与通用 | 命令 | 用途 | |------|------| | `ceph-volume inventory` | 查询主机物理磁盘清单,输出简短人类可读报告 | | `ceph-volume inventory --format json` | 输出 JSON 报告(含 model/size、LV、是否被 ceph 使用、是否可用及原因) | | `ceph-volume inventory ` | 报告单个设备的详细信息(plain / json 均可) | | `ceph-volume drive-group --help` | 查看把 drive group spec 直接传给 ceph-volume 的用法(spec 可由文件 / 字符串 / stdin 传入) | | `ceph-volume zfs inventory` | FreeBSD 上通过 GEOM 查询磁盘清单(仅 FreeBSD) | | `ceph-volume zfs inventory --format json` | 同上,JSON 输出 | ### 8.2 lvm 后端 | 命令 | 用途 | |------|------| | `ceph-volume lvm prepare --bluestore --data vg/lv` | 在已有 LV 上打元数据(不激活、不改动卷内容) | | `ceph-volume lvm prepare --bluestore --data /path/to/device` | 传裸设备,自动创建 VG/LV 后 prepare | | `ceph-volume lvm prepare --bluestore --dmcrypt --data vg/lv` | 启用 dmcrypt 加密 | | `ceph-volume lvm prepare --bluestore --dmcrypt --with-tpm --data vg/lv` | 加密 + TPM2 token enrollment(Squid 起) | | `ceph-volume lvm prepare --bluestore --data vg/lv --crush-device-class foo` | 指定 CRUSH device class | | `ceph-volume lvm prepare --filestore --data --journal ` | filestore 后端(**Reef 起已废弃**) | | `ceph-volume lvm prepare --filestore --osd-id 0 --osd-fsid ` | 对既有 OSD 用 prepare(**会销毁数据**) | | `ceph-volume lvm activate --bluestore ` | 激活单个已 prepare 的 OSD | | `ceph-volume lvm activate --all` | 激活所有由 ceph-volume 创建但处于 inactive 的 OSD(幂等) | | `ceph-volume lvm create --bluestore --data ` | `prepare` + `activate` 一步到位,OSD 立即 up/in | | `ceph-volume lvm batch --report --db-devices ` | 预演批量部署布局,打印报告后退出 | | `ceph-volume lvm batch --report --format json-pretty ...` | 以 JSON 形式预演 | | `ceph-volume lvm batch --yes --db-devices ` | 跳过确认直接批量部署 | | `ceph-volume lvm batch ... --no-auto` | 所有设备都作独立 OSD,不做自动排序 | | `ceph-volume lvm batch ... --auto` | 显式启用按 rotational 属性的自动排序 | | `ceph-volume lvm batch ... --block-db-slots N` | 隐式 sizing:提示应有 N 个 data device 的 db 落在快速设备上 | | `ceph-volume lvm batch ... --block-wal-slots N` | 同上,针对 wal | | `ceph-volume lvm batch ... --journal-slots N` | 同上,针对 journal | | `ceph-volume lvm batch ... --block-db-size ` | 显式指定 db 卷大小(无法满足则不部署任何 OSD) | | `ceph-volume lvm batch ... --block-wal-size ` | 显式指定 wal 卷大小 | | `ceph-volume lvm batch ... --journal-size ` | 显式指定 journal 大小 | | `ceph-volume lvm list` | 列出所有与 Ceph 关联的设备/LV(按 OSD ID 分组) | | `ceph-volume lvm list /` | 列出单个 logical volume(必须带卷组名) | | `ceph-volume lvm list /dev/sdd1` | 列出单个分区 | | `ceph-volume lvm list --format=json` | JSON 输出,含原始 LVM tags | | `ceph-volume lvm zap /` | 擦除 LV 内容(保留 LV 本身) | | `ceph-volume lvm zap /dev/sdc1` | 擦除分区 | | `ceph-volume lvm zap /dev/sdc --destroy` | 擦除并移除裸设备上的 vgs/lvs | | `ceph-volume lvm zap --destroy --osd-id 1` | 按 OSD ID 过滤擦除 | | `ceph-volume lvm zap --destroy --osd-fsid ` | 按 OSD FSID 过滤擦除(更严格) | | `ceph-volume lvm migrate --osd-id N --osd-fsid --from data --target vg/lv` | 把 BlueFS 数据从主设备搬到目标 LV | | `ceph-volume lvm migrate ... --from data db wal --target vg/lv` | 多源搬迁(WAL 移除、DB 替换) | | `ceph-volume lvm migrate ... --from db wal --target vgname/data` | 搬回主设备,WAL 与 DB 均移除 | | `ceph-volume lvm new-db --osd-id N --osd-fsid --target vg/lv` | 给 OSD 新挂一个 DB 卷(已有 DB 则失败) | | `ceph-volume lvm new-wal --osd-id N --osd-fsid --target vg/lv` | 给 OSD 新挂一个 WAL 卷 | | `ceph-volume lvm scan` | 发现此前由本工具配置的 Ceph 卷 —— **尚未实现(not yet implemented)** | | `ceph-volume lvm trigger` | 内部子命令:解析 systemd 元数据并分发给 `ceph-volume lvm activate` | ### 8.3 simple 后端 | 命令 | 用途 | |------|------| | `ceph-volume simple scan` | 扫描所有运行中的 ceph-disk OSD(非 ceph-disk 创建的会被忽略) | | `ceph-volume simple scan /var/lib/ceph/osd/ceph1` | 扫描 OSD 目录 | | `ceph-volume simple scan /dev/sda1` | 扫描 OSD 的 data partition(**必须是 data partition**) | | `ceph-volume simple scan --force ` | 覆盖已存在的 JSON 元数据文件 | | `ceph-volume simple scan --stdout ` | 输出到 stdout,不写文件 | | `ceph-volume simple activate ` | 激活已扫描的 OSD(同时 mask 掉所有 ceph-disk systemd unit) | | `ceph-volume simple activate --file /etc/ceph/osd/{id}-{uuid}.json` | 直接指定 JSON 文件激活 | | `ceph-volume simple trigger` | 内部子命令:解析 systemd 元数据并分发给 `ceph-volume simple activate` | ### 8.4 systemd 相关 | 命令 | 用途 | |------|------| | `systemctl enable ceph-volume@lvm--` | 启用 lvm 后端 OSD 的开机激活 unit(oneshot,本地文件系统就绪后运行) | | `systemctl enable ceph-volume@simple--` | 启用 simple 后端 OSD 的开机激活 unit | | `systemctl start ceph-osd@` | 启动该 OSD 的守护进程 | | `systemctl stop ceph-osd@` | 停止该 OSD 守护进程(zap 前需要) | | `CEPH_VOLUME_SYSTEMD_TRIES`(环境变量) | 激活重试最大次数,默认 **30** | | `CEPH_VOLUME_SYSTEMD_INTERVAL`(环境变量) | 重试间隔秒数,默认 **5** | ### 8.5 辅助命令(文档中出现的非 ceph-volume 命令) | 命令 | 用途 | |------|------| | `ls -l /var/lib/ceph/osd/ceph-0` | 查看 OSD 目录与 block / block.db / block.wal 符号链接 | | `parted --script /dev/sdd mklabel gpt` | 给设备建 GPT label | | `parted --script /dev/sdd mkpart primary 1 100%` | 建分区(自动带 PARTUUID) | | `blkid /dev/sdd1` | 确认分区含可被发现的 PARTUUID | | `lvextend -l ${size} ${lv}/${db} ${ssd_dev}` | 扩容 db 用的 logical volume | | `cephadm unit --fsid $cid --name osd.${osd} stop` | 停止 cephadm 管理的 OSD | | `cephadm unit --fsid $cid --name osd.${osd} start` | 启动 cephadm 管理的 OSD | | `cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-expand --path /var/lib/ceph/osd/ceph-${osd}` | 让 BlueFS 认识到扩容后的新容量 | | `cephadm shell --fsid $cid --name osd.${osd} -- ceph-bluestore-tool bluefs-bdev-migrate --path ... --devs-source .../block --dev-target .../block.db` | 把数据从 slow device 搬回 db device | | `ceph health detail` | 查看 BlueFS spillover 等健康详情 | | `ln -s /path/to/journal /var/lib/ceph/osd/-/journal` | 把 journal 卷链接到已挂载的数据卷(filestore) | | `ceph --cluster ceph --name client.bootstrap-osd --keyring /var/lib/ceph/bootstrap-osd/ceph.keyring mon getmap -o /activate.monmap` | 用 bootstrap key 抓取 monmap(filestore) | | `ceph-osd --cluster ceph --mkfs --mkkey -i --monmap ... --osd-data ... --osd-journal ... --osd-uuid --keyring ... --setuser ceph --setgroup ceph` | 填充 OSD 目录(filestore) | | `ceph-bluestore-tool prime-osd-dir`(在 activate 流程中调用) | 指向 OSD block 设备,重建 OSD 目录所需文件 | --- ## 文档未明确项 以下条目在本次覆盖的 24 个 rst 源文中**没有给出明确说明**,本册不做编造,需以 `--help` 或源码/其他分册为准: | # | 未明确项 | 说明 | |---|---------|------| | 1 | `--no-systemd` 的实际参数名 | `batch.rst` 只描述了「avoiding `systemd` units from starting」这一**特性**,未给出 flag 字面名称。本册涵盖的源文中未出现 `--no-systemd` 字符串 | | 2 | `ceph-volume lvm prepare` / `create` 的**完整**参数清单 | 官方文档只在叙述中逐个提到 `--bluestore`、`--data`、`--block.db`、`--block.wal`、`--journal`、`--dmcrypt`、`--with-tpm`、`--osd-id`、`--osd-fsid`、`--crush-device-class`、`--filestore`,**没有** `--help` 式全量列表;是否还有其他参数(如 `--block-db-size` 在 create 下是否可用)未明确 | | 3 | `--block-db-size` / `--block-wal-size` / `--journal-size` 的取值格式 | 文档只说「provide explicit sizes」,未说明是 `60G`、`60GB` 还是字节数,也未给示例 | | 4 | `--block-db-slots` / `--block-wal-slots` / `--journal-slots` 的默认值 | 文档未明确 | | 5 | `--crush-device-class` 的默认值 | 文档只给了用法示例(`--crush-device-class foo`),未说明默认值(如是否自动识别 ssd/hdd) | | 6 | `batch` 的 `--format` 默认值 | 文档只说明支持 `json` 与 `json-pretty`,并提到 `pretty` 是报告的默认「pretty report format」,未以参数默认值形式明确 | | 7 | `--db-devices` 之外的同族参数 | 文档只出现 `--db-devices`;是否有 `--wal-devices`、`--journal-devices` 未明确 | | 8 | `batch` 是否支持显式 `--bluestore` | 文档只说「defining bluestore」被支持,未给出该 flag 的实际拼写与默认值 | | 9 | `ceph-volume lvm activate` 的 `--bluestore` 默认值 | 示例中使用了 `--bluestore`,但文档说 objectstore 类型由 LVM tags 推断,该 flag 是否必需未明确 | | 10 | `inventory` 的实际输出样例与字段清单 | 文档只描述了「会包含哪些类型的信息」,**没有给任何样例输出** | | 11 | `inventory ` 的示例 | 文档只说「可以指定设备路径」,未给示例 | | 12 | `zfs inventory` 的示例命令与输出 | 同上,且仅限 FreeBSD | | 13 | `drive-group` 子命令的具体 flag 与 spec 字段 | `drive-group.rst` 明确要求去看 `ceph-volume drive-group --help`;spec 字段定义在本册范围外 | | 14 | OSD data 与 journal 的**最小容量要求**数值 | `prepare.rst` 只说「be sure to meet the minimum size requirements」,未给数字 | | 15 | `ceph-volume lvm create` 的幂等性 | 文档对 `activate` 与 `batch` 明确写了幂等,对 `create` / `prepare` 未明确 | | 16 | `CEPH_VOLUME_SYSTEMD_TRIES` / `CEPH_VOLUME_SYSTEMD_INTERVAL` 的设置方式 | 文档只说明它们是「configurable environment variables」及默认值,未说明应在何处配置(systemd unit 的 `Environment=`、`/etc/environment` 等) | | 17 | `migrate` 的 `--from` 是否支持 `block` 这个别名 | 文档示例只用 `data` / `db` / `wal` | | 18 | `new-wal` 的失败条件 | `newwal.rst` 原文写「Fails if OSD has already got attached **DB**」,与直觉(应为已挂 WAL)不一致;源文如此,未作改动,是否笔误未明确 | | 19 | SPDK 后端的子命令名与可用性 | `intro.rst` 只说「on the immediate horizon」,未给子命令名,也未见对应 rst 页面 | | 20 | `ceph-volume lvm trigger` 的完整参数 | 文档只说明其职责,未给参数 | | 21 | `lvm scan` 的实现计划 | 文档仅标注 `not yet implemented`,无时间表 | | 22 | `zfs` 后端 prepare/activate/create/list/scan 的实现计划 | 源文中均被注释为 `not yet implemented`,无时间表 | | 23 | `ceph-volume` 与 cephadm 的具体调用界面 | 文档仅在 `activate.rst` 提示「For OSDs deployed by cephadm, refer to cephadm-osd-activate」,未在本册展开 | | 24 | `--with-tpm` 的前置条件(TPM2 硬件/软件栈要求、失败回退行为) | 文档只说自 Squid 起可选用,未展开 | | 25 | LUKS2 在哪些发行版可用 | 文档只说「not widely available in all Linux distributions supported by Ceph」,未列具体发行版 | | 26 | `zap` 对 `block.db` / `block.wal` 单独设备的处理 | 文档只说可按 `--osd-id` / `--osd-fsid` 过滤多个设备,未说明 db/wal 是否总被一并处理 | --- > 本册完。全部内容均整理自 Ceph Tentacle v20.2.4 官方 `doc/ceph-volume/` 下 24 个 rst 源文;凡官方未写之处,均已标注「文档未明确」,由本册作者补充的推断与提示均以「💡 补充」标出。