☰
Incus CephFS 存储驱动详解:基于 Ceph 分布式文件系统的自定义卷存储
2026/10/10 5:53:14 网站建设 项目流程
  • 后端
  • 虚拟化
  • 容器运行时

【免费下载链接】incus

Powerful system container and virtual machine manager

项目地址:https://gitcode.com/gh_mirrors/inc/incus
点击查看免费下载

本篇技术指南围绕 Incus 的cephfs存储驱动展开,讲解如何利用 Ceph 的分布式文件系统组件 CephFS 为 Incus 提供远程、可共享的文件系统存储,涵盖驱动适用场景、Ceph 术语、存储池与存储卷的全部配置项,以及源码层面的创建、挂载与校验机制。读完本文,你将掌握在 Incus 中创建并管理 CephFS 存储池的完整配置方法,理解source、cephfs.create_missing、cephfs.data_pool、cephfs.meta_pool等核心参数的作用与底层实现,并能在多节点集群中正确规划此类存储的用途。

CephFS 与 Incus 存储体系

cephfs是 Incus 提供的众多存储驱动之一,对应 doc/reference/storage_cephfs.md 中定义的驱动名称。CephFS(Ceph File System)是 Ceph 的文件系统组件,提供了一个健壮、功能完整且符合 POSIX 规范的分布式文件系统。在内部实现上,CephFS 将文件映射到 Ceph 对象(object)上存储,并将文件元数据(例如文件属主、目录路径、访问权限)存放在一个独立的数据池中。

Ceph 本身是一个开源存储平台,数据保存在基于 RADOS(Reliable Autonomic Distributed Object Store,可靠自主分布式对象存储)的存储集群中。它具有很高的可扩展性,并且由于是无单点故障的分布式系统,可靠性也非常出色。Ceph 为块存储和文件系统提供了不同的组件:

  • Ceph RBD(RADOS Block Device):Ceph 的块存储组件,将数据和工作负载分布到整个 Ceph 集群,支持精简配置(thin provisioning),因此允许资源超配。在 Incus 中对应ceph驱动。
  • CephFS:Ceph 的文件系统组件,即本文介绍的cephfs驱动所使用的底层存储。

需要特别注意的是,Incus 中名为ceph的驱动只使用 Ceph RBD(块存储)功能,而非完整的 Ceph 功能;若需要基于 Ceph 提供文件系统类型的存储卷,则应选用cephfs驱动。

Ceph 基础术语

在深入配置之前,先厘清 Ceph 的常用术语(源自 doc/reference/storage_ceph.md 中共享的 Ceph 术语说明):

  • 对象(Object):Ceph 存储数据的基本单位。
  • OSD(Object Storage Daemon,对象存储守护进程):负责存储和管理数据的守护进程。
  • 池(Pool):Ceph 存储的逻辑分区,用于存放对象,也被称为数据池(data pool)、存储池(storage pool)或 OSD 池(OSD pool)。

一个CephFS 文件系统由两个 OSD 存储池组成:一个存放实际的数据,另一个存放文件的元数据。这种数据与元数据分离的设计是 CephFS 高性能与可扩展性的基础。

cephfs驱动在 Incus 中的定位

Incus 的cephfs驱动并不是一个通用的块存储驱动,它有着明确的适用范围。原文档明确指出:

cephfs驱动只能用于内容类型(content type)为filesystem的自定义存储卷。

对于其他类型的存储卷,应使用ceph驱动。ceph驱动同样可以为内容类型为filesystem的自定义存储卷提供服务,但它的实现方式是在 Ceph RBD 镜像之上叠加一个文件系统(由block.filesystem配置项控制,详见 doc/reference/storage_ceph.md)。这种"模拟"方式带来一个关键限制:由于文件系统叠加在单个 RBD 镜像之上,内容类型为filesystem的自定义存储卷同一时刻只能被分配给一个实例;如果需要多个实例(甚至是不同集群成员上的实例)同时共享一个filesystem类型的自定义卷,就必须使用cephfs驱动。

这一约束在驱动源码中有直接体现。driver_cephfs.go 中Info()方法返回的驱动信息显示:

VolumeTypes: []VolumeType{VolumeTypeCustom}, // 仅支持自定义存储卷 VolumeMultiNode: d.isRemote(), // 支持多节点共享 BlockBacking: false, // 非块设备后端 MountedRoot: true, // 以挂载根路径方式使用

