
Ceph 设备发现指南详解ceph-volume lvm list命令的使用、输出格式与实现原理【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/cephceph-volume lvm list是 Ceph 卷管理工具ceph-volume中用于**发现并列出与 Ceph 集群关联的所有设备逻辑卷与物理磁盘**的核心子命令。本文以 Ceph 官方文档 doc/ceph-volume/lvm/list.rst 为骨架结合仓库中 listing.py 与 lvm.py API 的源码实现完整讲解该命令的两种报告模式、pretty/json两种输出格式、LVM 标签约定与设备名同步机制帮助你快速定位 OSD 与设备之间的对应关系并在脚本化运维中正确解析输出。命令定位发现哪些设备属于 Cephceph-volume lvm list属于ceph-volume lvm子命令体系完整的子命令列表见 doc/ceph-volume/lvm/index.rst。它列出系统中可能与 Ceph 集群关联的所有设备逻辑卷和物理设备前提是这些设备携带了足够的元数据LVM 标签以供发现。与已废弃的ceph-disk不同该命令只展示与 Ceph 关联的设备凡是未被 Ceph 使用的设备一律不会出现在输出中。从源码看这一过滤逻辑位于 listing.py 的create_report方法遍历api.get_lvs()返回的每一个逻辑卷调用api.is_ceph_device(lv)判断其是否携带 Ceph 标签不满足条件的 LV 直接continue跳过。输出按OSD ID分组每个 OSD 一个 osd.N 段落这与ceph-disk按设备路径组织的输出风格截然不同便于直接回答某个 OSD 由哪些设备组成。命令行选项原文档给出的唯一命令行选项为选项说明默认值--format输出格式可选json或prettypretty人类可读的分组格式此外该命令还接受一个可选的位置参数DEVICE路径用于单设备报告见下文。这一参数定义在 listing.py 的main方法 中nargs?表示可省略帮助文本明确说明其取值可以是vg/lv形式的逻辑卷路径也可以是/dev/sda1这样的设备路径。完整报告Full Reporting一览集群全部关联设备不带任何位置参数时ceph-volume lvm list输出系统中所有与 Ceph 关联的设备与逻辑卷。执行ceph-volume lvm list两个 OSD 的pretty输出示例一个 OSD 使用 LV 作为 journal另一个使用物理设备作为 journal如下 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输出字段解读pretty模式下每个设备条目包含以下字段type设备在 OSD 中扮演的角色如data数据、journal日志结合 tag-api 文档 可知bluestore 后端还可能出现db、wal、block等类型osd id该设备所属的 OSD 编号cluster fsidCeph 集群的文件系统 IDUUIDosd fsidOSD 自身的 UUIDjournal uuid/data uuid对应逻辑卷或分区的 UUIDjournal device/data device设备路径devices组成该逻辑卷的物理设备列表。关于devices字段原文档特别指出由于 LVM 允许一个逻辑卷横跨多块物理磁盘因此在pretty模式下该值为逗号分隔的字符串而在json模式下则为数组。这一点在源码 listing.py 的pretty_report中有直接体现打印时使用,.join(device[devices])拼接而在create_report中该字段通过 lvm.py 的get_pvs遍历物理卷按pv.lv_uuid lv.lv_uuid匹配归属原样以列表存入报告。注意pretty输出中的标签名是经过可读化处理的。例如osd id在 LVM 元数据中实际以ceph.osd_id标签存储readable_tag函数将ceph.osd_id拆分为osd id。LVM 标签的完整命名约定见 LVM Tag API 文档所有标签统一使用ceph.tag nametag value的命名空间前缀。单设备报告Single Reporting按需查询指定设备单设备报告接受设备路径或逻辑卷作为位置参数三种输入形式如下1. 按逻辑卷查询必须使用卷组名/逻辑卷名逻辑卷必须同时给出卷组vg名和逻辑卷lv名ceph-volume lvm list test_group/data-lv2输出 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/sdc2. 按物理设备路径查询必须使用完整路径裸磁盘含分区必须使用完整设备路径ceph-volume lvm list /dev/sdd1输出 osd.0 [journal] /dev/sdd1 PARTUUID cd72bd28-002a-48da-bdf6-d5b993e84f3f3. 按 OSD ID 查询从源码 listing.py 的single_report可以看到参数会被按以下规则分派参数全为数字如0→ 视为 OSD ID调用 get_lvs_from_osd_id 按ceph.osd_id标签查询该 OSD 下全部 LV参数以/开头→ 视为块设备路径调用 get_lvs_from_path先按设备路径查询物理卷上关联的 LV若没有命中再退化为按 LV 的path过滤覆盖/dev/vg/lv、/dev/mapper/形式其余形式 → 按vg_name/lv_name拆解调用 get_single_lv 精确匹配匹配到多个 LV 时该方法会抛出RuntimeError以避免歧义。值得注意的边界情况当按路径查询未命中任何 Ceph LV 时single_report还会尝试把该路径当作非 LVM 的 journal/wal/db 物理设备来匹配——它会反向遍历所有 LV 的ceph.type_device标签若某标签值等于所查路径则将该 LV 关联的 OSD 与该物理设备一并报告对应源码 L169-L179 的 fallback 逻辑。这正是上文/dev/sdd1只显示PARTUUID一个字段的原因它本身不是 LVM 卷其身份信息全部保存在关联的 data LV 标签中。json 输出面向自动化与脚本解析使用--formatjson时命令会输出设备在 LVM 元数据中存储的全部信息包括原始标签且不做任何可读化改写——标签名保留ceph.osd_id等原始形式。完整报告和单设备查询都支持 json 模式。以单个逻辑卷为例ceph-volume lvm list --formatjson test_group/data-lv1{ 0: [ { devices: [/dev/sda], lv_name: data-lv1, lv_path: /dev/test_group/data-lv1, lv_tags: ceph.cluster_fsidce454d91-d748-4751-a318-ff7f7aa18ffd,ceph.data_device/dev/test_group/data-lv1,ceph.data_uuidTUpfel-Q5ZT-eFph-bdGW-SiNW-l0ag-f5kh00,ceph.journal_device/dev/sdd1,ceph.journal_uuidcd72bd28-002a-48da-bdf6-d5b993e84f3f,ceph.osd_fsid943949f0-ce37-47ca-a33c-3413d46ee9ec,ceph.osd_id0,ceph.typedata, 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 } ] }json 输出的结构说明顶层是一个以 OSD ID 为键的对象字符串形式的0值为该 OSD 关联设备的数组每个设备对象包含 LV 的常规属性lv_name、lv_path、lv_uuid、vg_name、type以及devices物理设备数组和tags结构化标签对象lv_tags是 LVM 原始标签的逗号分隔字符串与tags对象内容等价只是保持了 LVM 元数据的原始呈现。json 输出由 listing.py 的list方法 直接json.dumps(report, indent4, sort_keysTrue)生成。源码注释揭示了一个重要的工程细节当报告为空没有任何 Ceph 设备时json 模式依然返回退出码 0而不是报错。这是因为该输出常被 ceph-ansible 等自动化系统消费调用方只需读取 JSON 内容判断即可非零退出码反而会带来不必要的噪音相比之下pretty模式在无结果时会抛出No valid Ceph lvm devices found并非零退出raise SystemExit更适合交互式排查。另外json 模式下devices字段是数组而非逗号拼接tags中保留了ceph.osd_id0这类原始标签键与pretty模式中osd id的可读形式形成鲜明对比——两者服务于不同的消费场景。信息同步机制设备名变化时如何保持准确在执行任何列表操作之前ceph-volume lvm list会先查询 LVM API确保可能被使用的物理设备没有发生命名漂移。为什么需要这一步因为像/dev/sda1这类非持久化设备名在重启或硬件枚举顺序变化后可能变成/dev/sdb1如果直接使用旧名报告就会指向错误的设备。检测原理PARTUUID检测得以实现的关键在于PARTUUID被作为元数据的一部分保存在 data 逻辑卷的 LVM 标签中。即使 journal 是物理设备非 LVM 卷其PARTUUID信息也会存储在与之关联的 data LV 上这正是上文/dev/sdd1条目中PARTUUID字段的来源。具体的同步流程为报告生成前工具通过blkid按PARTUUID反查设备的当前真实名称如果发现当前名称与标签中记录的名称不一致例如/dev/sda1已变为/dev/sdb1则更新对应 LVM 标签使后续报告使用刷新后的新名称。从源码结构看这一按需刷新的行为与 lvm.py API 中围绕 LV 标签读写、blkid/PARTUUID查询的工具函数相互配合保证list报告始终反映设备的最新命名避免运维人员被过时的设备路径误导。源码视角list子命令的完整调用链ceph-volume lvm list的入口在 src/ceph-volume/ceph_volume/devices/lvm/main.py 的mapper字典中list映射到listing.List类。整个执行流程可概括为main.py的LVM.main()通过terminal.dispatch(self.mapper, self.argv)将list参数分发给listing.ListList.main()解析参数device位置参数与--format选项List.list()判断是否传入设备参数分别调用single_report()或full_report()create_report()遍历 LV先做 Ceph 关联过滤is_ceph_device再按 OSD ID 分组、补充物理设备devices字段、追加非 LVM 的 journal/wal/db 物理设备条目最后根据--format走json.dumpsjson 模式或pretty_report()pretty 模式内含标签名可读化与osd.%s标题渲染。其中full_report实际执行的是create_report(api.get_lvs())即全量扫描系统 LV而direct_report()是一个不带 CLI 参数解析的便捷入口供其他非 CLI 消费者直接获取完整报告无需构造参数对象。依赖前提list能正确工作有一个前提相关 LV 必须已经通过ceph-volume lvm prepare/create或batch预先打上所需标签。只有携带了ceph.cluster_fsid、ceph.osd_id、ceph.type等标签的 LV 才会被is_ceph_device识别为 Ceph 设备这与 doc/dev/ceph-volume/lvm.rst 中标签是设备发现的唯一依据的设计一脉相承。常用的ceph.*标签包括typedata/journal/osd 等、cluster_fsid、osd_fsid、osd_id、data_device/data_uuid、journal_device/journal_uuid以及 bluestore 后端的block_device/block_uuid、db_device/db_uuid、wal_device/wal_uuid和encryptedLUKS 加密标记、vdo等。实用建议与常见场景快速核对 OSD 与磁盘的对应关系执行ceph-volume lvm list按 osd.N 分段阅读即可确认每个 OSD 的数据盘、日志盘分别落在哪些物理设备上脚本化采集设备元数据使用ceph-volume lvm list --formatjson配合jq按 OSD ID 聚合tags与devices数组注意空结果时退出码仍为 0需自行判断 JSON 是否为空排查设备名漂移当怀疑/dev/sdX名称变化导致 OSD 激活失败时优先运行list触发 PARTUUID 同步并观察devices字段是否已更新为新路径定位单一设备归属不确定某个裸盘属于哪个 OSD 时用ceph-volume lvm list /dev/sdX1直接查询输出中的osd id与type字段会给出答案与相关命令配合list只读不改动设备状态是排查问题的安全第一步确认归属后再结合 zap.rst销毁设备、migrate.rst迁移 journal/db/wal等命令执行变更操作。小结ceph-volume lvm list以 LVM 标签为核心把发现设备 → 按 OSD 分组 → 输出报告三个环节串成一条清晰的链路pretty模式适合人工排障json模式适合自动化消费单设备查询支持vg/lv、/dev/xxx与 OSD ID 三种输入形式而基于PARTUUID的命名同步机制保证了结果始终与设备真实状态一致。理解其输出字段与标签约定是高效管理 Ceph OSD 设备、排查启动与挂载问题的关键基本功。【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考