Appearance
Ceph 块与文件
Ceph 集群对外提供三类接口:RBD 块设备、CephFS 文件系统、RGW 对象存储。这篇覆盖 RBD 和 CephFS,RGW 和 S3 语义放到对象存储里单独看。
RBD 暴露的是一块远端块设备,客户端格式化成 ext4/xfs 后挂载,常见场景是虚拟机磁盘、单实例数据库数据盘、K8s RWO 卷。CephFS 暴露的是一个已有的共享文件系统,多台客户端直接挂目录,常见场景是共享文件、日志归档、多 Pod 读写的共享目录。二者底层数据都存在 Ceph OSD 里,但访问语义完全不同。
RBD 镜像创建和挂载
创建 Pool 并启用 RBD:
bash
ceph osd pool create rbd-pool 32
ceph osd pool application enable rbd-pool rbd
rbd pool init rbd-pool创建镜像:
bash
# 相当于申请一块 10G 的远端块设备
rbd create rbd-pool/app-data --size 10G
rbd info rbd-pool/app-data客户端挂载:
bash
rbd map rbd-pool/app-data --name client.admin
rbd showmapped
lsblk # 出现 /dev/rbd0
mkfs.xfs /dev/rbd0
mkdir -p /data/app
mount /dev/rbd0 /data/appRBD 镜像默认按单客户端读写设计。多台机器同时把同一个 RBD 当普通文件系统挂载会写坏数据——除非上层用了支持共享块设备的集群文件系统或应用协议(如 Oracle RAC 配合特定配置)。
两种映射方式:
| 方式 | 路径 | 场景 |
|---|---|---|
krbd | 内核 RBD 驱动,rbd map 默认 | 普通 Linux 挂载 |
rbd-nbd | 通过 NBD 暴露块设备,用户态 | 老内核或特定 feature 兼容 |
老内核不支持新 RBD feature 时 rbd map 会直接失败。排查时看客户端内核版本、Ceph 版本和镜像 feature:
bash
rbd info rbd-pool/app-data为老内核创建更保守的镜像:
bash
# layering 是基础 feature,兼容性最好
rbd create rbd-pool/legacy-data --size 10G --image-feature layeringRBD 快照、回滚和克隆
快照记录某个时间点的块设备状态,不是备份的全部——Pool 坏、集群误删、逻辑数据早已损坏时,光靠快照不够。
bash
# 创建快照前最好先静默应用写入(fs freeze 或应用层处理)
rbd snap create rbd-pool/app-data@snap-20260522
rbd snap ls rbd-pool/app-data回滚:
bash
# 执行前停写入、umount、unmap
umount /data/app
rbd unmap /dev/rbd0
rbd snap rollback rbd-pool/app-data@snap-20260522
rbd map rbd-pool/app-data --name client.admin
mount /dev/rbd0 /data/app克隆依赖父快照,先 protect 再 clone:
bash
rbd snap protect rbd-pool/app-data@snap-20260522
rbd clone rbd-pool/app-data@snap-20260522 rbd-pool/app-data-clone需要完全摆脱父快照时 flatten:
bash
# flatten 把依赖数据摊平到克隆镜像自身,耗时和数据量相关
rbd flatten rbd-pool/app-data-clone镜像删不掉时,原因通常是还有快照、克隆依赖或客户端 watcher——rbd status 能看到谁在占用。
RBD 扩容
扩容镜像本身:
bash
rbd resize rbd-pool/app-data --size 20G
rbd info rbd-pool/app-data然后扩文件系统(两步都要做,先 resize 镜像再扩文件系统):
bash
xfs_growfs /data/app # xfs 在线扩容ext4 用 resize2fs /dev/rbd0。RBD 扩容比较顺手,缩容很危险——顺序是文件系统先缩再缩块设备,顺序反了直接破坏数据。
RBD 客户端权限
给业务客户端分配最小权限,避免随手发放 client.admin:
bash
ceph auth get-or-create client.app \
mon 'profile rbd' \
osd 'profile rbd pool=rbd-pool' \
mgr 'profile rbd pool=rbd-pool' \
-o /etc/ceph/ceph.client.app.keyring
chmod 600 /etc/ceph/ceph.client.app.keyring使用:
bash
rbd map rbd-pool/app-data --name client.appRBD 持久化挂载
手动 rbd map 和 mount 在重启后会消失。用 systemd unit 固化:
ini
[Unit]
Description=Map Ceph RBD app-data
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/rbd map rbd-pool/app-data --name client.app
ExecStart=/usr/bin/mount /dev/rbd/rbd-pool/app-data /data/app
ExecStop=/usr/bin/umount /data/app
ExecStop=/usr/bin/rbd unmap /dev/rbd/rbd-pool/app-data
[Install]
WantedBy=multi-user.target生产里要加等待 Ceph 网络和 keyring 的依赖。RBD 数据盘挂上之前如果应用先启动了,数据会写到本地空目录而不是真正的数据盘上。
CephFS 核心组件
CephFS 的文件内容存在 OSD 的数据池里,目录树、文件名、权限、inode 这类元数据由 MDS 管理:
两个底层 Pool:
| Pool | 存放内容 |
|---|---|
| metadata pool | 目录树、inode、文件权限和元数据 |
| data pool | 文件内容数据块 |
MDS 异常时,目录遍历、创建、删除、rename 这类元数据操作会直接受影响——不一定是数据池慢。
MDS 常见状态:
| 状态 | 含义 |
|---|---|
active | 当前提供服务 |
standby | 待命,active 故障后接管 |
standby-replay | 跟随 active 回放日志,接管更快 |
replay/resolve | 故障恢复中间态 |
创建 CephFS
bash
# metadata pool 用较少的 PG,data pool 用较多的 PG
ceph osd pool create cephfs_data 64
ceph osd pool create cephfs_metadata 32
ceph osd pool application enable cephfs_data cephfs
ceph osd pool application enable cephfs_metadata cephfs
ceph fs new cephfs cephfs_metadata cephfs_data
ceph fs ls部署 MDS(至少保留 standby):
bash
ceph orch apply mds cephfs --placement="3 ceph01 ceph02 ceph03"
ceph fs status cephfs挂载 CephFS
内核客户端(性能和稳定性通常更好):
bash
mkdir -p /mnt/cephfs
# MON 地址写多个,客户端能在 MON 之间切换
mount -t ceph 192.168.10.41:6789,192.168.10.42:6789,192.168.10.43:6789:/ /mnt/cephfs \
-o name=admin,secretfile=/etc/ceph/admin.secretceph-fuse(用户态,部署和调试更方便,适合老内核):
bash
mkdir -p /mnt/cephfs
ceph-fuse -n client.admin /mnt/cephfsCephFS 权限
CephFS 权限分两层:CephX 控制能不能访问文件系统或特定路径,Linux 文件权限控制具体读写的目录和文件。两层都通过才真正能写。
bash
# 限制只能访问 CephFS 下 /app 路径
ceph fs authorize cephfs client.app /app rw
ceph auth get client.app -o /etc/ceph/ceph.client.app.keyringCephFS 快照
bash
ceph fs set cephfs allow_new_snaps true
mkdir -p /mnt/cephfs/app
mkdir /mnt/cephfs/app/.snap/snap-20260522
ls /mnt/cephfs/app/.snap删除快照:rmdir /mnt/cephfs/app/.snap/snap-20260522。快照会占用后端容量——文件删了但快照还在,空间不会立刻释放。
CephFS 运行时排查
bash
ceph fs status cephfs
ceph mds stat
ceph tell mds.* status
ceph tell mds.cephfs:0 client ls # 看哪些客户端连着 MDS,排查卡住客户端| 现象 | 方向 |
|---|---|
ls 很慢 | MDS 负载、目录文件过多、metadata pool 延迟 |
| 客户端卡住 | session/caps 异常、网络中断、MDS 切换 |
| MDS 频繁切换 | MDS 进程异常、内存不足、metadata pool 慢 |
| 空间不释放 | 快照未删、客户端仍持有已删除文件 |
| 单目录特别慢 | 单目录下文件过多,元数据集中 |
CephFS 的慢不一定是数据池慢。目录遍历和元数据操作更偏向 MDS 和 metadata pool,大文件顺序读写才更偏 OSD 数据池和网络。
常见故障汇总
RBD:
| 现象 | 方向 |
|---|---|
rbd map 失败 | ceph.conf、keyring、内核模块、MON 网络 |
| 挂载文件系统失败 | 未格式化、文件系统损坏、重复挂载 |
| 无法删除镜像 | 有快照、有 watcher、被克隆依赖 |
| 扩容后空间不变 | 文件系统还没扩——镜像 resize 和 fs 扩容是两个步骤 |
| 老系统 map 失败 | RBD feature 和内核版本不兼容 |
CephFS:
| 现象 | 方向 |
|---|---|
| 挂载失败 | MON 地址、key 文件存在、MDS 状态、客户端版本 |
| 目录操作慢 | MDS 负载、单目录文件数量、metadata pool 延迟 |
| 文件读写慢 | OSD 延迟、网络、客户端缓存不足 |
| 权限异常 | CephX 权限和 Linux 文件权限各查各的 |
| MDS active 不稳定 | MDS 日志、内存、metadata pool、standby 是否正常接管 |
客户端排查入口:
bash
mount | grep -E 'ceph|rbd'
dmesg | grep -i ceph | tail -50
lsblk集群侧排查入口:
bash
ceph -s
ceph health detail
ceph osd perf
ceph fs status cephfs
rbd status rbd-pool/app-data客户端报 IO 慢时,根因常常在 OSD slow ops、PG recovery、某块 OSD 磁盘延迟或 MDS 负载。同时看客户端和集群状态,不要只看一边。