而CreateVolume的实现(driver_cephfs_volumes.go)则对卷类型做了硬性校验,非自定义卷(VolumeTypeCustom)或非文件系统内容类型(ContentTypeFS)都会直接返回ErrNotSupported。这从源码层面印证了"仅用于 filesystem 内容类型的自定义存储卷"这一限制。

与本地存储驱动的差异

与大多数存储驱动不同,cephfs驱动不会主动搭建存储系统,而是假定你已经安装并运行了一个可访问的 Ceph 集群(这与ceph驱动共享同一前提)。此外,cephfs提供的是远程存储:受内部网络影响,存储访问可能比本地存储稍慢;但在集群环境中,远程存储具有巨大优势——所有集群成员都能访问完全相同的存储池与内容,无需在成员之间同步存储池数据。从源码看,driver_cephfs.go 中的isRemote()方法直接返回true,Info()中的Remote与VolumeMultiNode字段均以此为据,确认了该驱动属于远程、多节点可共享的存储类型。

池的完全控制权

Incus 假定自己拥有对 OSD 存储池的完全控制权。因此,不应在 Incus 使用的 OSD 存储池中维护任何非 Incus 拥有的文件系统实体,因为 Incus 可能会将其删除。这一原则同样适用于ceph驱动,属于两个 Ceph 相关驱动共享的行为约定。

创建 CephFS 存储池的两种方式

cephfs驱动提供了两种接入 CephFS 文件系统的方式,二者通过配置项组合决定:

  1. 使用已有文件系统:预先在 Ceph 集群中创建好 CephFS 文件系统,然后通过存储池的source配置项指定要使用的文件系统(或文件系统路径)。
  2. 自动创建:设置cephfs.create_missing为true,Incus 会自动创建文件系统,以及配置项cephfs.data_pool和cephfs.meta_pool所指定的数据与元数据 OSD 池。

从 driver_cephfs.go 的Create()实现可以完整还原这套流程的底层逻辑:

  • 首先检查source配置,缺失时直接报错Missing required source name/path;
  • 将cephfs.path与source进行一致性校验(cephfs.path必须与source匹配),并解析出文件系统名fsName与路径fsPath;
  • 调用fsExists()判断目标 CephFS 是否已存在。若已存在,则拒绝设置cephfs.create_missing、cephfs.osd_pg_num、cephfs.meta_pool、cephfs.data_pool等与创建文件系统相关的键;
  • 若文件系统不存在,则必须设置cephfs.create_missing=true,否则报错The requested CephFS doesn't exist。创建时cephfs.osd_pg_num若未指定,源码中会默认设为32(注释说明 Ceph 会在必要时自动调整该值);
  • 依次检查并创建元数据池与数据池(缺失时执行ceph osd pool create),最后通过ceph fs new <fsName> <meta_pool> <data_pool>创建文件系统;
  • 完成创建后,Incus 会临时挂载该文件系统,创建source指定的目录路径,并要求该路径必须为空(源码中Only empty CephFS paths can be used as a storage pool)。整个流程由revert机制兜底,任何一步失败都会回滚已创建的 OSD 池与文件系统。

fsExists()与osdPoolExists()的具体实现位于 driver_cephfs_utils.go,两者都通过调用ceph命令查询,并依据退出码判断:错误状态码为2时确认目标不存在,其他非零状态码则视为无法确定(可能为网络问题或 Ceph 内部问题),直接返回错误。

挂载的底层实现

cephfs驱动通过内核 Ceph 文件系统挂载 CephFS。在 utils_ceph.go 的CephBuildMount()中,Incus 会从 Ceph 集群收集三样关键信息来构造挂载参数:

  • FSID(CephFsid()):Ceph 集群的唯一标识;
  • Monitors(CephMonitors()):monitor 节点地址列表,优先使用 v2 协议地址(ms_mode=prefer-crc),否则回退到 v1 协议(ms_mode=legacy);
  • Keyring(CephKeyring()):客户端密钥。若密钥为空,则认为禁用了 cephx 认证。

最终构造出的挂载源形如user@fsid.fsName=/path,挂载选项包含mon_addr、name、secret等,随后通过TryMount()挂载到GetPoolMountPath(d.name)(driver_cephfs.go)。Mount()方法会先检查挂载点是否已是 Ceph 挂载点,避免重复挂载。

