Ceph ceph-volume simple activate 详解:接管已部署 OSD 的激活机制与实战操作
Ceph ceph-volume simple activate 详解接管已部署 OSD 的激活机制与实战操作【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph导读本文围绕 Ceph 官方文档 doc/ceph-volume/simple/activate.rst 展开深入剖析ceph-volume simple activate子命令的设计意图、命令行用法、设备发现原理、systemd 激活链路及其在源码层面的实现细节。读完本文你将掌握如何基于scan阶段生成的 JSON 元数据激活一个已部署 OSD、为何激活必须同时提供 OSD ID 与 OSD UUID、激活时系统会对ceph-disk与 systemd 单元做哪些处理以及设备在改名或迁移后仍能被正确定位的内在机制。一、前置条件scan阶段生成的 JSON 元数据activate并不是一个自包含的操作它依赖ceph-volume simple家族的前置步骤。整个simple工作流分为两步Scan扫描正在运行的 OSD 或其数据设备把启动 OSD 所需的一切元数据捕获下来Activate依据扫描结果激活 OSD使其在无udev/ceph-disk干预的情况下正常启动。scan阶段默认会把元数据以 JSON 格式持久化到/etc/ceph/osd/目录文件命名约定为OSD ID-OSD FSID.json例如一个 ID 为0、FSID 为6cc43680-4f6e-4feb-92ff-9c7ba204120e的 OSD其元数据文件路径为/etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json只有当该文件存在且内容完整时OSD 才准备好被激活。因此activate的官方帮助文本也明确强调The OSD must have been scanned previously (seeceph-volume simple scan)so that all needed OSD device information and metadata exist.见 src/ceph-volume/ceph_volume/devices/simple/activate.py。关于scan的完整细节目录扫描、设备扫描、JSON 内容结构等可参考配套文档 doc/ceph-volume/simple/scan.rst。二、激活入口命令行用法全解2.1 以 OSD ID OSD UUID 激活激活过程要求同时使用OSD ID与OSD UUID即 OSD FSID两个参数ceph-volume simple activate 0 6cc43680-4f6e-4feb-92ff-9c7ba204120e执行上述命令后ceph-volume会假定对应的 JSON 配置文件位于/etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json在源码中该路径通过os.path.join(json_dir, %s-%s.json % (args.osd_id, args.osd_fsid))拼接而成其中json_dir默认取自环境变量CEPH_VOLUME_SIMPLE_JSON_DIR未设置时回退为/etc/ceph/osd/。若拼接出的路径不存在命令会抛出RuntimeError(Expected JSON config path not found: %s % json_config)见 activate.py。2.2 直接指定 JSON 文件如果不想依赖默认目录与命名约定可以直接把 JSON 文件路径传给--file参数ceph-volume simple activate --file /etc/ceph/osd/0-6cc43680-4f6e-4feb-92ff-9c7ba204120e.json2.3 批量激活--allactivate还支持一次性激活目录下所有已扫描 OSDceph-volume simple activate --all源码会通过glob.glob({}/*.json.format(json_dir))遍历 JSON 目录中的全部文件逐个执行激活单个 OSD 激活失败抛出RuntimeError时只打印告警不会中断其余 OSD 的激活。若同时传了--file或 ID/FSID则会被忽略并输出--all was passed, ignoring --file and ID/FSID arguments的提示。2.4 跳过 systemd 操作--no-systemd默认激活会创建并启用 systemd 单元、启动 OSD 服务。若只需要完成挂载与符号链接等准备动作而不触碰 systemd例如在容器或测试环境中可以使用ceph-volume simple activate --no-systemd ID FSID该参数在源码中映射为skip_systemd启用后会跳过enable_systemd_units()中创建simple单元、maskceph-disk单元、enable/startceph-osdid的全部操作并输出Skipping enabling and starting OSD simple systemd unit because --no-systemd was used。2.5 参数一览参数说明默认行为IDOSD ID通常为整数如0必须与 FSID 同时提供除非使用--file或--allFSIDOSD FSID/UUID类似 SHA1 的字符串必须与 ID 同时提供除非使用--file或--all--file PATH指向已扫描 OSD 的 JSON 文件未指定时按ID-FSID.json拼接默认路径--all激活 JSON 目录下所有 OSD与--file/ID/FSID 互斥优先生效--no-systemd跳过 systemd 单元的创建、启用与 OSD 启动默认执行全部 systemd 操作环境变量CEPH_VOLUME_SIMPLE_JSON_DIR指定扫描 JSON 的存放目录未设置时默认/etc/ceph/osd/注意源码注释特意说明不提供 CLI 参数来指定 JSON 目录——因为如果允许在自定义路径激活开机时 systemd 若无法通过环境变量看到该路径激活将失败。三、为什么必须同时提供 OSD ID 与 UUID原文档明确指出OSD UUID 是一个额外的校验步骤用于确保激活的是正确的 OSD。原因是完全可能存在一个同 ID 的旧 OSD例如 OSD 被删除重建后 ID 复用仅凭 ID 激活很可能误启动错误的那一个。结合源码看这一校验体现在两层命令行层Activate.main()中若既没有--file也没有--all则要求 ID 和 FSID 同时给出否则报错ID and FSID are required to find the right OSD to activate。元数据层Activate.activate()会从 JSON 中重新读取whoamiOSD ID与fsid并以data.uuid作为主键去发现设备若 JSON 中data缺少uuid键同样会抛出RuntimeErrorno uuid key found for data。这意味着激活的正确性是由JSON 文件 ID/FSID 双重定位保证的。四、设备发现Discoveryblkid 与 lvm激活的核心难点之一是把哪个物理设备映射到哪个 OSD。ceph-volume采用discovery发现流程基于blkid与lvm两个底层工具完成。目前仅支持两类设备GPT 分区通过blkid查询其PARTUUIDLVM 逻辑卷通过lvsLVM 列出逻辑卷的工具查询其lv_uuid。这种设计带来一个关键能力即使设备被迁移到另一台机器或者设备名发生变化如非持久化的/dev/sda1这类名字只要 UUID 不变设备依然能被正确定位。这与直接依赖设备路径的方案有本质区别。设备发现完成后scan阶段生成的 JSON 配置文件将扮演映射表角色负责在激活时协调设备的挂载mount与符号链接symlink动作。以block.db设备为例JSON 中会同时存在两种记录详见 doc/ceph-volume/simple/scan.rstblock.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.db记录的是最新最准的设备信息激活时会对 LVM 与blkid重新查询确认而block.db_uuid是ceph-disk时代遗留的特殊文件内容。保留这种重复是为了支持没有ceph-disk特殊文件的 OSD、保证设备信息始终最新、同时兼容逻辑卷与 GPT 设备。在源码的get_device()方法中disk.get_device_from_partuuid(uuid)负责把 UUID 解析为实际设备路径见 activate.py。五、与 ceph-disk 的博弈mask systemd 单元ceph-volume simple的定位是接管take over那些由ceph-disk部署的 OSD摆脱udev/ceph-disk在开机时的自动触发机制。因此激活过程的一个重要副作用是禁用disable所有ceph-disk的 systemd 单元防止 udev/ceph-disk 交互在开机时再次尝试拉起这些设备。具体做法并非普通的systemctl disable而是mask屏蔽源码中systemctl.mask_ceph_disk()实际执行的是ln -sf /dev/null /etc/systemd/system/ceph-disk.service即把ceph-disk.service模板直接链接到/dev/null使其完全失效源码注释解释了原因systemctl mask ceph-disk*的通配符屏蔽方式在模板单元上存在 bug因此改为直接链接。由于/etc/systemd优先级高于其他位置的单元文件这一做法可靠生效见 src/ceph-volume/ceph_volume/systemd/systemctl.py。这里有一个值得注意的行为差异原文档特别强调当直接执行ceph-volume simple activate时会maskceph-disk单元当由 systemd 在系统开机过程中调用激活时会跳过这一步。这一差异在源码中由from_trigger标志控制Activate([osd_id, osd_uuid], from_triggerTrue)时即经由trigger子命令进入enable_systemd_units()会跳过enable_volume与mask_ceph_disk仅输出Skipping enabling of simple systemd unit与Skipping masking of ceph-disk systemd units提示见 trigger.py 与 activate.py。六、systemd 激活链路ceph-volumesimple- -激活不仅是一次性的命令行操作更是一条可被开机自动触发的 systemd 链路。6.1 单元命名与启用激活过程中systemd 会捕获 OSD ID 与 OSD UUID 并持久化内部等价于执行systemctl enable ceph-volumesimple-id-uuid例如systemctl enable ceph-volumesimple-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41这即为 ID 为0、UUID 为8715BEB4-15C5-49DE-BA6F-401086EC7B41的 OSD 启动了发现discovery流程。源码中systemctl.enable_volume(id_, fsid, device_typesimple)最终执行的就是systemctl enable ceph-volumesimple-id-fsid。6.2 单元模板ceph-volume.service模板单元定义在仓库的 systemd/ceph-volume.service.in核心内容如下[Unit] DescriptionCeph Volume activation: %i Afterlocal-fs.target Wantslocal-fs.target [Service] Typeoneshot KillModenone EnvironmentCEPH_VOLUME_TIMEOUT10000 ExecStart/bin/sh -c timeout $CEPH_VOLUME_TIMEOUT CMAKE_INSTALL_PREFIX/sbin/ceph-volume-systemd %i TimeoutSec0 [Install] WantedBymulti-user.target要点解读Typeoneshot激活是一次性任务执行完即退出ExecStart中的%i会被替换为实例名如simple-0-8715BEB4-...交给ceph-volume-systemd处理CEPH_VOLUME_TIMEOUT10000为激活操作设置了超时保护避免设备长时间无响应时 systemd 被卡死WantedBymulti-user.target保证单元在系统进入多用户模式时被拉起实现开机自动激活。6.3 triggersystemd 到 activate 的桥梁systemd 部分由ceph-volume simple trigger子命令承担。它的职责非常单一解析来自 systemd 的元数据然后分派给ceph-volume simple activate。其用法为ceph-volume simple trigger {SYSTEMD-DATA}其中SYSTEMD-DATA的格式为{OSD ID}-{OSD UUID}例如0-8715BEB4-15C5-49DE-BA6F-401086EC7B41。源码中Trigger.main()通过parse_osd_id()与parse_osd_uuid()把该字符串拆分为 ID 与 UUID然后调用Activate([osd_id, osd_uuid], from_triggerTrue).main()。trigger的帮助文本明确标注DO NOT USE DIRECTLY——它是 systemd 单元的内部助手不应被人工直接调用。6.4 开机启动时 systemd 侧的行为配套文档 doc/ceph-volume/simple/systemd.rst 描述了 systemd 侧启动流程单元实例名对应/etc/ceph/osd/id-uuid.jsonsystemd 启动时加载该 JSON 文件识别出逻辑卷后按 OSD 目标目录约定进行挂载/var/lib/ceph/osd/cluster name-osd id对于 ID 为0的 OSD即挂载到/var/lib/ceph/osd/ceph-0挂载完成后调用systemctl start ceph-osd0七、激活执行细节从源码看完整流程综合 activate.py 的实现一次完整的激活Activate.activate()按以下顺序执行7.1 加载与校验 JSON读取 JSON 文件并调用validate_devices()校验设备组合。对于 BlueStore OSD要求block与data两个键必须同时存在{block, data}.issubset(set(devices))否则报错Unable to activate bluestore OSD due to missing devices并列出已找到的 bluestore 设备block.db、block.wal、block、data。若 JSON 缺少type键则假定为bluestore因为不存在journal键可推断不是 Filestore。7.2 解析身份与路径osd_id取自whoami回退到命令行 IDosd_fsid取自fsid回退到命令行 FSIDdata_uuid取自data.uuid缺失则直接报错集群名默认ceph可由 JSON 中cluster_name覆盖目标目录拼接为/var/lib/ceph/osd/cluster_name-osd_id。7.3 加密设备处理若 JSON 标记encrypted激活会写入 lockbox keyringwrite_lockbox_keyring保证可解锁获取 dmcrypt 密钥并做base64.b64decode源码注释说明ceph-disk在 monitor 中存储的是未解码的密钥因此simple扫描的 OSD 需要额外一次解码而lvm侧加密不需要根据encryption_typeluks或plain调用luks_open/plain_open解密设备解密后返回/dev/mapper/uuid路径。scan阶段对 LUKS/PLAIN 加密的完整支持是这一能力的前提见 scan.rst。7.4 挂载数据设备若数据设备尚未挂载到目标目录system.device_is_mounted()检查则执行mount -v data_device /var/lib/ceph/osd/cluster_name-osd_id7.5 重建符号链接对block、block.db、block.wal三个设备只要 JSON 中存在对应 UUID 且能被解析为设备就执行ln -snf device osd_dir/name-f强制覆盖、-n避免把目录当作链接目标确保符号链接每次激活都会被重新建立原文档强调符号链接将alwaysbe re-done以保证链接指向正确的设备即使设备路径因重新部署或改名而发生变化。随后还会对设备执行chown保证 OSD 进程拥有正确的属主权限。7.6 启用与启动 OSD最后调用enable_systemd_units()创建并启用ceph-volumesimple-id-fsid单元mask 所有ceph-disk单元仅直接调用时执行systemctl enable --runtime ceph-osdid运行时启用systemctl start ceph-osdid启动 OSD。全部完成后输出Successfully activated OSD id with FSID fsid。八、三个子命令的协作关系ceph-volume simple命名空间下共三个子命令见 src/ceph-volume/ceph_volume/devices/simple/main.py 的 mapper 映射它们构成完整的生命周期闭环子命令职责触发时机scan捕获已部署 OSD 的元数据写入/etc/ceph/osd/id-fsid.json人工执行activate依据 JSON 挂载设备、重建链接、启用并启动 OSD人工执行--file/IDFSID/--alltrigger解析 systemd 传入的{ID}-{UUID}分派给activatefrom_triggerTruesystemd 开机自动执行从调用链上看ceph-volumesimple-id-uuid单元systemd 开机触发→ceph-volume simple trigger id-uuid→ceph-volume simple activate id uuid跳过 mask/enable 步骤→ 挂载、重建链接、systemctl start ceph-osdid。整体工作流可概括为scan 捕获元数据 → JSON 持久化 → 开机时 trigger 解析单元名 → activate 完成设备挂载与链接 → ceph-osd 单元启动。这一链路取代了旧的 udev/ceph-disk 触发机制使ceph-volume能以更可控、更可预测的方式管理历史部署的 OSD。【免费下载链接】cephCeph is a distributed object, block, and file storage platform项目地址: https://gitcode.com/gh_mirrors/ce/ceph创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考