存储池配置选项

下表整理了cephfs驱动的存储池配置项(源自 doc/config_options.txt 中storage_cephfs-common配置组,同时对应 driver_cephfs.go 中Validate()的校验规则):

配置项类型默认值作用域说明
sourcestring-(必填)本地(local)要使用的现有 CephFS 文件系统或文件系统路径;创建存储池时必填
cephfs.cluster_namestringceph全局(global)包含 CephFS 文件系统的 Ceph 集群名称,对应常量CephDefaultCluster(见 driver_ceph_utils.go)
cephfs.user.namestringadmin全局(global)使用的 Ceph 用户,默认admin,对应常量CephDefaultUser
cephfs.create_missingboolfalse全局(global)是否自动创建文件系统以及缺失的数据、元数据 OSD 池
cephfs.data_poolstring-全局(global)创建文件系统时使用的数据 OSD 池名称
cephfs.meta_poolstring-全局(global)创建文件系统时使用的元数据 OSD 池名称
cephfs.osd_pg_numstring-(创建时实际默认32)全局(global)创建缺失 OSD 池时使用的pg_num值
cephfs.pathstring/全局(global)CephFS 挂载的基础路径
cephfs.fscacheboolfalse全局(global)是否启用内核fscache与cachefilesd缓存
volatile.pool.pristinestringtrue全局(global)记录 CephFS 文件系统在创建时是否为空的内部状态

其中几个关键配置项的源码行为值得展开:

  • cephfs.cluster_name与cephfs.user.name:在 driver_cephfs.go 的FillConfig()中,若二者为空会自动填充默认值ceph与admin。所有底层ceph命令都会以--name client.<user>和--cluster <cluster>的方式携带这两个参数。
  • source的必填性:Create()中若source为空会直接报错,它是连接具体 CephFS 文件系统的唯一入口。
  • cephfs.path与source的关系:cephfs.path可以理解为存储池在 CephFS 文件系统中的子路径,创建时若两者不一致会报错cephfs.path must match the source。
  • cephfs.fscache:使用validate.Optional(validate.IsBool)校验,开启后允许内核通过fscache/cachefilesd对 CephFS 数据做本地缓存,可提升热点数据访问性能,但需宿主机内核与用户态支持。

创建存储池示例

使用已有 CephFS 文件系统创建存储池:

incus storage create mypool cephfs source=myfs/data cephfs.cluster_name=ceph cephfs.user.name=admin

自动创建文件系统及 OSD 池:

incus storage create mypool cephfs \ cephfs.create_missing=true \ cephfs.meta_pool=myfs_meta \ cephfs.data_pool=myfs_data \ cephfs.osd_pg_num=64 \ cephfs.path=/data

需要注意,cephfs.path指定的路径在文件系统创建时必须为空,否则创建会被拒绝。

存储卷配置选项

cephfs驱动存储池中的存储卷同样支持一组配置项,源自 doc/config_options.txt 中storage_volume_cephfs-common配置组。由于该驱动仅支持filesystem内容类型的自定义卷,多数选项与文件权限、ID 映射和快照管理相关:

配置项类型默认值生效条件说明
sizestring同volume.size适用驱动存储卷的大小/配额
initial.uidint同volume.initial.uid或0filesystem自定义卷卷在实例中的属主 UID
initial.gidint同volume.initial.gid或0filesystem自定义卷卷在实例中的属主 GID
initial.modeint同volume.initial.mode或711filesystem自定义卷卷在实例中的权限模式
security.sharedbool同volume.security.shared或false自定义块卷允许卷被多个实例共享(对cephfs而言天然多实例可共享)
security.shiftedbool同volume.security.shifted或false自定义卷启用 ID 移位(ID shifting),使卷在实例内以隔离的 ID 范围呈现
security.unmappedbool同volume.security.unmapped或false自定义卷禁用卷的 ID 映射
snapshots.expirystring同volume.snapshot.expiry自定义卷快照自动过期时间
snapshots.expiry.manualstring同volume.snapshot.expiry.manual自定义卷手动快照的过期时间
snapshots.patternstring同volume.snapshot.pattern或snap%d自定义卷自动快照的命名模式,其中%d会被替换为时间戳等参数
snapshots.schedulestring同volume.snapshot.schedule自定义卷自动快照的调度计划(cron 格式)

这些选项与cephfs驱动能力的对应关系如下:

  • 共享能力:cephfs驱动天然支持多实例共享filesystem自定义卷(VolumeMultiNode为true),这是它相对于ceph驱动的核心优势之一。
  • ID 映射:security.shifted与security.unmapped控制卷在实例内的 ID 映射行为,与 Incus 通用的 ID 映射机制一致。
  • 初始属主与权限:initial.uid/initial.gid/initial.mode决定卷挂载进实例时的属主与权限位,默认分别为0/0/711。

快照支持与迁移行为

原文档明确指出:如果服务器端启用了快照功能,cephfs驱动支持快照。结合 driver_cephfs.go 的MigrationTypes()实现可以看出,该驱动的数据迁移(包括卷复制、迁移、备份恢复)走的是rsync通道:

if contentType != ContentTypeFS { return nil } // Do not support xattr transfer on cephfs return []localMigration.Type{ { FSType: migration.MigrationFSType_RSYNC, Features: rsyncFeatures, // delete + compress(可选) + bidirectional }, }

值得注意的细节是:cephfs驱动不支持 xattr(扩展属性)传输,即通过 rsync 迁移卷时不会保留扩展属性。rsyncFeatures会根据rsync.compression配置决定是否携带compress特性。此外,Info()中OptimizedImages与PreservesInodes均为false,说明该驱动既没有针对镜像的优化路径,也不保留 inode 编号——这与 CephFS 的元数据存储模型一致。卷的复制(CreateVolumeFromCopy)与备份恢复(CreateVolumeFromBackup)也均基于 rsync/归档解包实现(见 driver_cephfs_volumes.go)。

运行环境要求与注意事项

综合源码与文档,使用cephfs驱动前需要确认以下前提:

  1. Ceph 集群可用:驱动不负责搭建存储系统,必须预先准备一个可访问的 Ceph 集群,并提供 monitor、FSID 与客户端密钥信息。
  2. 宿主机工具:driver_cephfs.go 的load()会校验宿主机上是否存在ceph与rbd两个命令,缺失任一都会报Required tool 'xxx' is missing;同时会记录rbd --version输出版本作为驱动版本。
  3. IncusOS 场景:若运行在 IncusOS 环境,load()还会检查ceph服务是否已启用。
  4. 内核挂载支持:驱动通过内核 Ceph 文件系统挂载(TryMount(..., "ceph", ...)),宿主机内核需包含 Ceph 文件系统支持。
  5. 路径必须为空:用作存储池的 CephFS 路径在创建时必须为空目录。
  6. 存储池专属性:不要在与 Incus 共用的 OSD 池中放置非 Incus 管理的实体,Incus 可能将其删除。

与其他驱动的选型小结

在 Incus 的存储规划中,cephfs与ceph两个驱动均基于 Ceph 但定位不同,原文档给出的选型要点如下:

  • 需要块存储(实例镜像、块设备卷)→ 使用ceph驱动(RBD)。
  • 需要可多实例共享的filesystem自定义卷→ 使用cephfs驱动。
  • ceph驱动也可承载filesystem内容类型的自定义卷,但同一时刻只能绑定一个实例;cephfs驱动则可跨实例、跨集群成员共享。

综上,cephfs驱动是 Incus 中面向"分布式共享文件系统卷"场景的专用方案。若你的部署需要多个容器/虚拟机同时读写同一份自定义卷数据(例如共享代码目录、共享配置、横向扩展的工作节点),并且底层已有 Ceph 集群,cephfs就是原文档推荐的实现路径。更进一步地,可结合 doc/howto/storage_pools.md 了解存储池的通用管理命令,或阅读 doc/reference/storage_ceph.md 对比 Ceph RBD 驱动的完整能力与限制,从而在 doc/reference/storage_drivers.md 所述的各驱动之间做出合理选择。

  • 后端
  • 虚拟化
  • 容器运行时

【免费下载链接】incus

Powerful system container and virtual machine manager

项目地址:https://gitcode.com/gh_mirrors/inc/incus
点击查看免费下载

相关推荐

上一篇:终极Adobe破解指南:GenP 3.0免费解锁完整教程
下一篇:虚拟摇杆驱动vJoy:Windows游戏开发的终极输入模拟解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询