Ceph存储全攻略:RBD、CephFS与RGW详解

目录

[Ceph 块存储RBD](#Ceph 块存储RBD)

[CephFS 文件存储详解](#CephFS 文件存储详解)

[MDS 高可用配置](#MDS 高可用配置)

[RGW 对象存储](#RGW 对象存储)

[Ceph 集群运维](#Ceph 集群运维)

[PG 状态速查指南](#PG 状态速查指南)

数据读写流程与存储池管理

存储池快照与数据压缩

[CephX 是什么?](#CephX 是什么?)

[Ceph RBD 使用详解](#Ceph RBD 使用详解)

[K8s 为什么需要 Ceph?](#K8s 为什么需要 Ceph?)

Ceph 块存储RBD

[一、什么是 RBD?](#一、什么是 RBD?)

[二、创建 RBD 存储池](#二、创建 RBD 存储池)

三、创建映像(Image)

[四、客户端使用 RBD](#四、客户端使用 RBD)

五、常见问题

六、删除数据后空间不释放?

一、什么是 RBD?

RBD(RADOS Block Device)即块存储设备,可以为 KVM、OpenStack、Kubernetes 等提供高性能、可无限扩展的存储后端。客户端通过 librbd 库即可把 Ceph 集群当硬盘用。不过,用于 rbd 的存储池需要事先启用rbd 功能并进行初始化。

二、创建 RBD 存储池

1. 创建存储池

复制代码
 ceph osd pool create myrbd1 64 64
  • 64 64:PG 和 PGP 数量,通常设为相同值 pool 'myrdb1' created

2. 启用 RBD 功能

复制代码
 ceph osd pool application enable myrbd1 rbd

3. 初始化存储池

复制代码
rbd pool init -p myrbd1
三、创建映像(Image)

存储池不能直接使用,需要先在里面创建映像文件,映像才是真正的"虚拟磁盘"。

复制代码
# 创建 5G 映像(默认特性)
rbd create myimg1 --size 5G --pool myrbd1

# 创建 3G 映像(只开启 layering,兼容低版本内核)
rbd create myimg2 --size 3G --pool myrbd1 --image-format 2 --image-feature layering

rbd create	创建一个 RBD 映像
myimg1	映像名称,可以随意起
--size 5G	虚拟磁盘大小 5GB
--pool myrbd1	存放在 myrbd1 这个存储池里
--image-format 2	使用第二版映像格式(支持更多高级特性)
--image-feature layering	只开启 layering(分层)这一个特性,其他全部关闭

Ceph RBD 支持很多高级特性:

特性 作用 低版本内核支持?
layering 支持快照分层/克隆 ✅ 支持
exclusive-lock 排他锁,防止多客户端同时写 ❌ 不支持
object-map 对象位图,加速 resize/flatten 操作 ❌ 不支持
fast-diff 快速计算增量 ❌ 不支持
deep-flatten 深度扁平化 ❌ 不支持

查看映像

bash

复制代码
 rbd ls --pool myrbd1          # 列出所有映像
 rbd --image myimg1 --pool myrbd1 info   # 查看映像详情
四、客户端使用 RBD

1. 安装客户端工具

复制代码
 yum install -y ceph-common

2. 同步认证文件

复制代码
 scp ceph.conf ceph.client.admin.keyring root@客户端IP:/etc/ceph/

3. 映射映像为本地磁盘

复制代码
 rbd -p myrbd1 map myimg2
 # 成功:/dev/rbd0
 ​
 rbd map 把 RBD 映像映射为本地块设备
 -p myrbd1   指定存储池名称
 myimg2  映像名称

4. 格式化并挂载

复制代码
 mkfs.ext4 /dev/rbd0
 mount /dev/rbd0 /data

5. 写入测试

复制代码
 dd if=/dev/zero of=/data/test-file bs=1MB count=300
五、常见问题

映射时报错:feature set mismatch

原因:映像的特性(如 object-map、fast-diff、deep-flatten)需要高版本内核支持,客户端内核太旧不支持。

解决:创建映像时只开启兼容特性:

复制代码
 rbd create myimg2 --size 3G --pool myrbd1 --image-feature layering

或者关闭已有映像的不兼容特性:

复制代码
 rbd feature disable myrbd1/myimg1 object-map fast-diff deep-flatten
六、删除数据后空间不释放?

在 RBD 块存储上删除文件后,ceph df 查看会发现空间没有被回收。

原因:删除操作只是在文件系统层面做了"已删除"标记,并没有通知底层 Ceph 集群释放这些块。

解决方法(二选一)

方法 1:手动触发空间回收

复制代码
 fstrim -v /data
  • fstrim:告诉底层存储"这些块已经不用了,收回去吧"

  • -v:显示回收了多少空间

方法 2:挂载时开启自动回收

复制代码
 mount -o discard /dev/rbd0 /data
  • discard 选项会让文件系统在删除文件时自动通知 底层存储回收空间,不用手动执行 fstrim

CephFS 文件存储详解

[一、CephFS 概述](#一、CephFS 概述)

[二、部署 MDS 服务](#二、部署 MDS 服务)

[1. 安装 MDS](#1. 安装 MDS)

[2. 部署 MDS 节点](#2. 部署 MDS 节点)

[3. 验证 MDS 状态](#3. 验证 MDS 状态)

三、创建存储池并初始化文件系统

四、创建客户端账户与认证文件

[1. 创建普通用户(推荐,不要直接用 admin)](#1. 创建普通用户(推荐,不要直接用 admin))

[2. 验证账户](#2. 验证账户)

[3. 导出认证文件](#3. 导出认证文件)

五、客户端安装与配置

[1. 安装客户端软件](#1. 安装客户端软件)

[2. 同步认证文件到客户端](#2. 同步认证文件到客户端)

[3. 验证权限](#3. 验证权限)

[六、客户端挂载 CephFS](#六、客户端挂载 CephFS)

方式一:内核空间挂载(推荐,性能好)

方式二:用户空间挂载(ceph-fuse,兼容性好)

[安装 ceph-fuse](#安装 ceph-fuse)

两种挂载方式对比

[CephFS 通过 NFS-Ganesha 导出](#CephFS 通过 NFS-Ganesha 导出)

[1. 安装](#1. 安装)

[2. 配置 /etc/ganesha/ganesha.conf](#2. 配置 /etc/ganesha/ganesha.conf)

[3. 启动服务](#3. 启动服务)

[4. 客户端挂载](#4. 客户端挂载)

[CephFS 配额(Quota)](#CephFS 配额(Quota))

一、CephFS 概述

CephFS 是 Ceph 提供的文件存储接口,类似 NFS,多台客户端可以同时挂载读写同一个目录,支持 POSIX 标准文件操作。

架构特点

  • 元数据分离 :文件元数据(文件名、权限、目录结构)存放在独立的 cephfs-metadata 池中,基于多副本保证高可用

  • MDS 缓存:专用 MDS 服务器在内存中缓存元数据,提升读写响应速度

  • 数据分离 :实际文件内容存放在 cephfs-data 池中

数据读写流程

  • 读数据:客户端请求 MDS → MDS 从 metadata 池加载元数据缓存到内存 → 返回给客户端 → 客户端直接去 OSD 读数据

  • 写数据:客户端请求 MDS → MDS 缓存元数据并同步到 metadata 池 → 客户端数据写入 data 池

二、部署 MDS 服务
1. 安装 MDS

Ubuntu:

复制代码
 apt-cache madison ceph-mds
 apt install ceph-mds=16.2.5-1bionic

CentOS:

复制代码
 yum install ceph-mds -y
2. 部署 MDS 节点
复制代码
 ceph-deploy mds create ceph-mgr1
3. 验证 MDS 状态
复制代码
 ceph mds stat
 # 初始输出:, 1 up:standby   (备用状态,需分配存储池后才变为 active)
三、创建存储池并初始化文件系统
复制代码
 # 1. 创建元数据池(存文件名、权限等)
 ceph osd pool create cephfs-metadata 32 32
 ​
 # 2. 创建数据池(存实际文件内容)
 ceph osd pool create cephfs-data 64 64
 ​
 # 3. 创建文件系统
 ceph fs new mycephfs cephfs-metadata cephfs-data
 ​
 # 4. 验证
 ceph fs ls                    # 列出所有文件系统
 ceph mds stat                 # 状态变为 active
 # 输出:mycephfs-1/1/1 up {0=ceph-mgr1=up:active}
 ceph fs status mycephfs       # 查看指定文件系统运行状态
四、创建客户端账户与认证文件
1. 创建普通用户(推荐,不要直接用 admin)
复制代码
 ceph auth add client.yanyan mon 'allow r' mds 'allow rw' osd 'allow rwx pool=cephfs-data'

权限说明

  • mon 'allow r':允许读取 Monitor(查看集群状态)

  • mds 'allow rw':允许通过 MDS 读写文件

  • osd 'allow rwx pool=cephfs-data':只允许操作数据池,不能碰其他池

2. 验证账户
复制代码
 ceph auth get client.yanyan
3. 导出认证文件
复制代码
 # 导出完整 keyring 文件
 ceph auth get client.yanyan -o ceph.client.yanyan.keyring
 ​
 # 仅导出密钥字符串(用于 mount 命令的 secret 参数)
 ceph auth print-key client.yanyan > yanyan.key
 ​
 # 查看内容
 cat ceph.client.yanyan.keyring
五、客户端安装与配置
1. 安装客户端软件
复制代码
 yum install epel-release -y
 yum install https://mirrors.aliyun.com/ceph/rpm-octopus/el7/noarch/ceph-release-1-1.el7.noarch.rpm -y
 yum install ceph-common -y
2. 同步认证文件到客户端
复制代码
 scp ceph.conf ceph.client.yanyan.keyring yanyan.key root@172.31.6.203:/etc/ceph/
3. 验证权限
复制代码
 ceph --user yanyan -s

能正常显示集群状态即表示认证成功。

六、客户端挂载 CephFS
方式一:内核空间挂载(推荐,性能好)

通过 key 文件挂载

复制代码
 mkdir /data
 mount -t ceph 172.31.6.104:6789,172.31.6.105:6789,172.31.6.106:6789:/ /data -o name=yanyan,secretfile=/etc/ceph/yanyan.key

通过 key 字符串挂载

复制代码
 mount -t ceph 172.31.6.104:6789,172.31.6.105:6789,172.31.6.106:6789:/ /data -o name=yanyan,secret=密钥字符串

测试读写

复制代码
 cp /etc/issue /data/
 dd if=/dev/zero of=/data/testfile bs=1M count=100

查看挂载状态

复制代码
 stat -f /data/
 # Type 显示为 ceph 即成功

开机自动挂载

编辑 /etc/fstab

复制代码
 172.31.6.104:6789,172.31.6.105:6789,172.31.6.106:6789:/ /data ceph defaults,name=yanyan,secretfile=/etc/ceph/yanyan.key,_netdev 0 0

验证配置:

复制代码
 mount -a
方式二:用户空间挂载(ceph-fuse,兼容性好)
安装 ceph-fuse
复制代码
 yum install ceph-fuse -y

挂载

复制代码
 mkdir /data
 ceph-fuse --name client.yanyan -m 172.31.6.104:6789,172.31.6.105:6789,172.31.6.106:6789 /data

开机自动挂载

编辑 /etc/fstab

复制代码
 none /data fuse.ceph ceph.id=yanyan,ceph.conf=/etc/ceph/ceph.conf,_netdev,defaults 0 0
两种挂载方式对比
挂载方式 命令 性能 依赖
内核挂载 mount -t ceph 需内核支持 ceph 模块
用户空间挂载 ceph-fuse 稍低 只需安装 ceph-fuse
CephFS 通过 NFS-Ganesha 导出

当前 CephFS 章节只讲了本地挂载,补充 NFS 导出可以让非 Linux 客户端或无法安装 ceph 模块的机器也能访问。

1. 安装
复制代码
 apt install nfs-ganesha-ceph -y   # Ubuntu
2. 配置 /etc/ganesha/ganesha.conf
复制代码
 cat > /etc/ganesha/ganesha.conf << 'EOF'
 NFS_CORE_PARAM {
     Enable_NLM = false;        # 关闭文件锁(兼容问题)
     Enable_RQUOTA = false;     # 关闭配额报告
     Protocols = 4;             # 只用 NFSv4
 }
 ​
 EXPORT_DEFAULTS {
     Access_Type = RW;          # 默认读写权限
 }
 ​
 EXPORT {
     Export_Id = 1;             # 导出编号,多个导出要不重复
     Path = "/";                # 把 CephFS 的根目录共享出去
     FSAL {
         name = CEPH;           # 告诉 Ganesha 后端是 CephFS
         hostname = "172.31.6.104";  # 你的 MON 节点 IP 之一
     }
     Squash = "No_root_squash";  # 允许客户端 root 保持 root 权限
     Pseudo = "/magedu";        # 客户端挂载时看到的路径名
     SecType = "sys";           # 使用系统用户认证
 }
 ​
 LOG {
     Default_Log_Level = WARN;  # 日志级别
 }
 EOF
 ​
 Path = "/":把 CephFS 的根目录共享出去,也可以改成 /data 等子目录。
 Pseudo = "/magedu":客户端挂载时用的 NFS 路径,比如 mount -t nfs 服务器IP:/magedu /本地目录。
 hostname:填你 Ceph 集群 MON 节点的 IP,Ganesha 会通过它连接 Ceph 集群。
3. 启动服务
复制代码
 systemctl restart nfs-ganesha
4. 客户端挂载
复制代码
 mount -t nfs 172.31.6.104:/magedu /data
 ​
 Windows 客户端:
 打开“此电脑” → 映射网络驱动器
 文件夹填 \\172.31.6.104\magedu
 完成,就能在 Windows 里直接读写 CephFS 的文件。
CephFS 配额(Quota)

CephFS 支持对目录设置容量或文件数限制,便于多租户隔离。

复制代码
 # 设置容量限制
 setfattr -n ceph.quota.max_bytes -v 10737418240 /mnt/cephfs/dir
 ​
 setfattr:设置文件扩展属性(extended attributes),Linux 文件系统都支持这个机制。
 -n ceph.quota.max_bytes:要设置的属性名,CephFS 定义的特殊属性,表示“最大字节数”。
 -v 10737418240:属性值,单位是字节,这里是 10GB(10 × 1024 × 1024 × 1024)。
 /mnt/cephfs/dir:要限制的目录路径(这个目录必须已经存在)
 ​
 # 设置文件数限制
 setfattr -n ceph.quota.max_files -v 10000 /mnt/cephfs/dir
 ​
 # 查看配额
 getfattr -n ceph.quota.max_bytes /mnt/cephfs/dir
 ​
复制代码
  研发组在 /data/rd 里放了一个 6GB 的大文件
 dd if=/dev/zero of=/data/rd/bigfile bs=1G count=6
 # 写到最后会报错:Disk quota exceeded

MDS 高可用配置

[1. 为什么要高可用?](#1. 为什么要高可用?)

[2. 添加更多 MDS 节点](#2. 添加更多 MDS 节点)

[3. 设置活跃主节点数量](#3. 设置活跃主节点数量)

[4. 配置专属备节点(可选但推荐)](#4. 配置专属备节点(可选但推荐))

[5. 分发配置并重启](#5. 分发配置并重启)

[6. 验证](#6. 验证)

1. 为什么要高可用?

MDS 是 CephFS 的元数据管家,如果只有一台 MDS,它一挂,所有客户端都无法找到文件,CephFS 整个瘫痪。

2. 添加更多 MDS 节点
复制代码
 # 在新增节点上安装
 apt install ceph-mds -y
 ​
 # 部署
 ceph-deploy mds create ceph-mgr2
 ceph-deploy mds create ceph-mon2
 ceph-deploy mds create ceph-mon3
3. 设置活跃主节点数量
复制代码
 # 设置最多 2 个主 MDS 同时工作
 ceph fs set mycephfs max_mds 2

此时 4 个 MDS 中,2 个变 active(主),2 个变 standby(备)。

4. 配置专属备节点(可选但推荐)

编辑 ceph.conf

复制代码
 [mds.ceph-mgr2]
 mds_standby_for_name = ceph-mgr1      # 只给 ceph-mgr1 当备胎
 mds_standby_replay = true             # 实时同步主节点元数据
 ​
 [mds.ceph-mon3]
 mds_standby_for_name = ceph-mon2
 mds_standby_replay = true

关键参数解释

  • mds_standby_for_name:指定专属备份哪个主 MDS

  • mds_standby_replay = true:备节点内存中实时保持元数据副本,主挂了毫秒级切换

5. 分发配置并重启
复制代码
 ceph-deploy --overwrite-conf config push ceph-mgr1 ceph-mgr2 ceph-mon2 ceph-mon3
 systemctl restart ceph-mds@ceph-mgr1.service
 systemctl restart ceph-mds@ceph-mgr2.service
 systemctl restart ceph-mds@ceph-mon2.service
 systemctl restart ceph-mds@ceph-mon3.service
6. 验证
复制代码
 ceph fs status
 ceph fs get mycephfs

RGW 对象存储

[什么是 RGW?](#什么是 RGW?)

[部署 RGW 服务](#部署 RGW 服务)

[创建 RGW 用户与认证](#创建 RGW 用户与认证)

[Bucket 核心概念](#Bucket 核心概念)

[客户端工具 s3cmd](#客户端工具 s3cmd)

s3cmd常用命令

[RGW 高可用](#RGW 高可用)

[HTTPS 配置](#HTTPS 配置)

常用管理命令

[Bucket 版本控制](#Bucket 版本控制)

生命周期规则

两个功能组合使用的场景

[总结对比 Ceph 三种存储](#总结对比 Ceph 三种存储)

什么是 RGW?

RGW(RADOS Gateway)提供 RESTful API 接口,客户端通过 HTTP 与 Ceph 交互,完成数据的上传、下载、删除等操作。兼容 S3 和 Swift 协议,适合图片、视频、备份归档等场景。

如果用 RBD(块存储)或 CephFS(文件存储),可以不启用 RGW。

部署 RGW 服务
复制代码
 # 1. 安装软件
 apt install -y radosgw
 ​
 # 2. 部署 RGW
 ceph-deploy --overwrite-conf rgw create ceph-mgr1
 ​
 # 3. 验证进程
 ps aux | grep radosgw

RGW 自动创建的存储池

部署完成后,ceph osd pool ls 会多出以下池:

存储池 作用
.rgw.root RGW 根配置(zone 等)
default.rgw.control 控制信息,通知其它 RGW 更新缓存
default.rgw.meta 元数据:用户信息、Bucket 映射、密钥等
default.rgw.log 各类操作日志
default.rgw.buckets.index Bucket 到对象的索引
default.rgw.buckets.data 实际对象数据,默认三副本
创建 RGW 用户与认证
复制代码
 # 创建用户
 radosgw-admin user create --uid="user1" --display-name="user1"
 # 输出 access_key 和 secret_key,供客户端使用
 ​
 # 创建只读用户
 radosgw-admin user create --uid="readonly" --display-name="readonly" --max-buckets=0
 # 修改用户配额
 radosgw-admin quota set --quota-scope=user --uid=user1 --max-size=10G
 radosgw-admin quota set --quota-scope=user --uid=user1 --max-objects=10000

用户权限基于 Bucket,可设置 readwritereadwritefull-control

Bucket 核心概念
  • Bucket 是存储对象的容器,扁平结构,不可嵌套。

  • 只能包含小写字母、数字、短横线 -

  • 必须以小写字母或数字开头和结尾

  • 长度 3-63 字节

  • 不能使用 IP 地址格式

  • 可设置访问控制、生命周期、跨域等。

客户端工具 s3cmd

安装与配置

复制代码
 apt install s3cmd -y
 s3cmd --configure
 ​
 Access Key: JIJX25OFEJ40JEBECDZV
 Secret Key: vBa23pj4AhGk9GPeSrhL9NLaldShudVfjQ4AC90E
 Default Region [US]:  (直接回车)
 S3 Endpoint [s3.amazonaws.com]: rgw.magedu.net:9900
 DNS-style bucket+hostname:port template: rgw.magedu.net:9900/%(bucket)s
 Encryption password: (回车跳过)
 Path to GPG program [/usr/bin/gpg]: (回车)
 Use HTTPS protocol [Yes]: No
 Test access with supplied credentials? [Y/n] y
 Save settings? [y/N] y
 ​
 # 输入 Access Key、Secret Key、Endpoint(如 rgw.magedu.net:9900)
s3cmd常用命令
复制代码
 s3cmd mb s3://mybucket               # 创建 Bucket
 s3cmd put file.jpg s3://mybucket/    # 上传文件
 s3cmd ls s3://mybucket/              # 列出对象
 s3cmd get s3://mybucket/file.jpg /local/   # 下载
 s3cmd rm s3://mybucket/file.jpg      # 删除对象
 s3cmd rb s3://mybucket               # 删除空 Bucket
RGW 高可用

部署多台 RGW(至少两台),使用 HAProxy 做 TCP 反向代理: 转发 443 到后端 9443

复制代码
 listen ceph-rgw
     bind 172.31.6.201:80
     mode tcp
     server rgw1 172.31.6.104:9900 check
     server rgw2 172.31.6.105:9900 check
 ​
 listen ceph-rgw-https
     bind 172.31.6.201:443
     mode tcp
     server rgw1 172.31.6.104:9443 check
     server rgw2 172.31.6.105:9443 check

客户端访问 VIP,实现故障转移。

复制代码
 # 在客户端挂载或测试时,停掉其中一台 RGW
 systemctl stop ceph-radosgw@rgw.ceph-mgr1
 ​
 # 客户端继续上传下载,服务不中断
 s3cmd put test.jpg s3://mybucket/
 ​
 # 恢复
 systemctl start ceph-radosgw@rgw.ceph-mgr1
HTTPS 配置

生成自签名证书

复制代码
 mkdir /etc/ceph/certs
 cd /etc/ceph/certs
 openssl genrsa -out civetweb.key 2048
 openssl req -new -x509 -key civetweb.key -out civetweb.crt -subj "/CN=rgw.magedu.net"
 cat civetweb.key civetweb.crt > civetweb.pem

修改 ceph.conf

复制代码
 [client.rgw.ceph-mgr1]
 rgw_frontends = "civetweb port=9900+9443s ssl_certificate=/etc/ceph/certs/civetweb.pem"

重启服务后,通过 https://rgw.magedu.net:9443 访问。负载均衡器可相应转发 443 端口。

常用管理命令
命令 说明
radosgw-admin user list 列出所有用户
radosgw-admin bucket list 列出所有 Bucket
radosgw-admin bucket stats --bucket=xxx 查看 Bucket 统计
radosgw-admin usage show --uid=user1 查看用户用量
ceph osd pool ls 查看 RGW 相关存储池
radosgw-admin user info --uid=user1 查看用户详细信息
radosgw-admin user modify --uid=user1 --max-buckets=20 修改用户属性
radosgw-admin bucket list --uid=user1 查看某用户的所有 Bucket
Bucket 版本控制

默认情况下,如果你往 Bucket 里上传了一个同名文件,旧文件会被直接覆盖,再也找不回来

开启版本控制后,每次上传同名文件,Ceph 不会删除旧文件,而是给它打上一个版本号保留起来。你可以随时找回任意一个历史版本。

类比

就像 Word 文档的"修订历史",你改了 10 次,每次的版本都留着,随时可以恢复到 3 天前那个版本。

开启版本控制

复制代码
 s3cmd setbucketversioning s3://mybucket enabled

验证是否开启

复制代码
 s3cmd info s3://mybucket

输出里会看到 Versioning: Enabled

实际效果演示

复制代码
 # 1. 上传第一个版本
 echo "版本1的内容" > test.txt
 s3cmd put test.txt s3://mybucket/
 ​
 # 2. 修改后再次上传(覆盖)
 echo "版本2的内容" > test.txt
 s3cmd put test.txt s3://mybucket/
 ​
 # 3. 再次修改上传
 echo "版本3的内容" > test.txt
 s3cmd put test.txt s3://mybucket/
 ​
 # 4. 查看所有版本
 s3cmd ls --list-md5 s3://mybucket/test.txt

你会发现虽然只有一个文件 test.txt,但它保留了三个历史版本。你可以指定某个版本下载回来。

关闭版本控制(不再保留新版本,但旧版本还在):

复制代码
 s3cmd setbucketversioning s3://mybucket suspended
生命周期规则

自动清理 Bucket 里的旧文件,节省存储空间。比如"只要超过 90 天的文件,自动删除"。

你不需要手动去删,Ceph 会定时检查并执行。

类比

就像手机相册的"自动清理 30 天前的截图",到时间了系统自己删。

第一步:写一个 XML 规则文件

创建一个 lifecycle.xml 文件,内容如下:

复制代码
 <LifecycleConfiguration>
   <Rule>
     <ID>delete-old-files</ID>          <!-- 规则名字,随便起 -->
     <Filter></Filter>                   <!-- 作用于 Bucket 内所有文件 -->
     <Status>Enabled</Status>            <!-- 启用这条规则 -->
     <Expiration>
       <Days>90</Days>                   <!-- 超过 90 天的文件自动删除 -->
     </Expiration>
   </Rule>
 </LifecycleConfiguration>

参数解释

  • <ID>:给这条规则起个名字,方便以后管理

  • <Filter>:过滤条件,空的表示对 Bucket 里所有文件 生效。也可以指定前缀,比如 <Prefix>logs/</Prefix> 表示只对 logs/ 目录下的文件生效

  • <Days>90</Days>:文件创建后超过 90 天就自动删除

第二步:应用规则到 Bucket

复制代码
 s3cmd setlifecycle lifecycle.xml s3://mybucket

第三步:验证规则是否生效

复制代码
 s3cmd getlifecycle s3://mybucket

会输出刚才设置的 XML 内容。

删除生命周期规则

复制代码
 s3cmd dellifecycle s3://mybucket
两个功能组合使用的场景

假设你的监控系统每天产生大量截图,上传到 s3://monitor-screenshots

  1. 开启版本控制:防止有人误删或覆盖重要截图

  2. 设置生命周期:90 天前的截图自动删除,不然磁盘很快就满了

这样既安全又省空间。

总结对比 Ceph 三种存储
存储类型 访问方式 典型场景
RBD 映射为本地磁盘,格式化挂载 虚拟机磁盘、数据库
CephFS mount 成目录,POSIX 操作 共享文件系统
RGW HTTP API(S3/Swift) 对象存储、网盘、备份

Ceph 集群运维

一、通过套接字进行单机管理

二、集群的停止与重启

三、添加服务器

[四、删除 OSD 或服务器](#四、删除 OSD 或服务器)

[五、Ceph 配置文件(ceph.conf)](#五、Ceph 配置文件(ceph.conf))

[六、Ceph Dashboard 开启与使用](#六、Ceph Dashboard 开启与使用)

[七、存储池、PG 与 CRUSH 核心概念](#七、存储池、PG 与 CRUSH 核心概念)

一、两种存储池类型

二、副本池读写流程

[三、PG 与 PGP](#三、PG 与 PGP)

[四、PG 数量计算(重要)](#四、PG 数量计算(重要))

[五、验证 PG 分布](#五、验证 PG 分布)

[八、CRUSH map 手动编辑与自定义规则](#八、CRUSH map 手动编辑与自定义规则)

[最简单的方法(不用手写 map)](#最简单的方法(不用手写 map))

[手动编辑 map 的流程(机架感知等复杂场景)](#手动编辑 map 的流程(机架感知等复杂场景))

九、常见故障诊断命令速查

十、性能基准测试命令

一、通过套接字进行单机管理

什么是套接字(Socket)管理? 每个 Ceph 服务(OSD、MON)启动后,会在 /var/run/ceph/ 下生成一个 .asok 文件,管理员可以通过这个文件直接和本机上的单个守护进程交互,不经过集群网络。

查看套接字文件

复制代码
 # OSD 节点
 ll /var/run/ceph/
 # 输出:ceph-osd.0.asok, ceph-osd.1.asok ...
 ​
 # MON 节点
 ll /var/run/ceph/
 # 输出:ceph-mon.mon01.asok ...

使用方式

复制代码
 ceph --admin-socket /var/run/ceph/ceph-osd.0.asok --help

常用操作

复制代码
 # 查看 MON 状态  输出这个 MON 节点的内部状态
 ceph --admin-daemon /var/run/ceph/ceph-mon.mon01.asok mon_status
   
 # 查看当前配置    这个进程当前生效的全部配置参数
 ceph --admin-daemon /var/run/ceph/ceph-mon.mon01.asok config show

这种管理方式不依赖集群网络,当集群异常时仍可操作本机进程。

二、集群的停止与重启

核心原则 :关闭前设置 noout,防止 OSD 被踢出导致数据无谓迁移。

关闭顺序(从外到内):

复制代码
 # 1. 设置 noout
 ceph osd set noout    t #关闭服务前设置 noout noout is set
 ​
 # 2. 停止客户端(断开挂载、映射)
 # 3. 停止 RGW(如使用)
 # 4. 停止 CephFS MDS
 # 5. 停止 OSD
 # 6. 停止 MGR
 # 7. 停止 MON

启动顺序(从内到外):

复制代码
 # 1. 启动 MON
 # 2. 启动 MGR
 # 3. 启动 OSD
 # 4. 启动 MDS
 # 5. 启动 RGW
 # 6. 启动客户端
 # 7. 取消 noout
 ceph osd unset noout
三、添加服务器
复制代码
 # 1. 配置软件源
 # 2. 安装 Ceph 软件
 ceph-deploy install --release pacific 新节点名
 ​
 # 3. 擦除磁盘
 ceph-deploy disk zap 新节点名 /dev/sdb
 ​
 # 4. 创建 OSD
 ceph-deploy osd create 新节点名 --data /dev/sdb
四、删除 OSD 或服务器

删除单个 OSD

复制代码
 # 1. 踢出集群
 ceph osd out 1
 ​
 # 2. 等待数据迁移完成
 ​
 # 3. 停止进程
 systemctl stop ceph-osd@1
 ​
 # 4. 删除 OSD
 ceph osd rm 1

删除整台服务器

复制代码
 # 1. 逐一把该主机所有 OSD 按上述步骤删除
 # 2. 从 CRUSH 移除主机
 ceph osd crush rm 主机名

五、Ceph 配置文件(ceph.conf)

加载优先级(从高到低):

复制代码
 1. $CEPH_CONF 环境变量
 2. -c 参数指定的位置
 3. /etc/ceph/ceph.conf
 4. ~/.ceph/ceph.conf
 5. ./ceph.conf

配置段

段名 作用 示例
[global] 全局配置 fsidmon_host
[osd] 所有 OSD 通用 也可写 [osd.1] 指定单个
[mon] 所有 MON 通用 也可写 [mon.mon01] 指定单个
[client] 客户端配置 挂载、映射默认参数
六、Ceph Dashboard 开启与使用

Ceph Dashboard 是一个 Web 管理界面 ,打开浏览器就能看到集群状态、存储用量、OSD 健康度、性能曲线。不用每次都敲 ceph -s

复制代码
 # 启用 dashboard 模块  在 active MGR 节点上加载 dashboard 模块
 ceph mgr module enable dashboard
 ​
 # 创建自签名证书
 ceph dashboard create-self-signed-cert
 ​
 # 创建管理员用户
 ceph dashboard ac-user-create admin <password> administrator
 admin:用户名
 密码:自己设置
 administrator:角色,表示管理员权限
 ​
 # 查看访问地址
 ceph mgr services
 {
     "dashboard": "https://172.31.6.104:8443"
 }

浏览器访问 https://<mgr-ip>:8443 即可。如果打不开

  • 确认 MGR 节点 IP 是对的

  • 确认防火墙允许 8443 端口

  • 确认 ceph mgr stat 显示有 active MGR

七、存储池、PG 与 CRUSH 核心概念
一、两种存储池类型
类型 原理 冗余方式 磁盘占用 适用场景
副本池(replicated) 一主多备,默认 3 副本 1 份数据存 3 份 3 倍 RBD、CephFS、RGW 均支持
纠删码池(erasure code) 数据分块 + 校验块,如 8+4 12 块中允许坏 4 块 1.5 倍 默认仅 RGW 可用;从 Luminous**(v12.2.x,2017年发布)** 版本起,开启 allow_ec_overwrites 后 RBD 和 CephFS 也可使用(元数据需存放于副本池)

纠删码参数解读

  • k=2:数据块数,对象被切成 k 份

  • m=2:校验块数,最多允许坏 m 个 OSD

  • 默认配置 k=2, m=2,生产常用 k=8, m=4

  • 优点:节省磁盘空间(3 副本需要 300% 空间,8+4 只需 150%)

  • 缺点:读写时要编解码计算,CPU 开销更高

创建纠删码池示例

复制代码
 ceph osd pool create erasure-testpool 16 16 erasure
 ceph osd erasure-code-profile get default
 rados put -p erasure-testpool testfile1 /var/log/syslog
 rados get -p erasure-testpool testfile1 /tmp/testfile1
二、副本池读写流程

读数据(只读主 OSD)

复制代码
 客户端 → 主 OSD → 从本地磁盘读 → 返回数据

写数据(主 OSD 协调,等所有副本写完才确认)

复制代码
 客户端 → 主 OSD → 同时发给副本 OSD1、OSD2
                 → 副本写完回复主 OSD
                 → 主 OSD 回复客户端"写完"

纠删码读写

  • :主 OSD 先把数据编码成 k+m 个块,再分发写入各 OSD

  • :从各 OSD 收集数据块后解码还原;有块丢失时自动用校验块重建

三、PG 与 PGP

PG(归置组 Placement Group)

  • 存储池的虚拟子单元,夹在对象和 OSD 之间

  • 对象先映射到 PG,PG 再映射到 OSD

  • 好处:数据迁移以 PG 为单位,效率高

PGP(PG for Placement)

  • PG 到 OSD 的组合排列关系

  • 创建池时通常 PG = PGP

数据定位全流程

复制代码
 对象 → (哈希) → PG → (CRUSH 算法) → 具体 OSD
四、PG 数量计算(重要)

核心公式

复制代码
 总 PG 数 = (OSD 总数 × 100) ÷ 副本数
 单池 PG = 总 PG 数 ÷ 存储池数量 → 取最接近的 2 的 N 次幂

计算示例:100 个 OSD,3 副本,5 个存储池

复制代码
 总 PG = 100 × 100 ÷ 3 ≈ 3333
 单池 PG = 3333 ÷ 5 ≈ 666 → 取 512

数量参考

集群规模 每 OSD 建议 PG 数
< 50 个 OSD 100-150
> 50 个 OSD 50-100
大型集群 100-200

关键约束

  • PG 数必须是 2 的 N 次幂(8、16、32、64、128、256、512...)

  • 每个 OSD 的 PG 不超过 250 个

  • PG 太少:数据分布不均,同步时网络负载集中

  • PG 太多:CPU 和内存开销过大


五、验证 PG 分布
复制代码
 # 查看某池的 PG 状态
 ceph pg ls-by-pool mypool | awk '{print $1,$2,$15}'
 ​
 # 查看所有 PG 状态
 ceph pg stat

awk '{print $1,$2,$15}' 输出各列含义:

  • $1:PG ID

  • $2:对象数量

  • $15:该 PG 分布在哪些 OSD 上(ACTING 列)

八、CRUSH map 手动编辑与自定义规则

场景:

你有 4 台存储节点,每台上面插了 1 块 SSD (480G)和 2 块 HDD(2T)。现在你想实现:

  • 高性能池 ssd-pool 的数据只存到 SSD 上

  • 备份池 backup-pool 的数据只存到 HDD 上

最简单的方法(不用手写 map)
复制代码
 # 1. 创建一条仅选 SSD 的规则
 ceph osd crush rule create-replicated ssd_rule default host ssd
 ​
 # 2. 创建存储池时指定这条规则
 ceph osd pool create ssd-pool 32 32 ssd_rule
 ​
 - `ssd_rule`:规则名字,自己起
 - `default`:从哪个 root 开始(默认的就行)
 - `host`:故障域级别,保证同一数据的不同副本在不同主机上
 - `ssd`:设备类别,只选标记为 SSD 的 OSD

这条命令执行完,ssd-pool 里的数据就只会落在 SSD 上。

手动编辑 map 的流程(机架感知等复杂场景)

如果上面的命令行方式满足不了(比如你要机架感知),才需要手动编辑:

复制代码
 # 1. 导出当前 CRUSH map
 ceph osd getcrushmap -o /tmp/crush.bin
 ​
 # 2. 转为可编辑文本
 crushtool -d /tmp/crush.bin -o /tmp/crush.txt
 ​
 # 3. 用 vim 编辑
 vim /tmp/crush.txt

文本文件里的结构你可以理解为四个部分:

a) 设备清单(devices):列出所有 OSD

复制代码
 device 0 osd.0 class ssd    # ← class 决定它属于 ssd 还是 hdd
 device 1 osd.1 class hdd
 device 2 osd.2 class hdd

b) 类型定义(types):不用改

c) 桶(bucket):把 OSD 按物理拓扑组织

复制代码
 host store01 {              # 一台主机叫 store01
     item osd.0 weight 0.48  # 里面放这块 SSD
     item osd.1 weight 1.95  # 和这块 HDD
     item osd.2 weight 1.95
 }
 host store02 { ... }
 root default {              # 所有主机的总集合
     item store01 weight ...
     item store02 weight ...
 }

d) 规则(rule):定义怎么选 OSD

复制代码
 rule ssd_rule {
     id 10
     type replicated
     step take default       # 从 default 这个 root 开始
     step chooseleaf firstn 0 type host  # 选不同主机,每个主机选一个 OSD
     step emit
 }

编辑完后

复制代码
 # 4. 转回二进制
 crushtool -c /tmp/crush.txt -o /tmp/crush-new.bin
 ​
 # 5. 导入(立即生效,危险!)
 ceph osd setcrushmap -i /tmp/crush-new.bin
 ​
 # 6. 验证
 ceph osd crush rule ls
 ceph osd pool create test-pool 32 32 ssd_rule

实际上如果你只是想分 SSD/HDD,用第一段里的命令行方式就够了,不用手动写 map。

九、常见故障诊断命令速查
复制代码
 ceph health detail                 # 查看健康详情
 ceph pg dump_stuck inactive        # 卡住的 PG
 ceph pg dump_stuck unclean
 ceph pg dump_stuck stale
 ceph daemon osd.X status           # 某 OSD 实时状态
 ceph pg <pgid> query               # 某 PG 详细信息
 ceph log last 50                   # 最近集群日志
 ceph osd perf                      # 各 OSD 延迟
十、性能基准测试命令
复制代码
 # RADOS 性能测试(写)
 rados bench -p <pool> 10 write --no-cleanup
 ​
 # RADOS 性能测试(读)
 rados bench -p <pool> 10 seq
 ​
 # RBD 性能测试(FIO)
 fio --filename=/dev/rbd0 --rw=randwrite --bs=4k --size=1G ...

PG 状态速查指南

[1. 正常基准状态](#1. 正常基准状态)

[2. 数据同步与恢复状态 (PG内部工作流)](#2. 数据同步与恢复状态 (PG内部工作流))

[3. 降级与警告状态 (影响冗余度,但IO通常不断)](#3. 降级与警告状态 (影响冗余度,但IO通常不断))

[4. 严重故障状态 (导致IO中断)](#4. 严重故障状态 (导致IO中断))

[5. 维护状态](#5. 维护状态)

PG (Placement Group) 是 Ceph 数据分布与管理的核心单元。一个健康的 PG 状态为 active+clean,任何故障都会导致状态变化。

1. 正常基准状态
  • Active: PG 可以正常处理客户端的读写请求。

  • Clean : PG 内的所有副本数据一致,且数量等于存储池设定的副本数(如3副本)。Active+Clean是完美状态。

2. 数据同步与恢复状态 (PG内部工作流)

这类状态通常出现在OSD重启、扩容或故障恢复时,数据正在重新同步。

  • Peering : 正在协商。同一个PG内的OSD正在互相通信,就数据状态达成一致,是恢复流程的第一步。

  • Recovering : 正在增量恢复。基于日志(PGLog)同步少量差异数据。通常OSD短暂离线后会出现。

  • Backfilling : 正在全量恢复。当OSD离线太久,日志无法增量同步时,会从主OSD全量拷贝整个PG数据。数据量大,耗时长。

  • Remapped : 重新映射。CRUSH算法为PG分配了新的OSD组合(如扩容时),数据开始从旧组合迁移到新组合。在此期间,客户端仍由旧组合中的主OSD处理请求,IO不断。

3. 降级与警告状态 (影响冗余度,但IO通常不断)
  • Degraded : 降级状态。PG发现某个副本数据不一致需要修复,或者当前可用的副本数少于规定数量。客户端IO通常不中断,但数据冗余度降低。

  • Undersized : 副本数不足 。当前在线的PG副本数低于存储池设定的 min_size 值。如果 min_size 配置合理,PG仍可处理IO。

  • Stale : 主OSD失联。主OSD没有按时向MON汇报PG状态(网络问题、进程卡死等)。此时,MON无法得知该PG的真实状态。

  • Peered : 已协商,但副本不足 。PG内OSD已完成协商,但由于在线副本数少于 min_size,PG暂时不能响应IO请求,IO会阻塞 。一旦副本数恢复或手动降低 min_size,即可恢复。

4. 严重故障状态 (导致IO中断)
  • Down : 瘫痪状态 。PG检测到在某个关键时期内,在线的OSD数量不足以完成数据修复。通常发生在"数据丢在旧OSD上,且旧OSD离线的同时,其他副本也全挂"的连环故障中。IO会完全阻塞

  • Incomplete : 协商失败 。在Peering过程中,PG发现无法选出权威日志,或选出的OSD组合无法完成数据修复。这通常是灾难性故障的前兆,如多副本同时永久损坏。IO阻塞

  • Inconsistent : 数据不一致。深度清理(Deep Scrub)时,发现副本间的对象数据内容不匹配。这是数据损坏的明确信号,需立即干预。

5. 维护状态
  • Scrubbing / Deep: PG正在执行数据一致性扫描(轻量或深度)。这是正常的后台维护操作,深度扫描时PG会暂时处于此状态。

一句话总结 :处理PG故障时,只要抓住 ActiveClean 两个核心。没了 Active,IO就会挂起没了 Clean,数据冗余度就处于风险中 。结合 ceph -sceph health detail,锁定故障PG,按上述状态逻辑排查,是运维的关键。

数据读写流程与存储池管理

一、数据读写流程

二、存储池管理

[1. 创建存储池](#1. 创建存储池)

[2. 列出存储池](#2. 列出存储池)

[3. 查看存储池统计](#3. 查看存储池统计)

[4. 重命名存储池](#4. 重命名存储池)

[5. 删除存储池](#5. 删除存储池)

[6. 存储池配额](#6. 存储池配额)

[7. 存储池常用参数](#7. 存储池常用参数)

[8. 清理(Scrub)参数](#8. 清理(Scrub)参数)

一、数据读写流程

整体步骤

复制代码
 APP 请求(对象名 + 存储池名)
     ↓
 客户端对对象名做哈希,取模得到 PG 编号
     ↓
 客户端对存储池名做哈希,与 PG 编号组合成完整 PG ID(如 3.23)
     ↓
 客户端从 MON 获取最新 cluster map
     ↓
 CRUSH 算法根据 PG ID + cluster map 计算出主 OSD 和备 OSD
     ↓
 客户端直接向主 OSD 发起读写请求
     ↓(写操作)
 主 OSD 同步数据到备 OSD,全部写完才确认

核心要点

  • 客户端不需要知道对象存哪,全靠 CRUSH 算法实时计算

  • 不需要查中心元数据表,因此无瓶颈、可无限扩展

  • 写操作由主 OSD 协调,等所有副本写完才返回成功

✅ 此流程自 Ceph 诞生至今基本未变,核心原理仍然适用。

二、存储池管理
1. 创建存储池
复制代码
 ceph osd pool create <poolname> <pg_num> <pgp_num> {replicated|erasure}

示例:

复制代码
 ceph osd pool create mypool 32 32

⚠️ 变化提示 :现代 Ceph 已支持 PG 自动扩缩容,创建时给一个初始 PG 数即可,后续集群会自动调整:

复制代码
 ceph osd pool set mypool pg_autoscale_mode on
2. 列出存储池
复制代码
 ceph osd pool ls              # 只显示名称
 ceph osd lspools              # 显示名称和 ID
 ceph osd pool ls detail       # 显示详细信息
3. 查看存储池统计
复制代码
 ceph osd pool stats mypool    # 查看单个池
 rados df                      # 查看所有池用量
4. 重命名存储池
复制代码
 ceph osd pool rename old-name new-name
5. 删除存储池

删除存储池会永久删除所有数据,Ceph 设置了两道防线:

防线一:nodelete 标志(默认为 false,可直接删)

复制代码
 ceph osd pool get mypool nodelete        # 查看
 ceph osd pool set mypool nodelete true   # 禁止删除
 ceph osd pool set mypool nodelete false  # 允许删除

防线二:集群级 mon_allow_pool_delete 参数(默认 false,需临时打开)

复制代码
 # 临时允许删除
 ceph tell mon.* injectargs --mon-allow-pool-delete=true
 ​
 # 执行删除(注意要写两遍存储池名)
 ceph osd pool rm mypool mypool --yes-i-really-really-mean-it
 ​
 # 恢复禁止删除
 ceph tell mon.* injectargs --mon-allow-pool-delete=false
6. 存储池配额

限制存储池的最大空间或对象数量:

复制代码
 # 查看配额
 ceph osd pool get-quota mypool
 ​
 # 限制对象数
 ceph osd pool set-quota mypool max_objects 1000
 ​
 # 限制容量
 ceph osd pool set-quota mypool max_bytes 10737418240   # 10G
7. 存储池常用参数
参数 含义 默认值 查看/设置命令
size 副本数 3 ceph osd pool get mypool size
min_size 最小服务副本数 2 ceph osd pool get mypool min_size
pg_num PG 数量 创建时指定 ceph osd pool get mypool pg_num
crush_rule CRUSH 规则 replicated_rule ceph osd pool get mypool crush_rule
nodelete 禁止删除标志 false ceph osd pool get mypool nodelete
nopgchange 禁止修改 PG 数 false ceph osd pool get mypool nopgchange
nosizechange 禁止修改配额 false ceph osd pool get mypool nosizechange
noscrub 关闭轻量清理 false ceph osd pool get mypool noscrub
nodeep-scrub 关闭深度清理 false ceph osd pool get mypool nodeep-scrub

修改 PG 数量

复制代码
 ceph osd pool set mypool pg_num 64

关闭/开启清理扫描(临时解决高 I/O 问题)

复制代码
 ceph osd pool set mypool noscrub true        # 暂停轻量清理
 ceph osd pool set mypool nodeep-scrub true   # 暂停深度清理
 ceph osd pool set mypool noscrub false       # 恢复
8. 清理(Scrub)参数

Scrub 是 Ceph 的数据一致性检查机制:

参数 默认值 含义
osd_scrub_min_interval 86400 秒(1 天) 轻量清理最小间隔
osd_scrub_max_interval 604800 秒(7 天) 轻量清理最大间隔
osd_deep_scrub_interval 604800 秒(7 天) 深度清理间隔
osd_max_scrubs 1 每个 OSD 同时进行的 scrub 数量

通过套接字查看当前 OSD 的 scrub 配置

复制代码
 ceph daemon osd.3 config show | grep scrub

存储池快照与数据压缩

存储池快照

[1. 创建快照](#1. 创建快照)

[2. 查看快照列表](#2. 查看快照列表)

[3. 回滚对象(基于快照恢复单个文件)](#3. 回滚对象(基于快照恢复单个文件))

[4. 删除快照](#4. 删除快照)

数据压缩

存储池快照

快照用于对存储池中的数据进行备份与还原 。注意:这是存储池级别的快照,与 RBD 映像快照不同。

⚠️ 实际使用提示 :生产环境中更常用的是 RBD 映像快照rbd snap),存储池快照主要用于 rados 对象级别的操作,日常使用场景较少。

1. 创建快照
复制代码
 # 方式一
 ceph osd pool mksnap mypool mypool-snap
 ​
 # 方式二
 rados -p mypool mksnap mypool-snap2
2. 查看快照列表
复制代码
 rados lssnap -p mypool
 1  mypool-snap   2026.4.03 16:12:56
 2  mypool-snap2  2026.4.03 16:13:40
3. 回滚对象(基于快照恢复单个文件)
复制代码
 # 上传文件
 rados -p mypool put testfile /etc/hosts
 ​
 # 创建快照
 ceph osd pool mksnap mypool mypool-snapshot001
 ​
 # 删除文件
 rados -p mypool rm testfile
 ​
 # 从快照回滚该文件
 rados rollback -p mypool testfile mypool-snapshot001
 ​
 # 文件已恢复,可正常操作
 rados -p mypool rm testfile
4. 删除快照
复制代码
 # 删除指定快照
 ceph osd pool rmsnap mypool mypool-snap
 ​
 # 验证
 rados lssnap -p mypool
数据压缩

如果使用 Bluestore 存储引擎,Ceph 支持实时数据压缩 (边压缩边写入),有助于节省磁盘空间。默认不开启压缩。

✅ 此功能在现代 Ceph 中依然有效,配置方式基本不变。

1. 设置压缩算法
复制代码
 ceph osd pool set mypool compression_algorithm snappy

常用算法对比

算法 CPU 消耗 压缩比 推荐场景
snappy 中等 默认推荐,通用场景
lz4 中等 与 snappy 类似
zstd 磁盘空间紧张时
zlib 不推荐,CPU 开销过大
none 关闭压缩
2. 设置压缩模式
复制代码
 ceph osd pool set mypool compression_mode aggressive

模式说明

模式 含义
none 不压缩
passive 仅当写操作带有可压缩提示时才压缩
aggressive 除非写操作带有不可压缩提示,否则都压缩
force 强制压缩,忽略所有提示
3. 查看压缩设置
复制代码
 ceph osd pool get mypool compression_algorithm
 ceph osd pool get mypool compression_mode
4. 压缩相关参数

存储池级别参数

参数 含义 默认值
compression_algorithm 压缩算法 snappy
compression_mode 压缩模式 none
compression_required_ratio 压缩后/压缩前的比值上限 .875

全局参数(配置于 ceph.conf)

参数 含义 默认值
bluestore_compression_algorithm 全局压缩算法 -
bluestore_compression_mode 全局压缩模式 -
bluestore_compression_min_blob_size 小于此值不压缩 0
bluestore_compression_max_blob_size 大于此值拆块后压缩 0
bluestore_compression_min_blob_size_ssd SSD 最小压缩块 8K
bluestore_compression_max_blob_size_ssd SSD 最大压缩块 64K
bluestore_compression_min_blob_size_hdd HDD 最小压缩块 128K
bluestore_compression_max_blob_size_hdd HDD 最大压缩块 512K
5. 在节点上验证压缩配置
复制代码
 ceph daemon osd.11 config show | grep compression
快照 vs 压缩 使用建议
功能 适用场景 注意事项
存储池快照 rados 对象级别回滚 生产更常用 RBD 快照(rbd snap
数据压缩 节省磁盘空间 CPU 与空间之间的权衡,建议 snappy/lz4 + aggressive

CephX 是什么?

二、认证流程

关键设计思想

[CephX 的两个限制](#CephX 的两个限制)

三、访问流程

四、用户类型

五、能力(Capabilities/Caps)

基础能力

[Profile 能力(预定义组合)](#Profile 能力(预定义组合))

六、典型权限示例

七、用户管理命令

[1. 列出所有用户](#1. 列出所有用户)

[2. 查看指定用户](#2. 查看指定用户)

[3. 添加用户](#3. 添加用户)

[4. 修改用户权限](#4. 修改用户权限)

[5. 删除用户](#5. 删除用户)

八、密钥环(Keyring)管理

[1. 导出用户到密钥环文件(备份)](#1. 导出用户到密钥环文件(备份))

[2. 从密钥环文件恢复用户](#2. 从密钥环文件恢复用户)

[3. 合并多个用户到同一个密钥环](#3. 合并多个用户到同一个密钥环)

九、权限配置场景速查

十、命令速查表

CephX 是 Ceph 内置的身份认证和授权协议,所有与 MON 通信的请求都必须通过认证。

两个关键点

  • 可以在 MON 节点关闭认证,但关闭后任何访问都被允许,数据无安全性

  • CephX 只负责认证授权 ,不负责数据加密传输


二、认证流程
复制代码
 客户端 → MON:我有密钥,给我一个 session key
 MON → 客户端:验证通过,返回 session key(用客户端密钥加密)
 客户端 → MON:用 session key 请求服务 ticket
 MON → 客户端:发放 ticket
 客户端 → OSD:出示 ticket
 OSD:MON 和 OSD 共享同一个 secret,信任 MON 发的 ticket,放行
  • ticket 有有效期,过期自动重新发放

  • 多个 MON 节点共同认证,无单点故障和性能瓶颈

关键设计思想
设计点 原因
每个 MON 都能认证 无单点故障,无性能瓶颈
session key 用客户端密钥加密 网络被监听也无法解密
MON 和 OSD 共享 secret OSD 信任 MON 的 ticket,不用每次读写都问 MON
ticket 有有效期 ticket 泄露影响是暂时的
CephX 的两个限制
限制 说明
不能扩展到非 Ceph 组件 只对 Ceph 内部有效,不能认证外部应用
不能加密传输数据 只管"你是谁",不管"数据在路上是否被偷看"

三、访问流程

无论客户端是块设备、对象存储还是文件系统,Ceph 在存储池中把所有数据都存为对象

  • 用户必须有存储池访问权限,才能读写数据

  • 用户必须有执行权限(x) ,才能使用 ceph 管理命令


四、用户类型

Ceph 用户格式:TYPE.ID

类型 说明 示例
client 管理员或应用程序 client.admin
osd OSD 守护进程 osd.0
mds MDS 守护进程 mds.ceph-mgr1
mgr MGR 守护进程 mgr.ceph-mgr1

管理员管理的用户都属于 client 类型。MON/OSD/MDS 是系统组件用户。


五、能力(Capabilities/Caps)

Ceph 通过 caps 描述用户对 MON/OSD/MDS 的授权范围。

语法格式daemon-type 'allow caps' [...]

基础能力
能力 含义
r 读权限(如检索 CRUSH 运行图)
w 写权限(写入对象)
x 执行权限(调用类方法、执行 auth 操作)
* 全部权限(读、写、执行 + 管理命令)
class-read 类读取(x 的子集)
class-write 类写入(x 的子集)
Profile 能力(预定义组合)
Profile 用途
profile osd OSD 间通信、状态上报、心跳检测
profile mds MDS 间通信
profile bootstrap-osd 引导初始化新 OSD
profile bootstrap-mds 引导初始化新 MDS

六、典型权限示例
复制代码
 # admin 用户:全部权限
 [client.admin]
 caps mds = "allow *"
 caps mgr = "allow *"
 caps mon = "allow *"
 caps osd = "allow *"
 ​
 # OSD 用户:OSD 间通信权限
 [osd.10]
 caps mgr = "allow profile osd"
 caps mon = "allow profile osd"
 caps osd = "allow *"
 ​
 # 自定义受限用户:只能读 MON,只能读写 mypool 这个存储池
 [client.tom]
 caps mon = "allow r"
 caps osd = "allow rwx pool=mypool"
七、用户管理命令
1. 列出所有用户
复制代码
 ceph auth list           #查看所有用户的名单及其权限和密钥
 ceph auth list -o output.keyring    # 导出到文件
2. 查看指定用户
复制代码
 ceph auth get client.admin
 ceph auth get osd.10
3. 添加用户
命令 是否创建 返回内容 适用场景
add 必须不存在 无输出 严格新建
get-or-create 不存在则创建 完整 keyring 格式 最常用
get-or-create-key 不存在则创建 只返回密钥字符串 脚本/自动化
print-key 不创建 只返回密钥字符串 查看已有密钥
复制代码
 # 方式一:add(已存在会报错)
 ceph auth add client.tom mon 'allow r' osd 'allow rwx pool=mypool'
 ​
 # 方式二:get-or-create(推荐)
 已存在就直接获取。会输出或导出完整的密钥文件
 ceph auth get-or-create client.jack mon 'allow r' osd 'allow rwx pool=mypool' -o jack.keyring
 ​
 # 方式三:只返回密钥字符串   没有多余信息,很适合在脚本里用
 ceph auth get-or-create-key client.jack mon 'allow r' osd 'allow rwx pool=mypool'
 # 方式四:查看已有用户密钥
 ceph auth print-key client.jack
4. 修改用户权限

注意ceph auth caps完全覆盖,必须同时带上旧权限和新权限。

复制代码
 # 仅查看当前权限
 ceph auth get client.jack
 ​
 # 修改权限(覆盖)
 ceph auth caps client.jack mon 'allow r' osd 'allow rw pool=mypool'
5. 删除用户
复制代码
 ceph auth del client.tom
八、密钥环(Keyring)管理

密钥环文件(.keyring)保存用户的认证信息,客户端需要此文件才能访问 Ceph。

密钥环文件优先级

复制代码
 /etc/ceph/<$cluster>.<type>.<id>.keyring   # 单用户
 /etc/ceph/cluster.keyring                   # 多用户
 /etc/ceph/keyring                           # 多用户
 /etc/ceph/keyring.bin                       # 二进制格式
1. 导出用户到密钥环文件(备份)
复制代码
 # 创建空 keyring 文件
 ceph-authtool --create-keyring ceph.client.user1.keyring
 ​
 ceph-authtool 是一个专门管理密钥环文件的工具。
 --create-keyring 就是让它生成一个新的、空的密钥环文件。
 ceph.client.user1.keyring 是这个文件的文件名,通常命名为 ceph.用户名.keyring,一看就知道是谁的卡。
 ​
 # 导出用户认证信息
 ceph auth get client.user1 -o ceph.client.user1.keyring
 ​
 ceph auth get client.user1 是从 Ceph 集群里查询 client.user1 这个用户的密钥和权限。
 -o ceph.client.user1.keyring 是把查询结果输出并覆盖到第一步创建的文件里。
 ​
 # 验证
 cat ceph.client.user1.keyring
2. 从密钥环文件恢复用户
复制代码
 # 误删用户
 ceph auth del client.user1
 ​
 # 从备份导入恢复
 ceph auth import -i ceph.client.user1.keyring
 ​
 # 验证
 ceph auth get client.user1
3. 合并多个用户到同一个密钥环
复制代码
 # 创建空文件
 ceph-authtool --create-keyring ceph.client.user.keyring
 ​
 # 导入 admin 用户
 ceph-authtool ./ceph.client.user.keyring --import-keyring ./ceph.client.admin.keyring
 ​
 # 再导入其他用户
 ceph-authtool ./ceph.client.user.keyring --import-keyring ./ceph.client.user1.keyring
 ​
 # 查看合并后的内容
 ceph-authtool -l ./ceph.client.user.keyring
九、权限配置场景速查
场景 权限配置
集群管理员 caps mon/osd/mgr/mds = "allow *"
RBD 客户端 caps mon = "allow r" + caps osd = "allow rwx pool=存储池名"
只读监控 caps mon = "allow r" + caps osd = "allow r pool=存储池名"

十、命令速查表
操作 命令
列出所有用户 ceph auth list
查看某用户 ceph auth get client.admin
创建用户 ceph auth get-or-create client.xxx mon 'allow r' osd 'allow rwx pool=xxx'
只获取密钥 ceph auth print-key client.xxx
修改权限 ceph auth caps client.xxx mon 'allow r' osd 'allow rw pool=xxx'
删除用户 ceph auth del client.xxx
导出到文件 ceph auth get client.xxx -o xxx.keyring
从文件导入 ceph auth import -i xxx.keyring
合并 keyring ceph-authtool target.keyring --import-keyring source.keyring

Ceph RBD 使用详解

[一、RBD 概述](#一、RBD 概述)

[二、创建 RBD 存储池](#二、创建 RBD 存储池)

[三、创建与管理 RBD 镜像](#三、创建与管理 RBD 镜像)

[1. 创建镜像](#1. 创建镜像)

[2. 查看镜像详细信息](#2. 查看镜像详细信息)

[3. 镜像特性说明与启用/禁用](#3. 镜像特性说明与启用/禁用)

常见特性

启用特性

禁用特性

[四、客户端挂载 RBD](#四、客户端挂载 RBD)

[1. 安装客户端软件](#1. 安装客户端软件)

[2. 同步认证文件(以 admin 为例)](#2. 同步认证文件(以 admin 为例))

[3. 映射镜像为本地块设备](#3. 映射镜像为本地块设备)

[4. 普通用户挂载示例](#4. 普通用户挂载示例)

五、镜像空间扩容

六、开机自动挂载

七、卸载与删除镜像

[1. 卸载镜像](#1. 卸载镜像)

[2. 删除镜像(谨慎操作)](#2. 删除镜像(谨慎操作))

八、镜像快照管理

[1. 快照命令概览](#1. 快照命令概览)

[2. 创建快照](#2. 创建快照)

[3. 回滚快照](#3. 回滚快照)

[4. 删除快照](#4. 删除快照)

[5. 快照数量限制](#5. 快照数量限制)

[6.RBD 镜像克隆与 flatten](#6.RBD 镜像克隆与 flatten)

用克隆的方法

[为什么需要 flatten](#为什么需要 flatten)

九、验证内核模块

一、RBD 概述

RBD(RADOS Block Device)是 Ceph 提供的块存储 ,可以简单理解为从 Ceph 集群里划分出来的"虚拟硬盘"。它的典型使用场景是:

  • 虚拟机当磁盘(比如 OpenStack、KVM 虚机直接挂载 RBD 镜像当系统盘或数据盘)。

  • 物理服务器或容器 提供额外的持久化存储(通过映射成本地 /dev/rbd 设备,格式化后直接挂载目录使用)。

  • 数据库、中间件等需要裸盘性能快照、克隆、扩容、高可用特性的场景。

它的好处是:

  • 可以随时扩容,不停机增加磁盘大小。

  • 可以快照/回滚,出了问题秒级恢复到某个时间点。

  • 可以克隆,快速复制出一份数据给开发测试。

  • 数据多副本分布在集群里,坏了硬盘也不丢数据。

二、创建 RBD 存储池
复制代码
 # 创建存储池
 ceph osd pool create rbd-data1 32 32
 ​
 # 查看存储池列表
 ceph osd pool ls
 ​
 # 在存储池上启用 RBD 应用
 ceph osd pool application enable rbd-data1 rbd
 ​
 # 初始化 RBD 池
 rbd pool init -p rbd-data1
三、创建与管理 RBD 镜像
1. 创建镜像
复制代码
 # 创建两个镜像:data-img1(3G)和 data-img2(5G)
 rbd create data-img1 --size 3G --pool rbd-data1 --image-format 2 --image-feature layering
 rbd create data-img2 --size 5G --pool rbd-data1 --image-format 2 --image-feature layering
 ​
 ​
 参数说明:
 --image-format 2:使用第二代镜像格式(支持更多高级特性,现在都推荐用 2)。
 --image-feature layering:开启分层快照特性,这样以后才能对镜像做快照,并从快照克隆出新的镜像。
 ​
 创建好之后,它们还不直接能用,需要像挂盘一样映射到客户端、格式化、挂载到目录,然后就能跟本地硬盘一样读写文件了。
 ​
 # 查看镜像列表
 rbd ls --pool rbd-data1
 ​
 # 查看镜像详细信息(含大小、格式等)
 rbd ls --pool rbd-data1 -l
 ​
 # 以 JSON 格式输出
 rbd ls --pool rbd-data1 -l --format json --pretty-format
2. 查看镜像详细信息
复制代码
 rbd --image data-img2 --pool rbd-data1 info
 rbd image 'data-img2':
 size 5 GiB in 1280 objects
 order 22 (4 MiB objects)   #对象大小,每个对象是 2^22/1024/1024=4MiB
 id: d42b6b8b4567     #镜像 id
 block_name_prefix: rbd_data.d42b6b8b4567 #size 里面的 1280 个对象名称前缀
 format: 2 #镜像文件格式版本
 features: layering #特性,layering 支持分层快照以写时复制
 op_features:
 flags:
 create_timestam
3. 镜像特性说明与启用/禁用
常见特性
  • layering:支持分层快照,写时复制(COW)。

  • striping:条带化 V2,提高顺序读写性能。

  • exclusive-lock:独占锁,限制同一镜像仅能被一个客户端使用。

  • object-map:对象映射(依赖独占锁),加速导入导出与空间统计。

  • fast-diff:快速计算镜像与快照差异(依赖 object-map)。

  • deep-flatten:快照扁平化,解除克隆对父镜像的依赖。

  • journaling:日志记录(依赖独占锁),可恢复数据但增加 IO 开销。

启用特性
复制代码
 rbd feature enable exclusive-lock --pool rbd-data1 --image data-img1
 rbd feature enable object-map --pool rbd-data1 --image data-img1
 rbd feature enable fast-diff --pool rbd-data1 --image data-img1
 ​
 # 验证特性已开启
 rbd --image data-img1 --pool rbd-data1 info
禁用特性
复制代码
 rbd feature disable fast-diff --pool rbd-data1 --image data-img1
 ​
 # 验证特性已关闭
 rbd --image data-img1 --pool rbd-data1 info
四、客户端挂载 RBD
1. 安装客户端软件
复制代码
 # 配置 YUM 源
 yum install epel-release
 yum install https://mirrors.aliyun.com/ceph/rpm-octopus/el7/noarch/ceph-release-1-1.el7.noarch.rpm -y
 ​
 # 安装 ceph-common
 yum install ceph-common
2. 同步认证文件(以 admin 为例)
复制代码
 # 从部署节点拷贝认证文件至客户端
 scp ceph.conf ceph.client.admin.keyring root@172.31.6.110:/etc/ceph/
3. 映射镜像为本地块设备
复制代码
 # 若内核不支持某些特性(如 object-map),先禁用
 rbd feature disable rbd-data1/data-img1 object-map
 ​
 # 映射镜像
 rbd -p rbd-data1 map data-img1
 rbd -p rbd-data1 map data-img2
 ​
 #Ceph 集群里的 data-img2 镜像就会自动出现在你本机,成为一个新的块设备  map → 多出设备 → 格式化 → 挂载到目录 → 正常使用
 # 查看映射的设备
 lsblk
4. 普通用户挂载示例

若使用非 admin 用户(如 client.shijie),则需要:

复制代码
 例:
 mkfs.xfs /dev/rbd0
 mkfs.xfs /dev/rbd1
 ​
 # 格式化(ext4 举例)
 mkfs.ext4 /dev/rbd0
 mkdir /data
 mount /dev/rbd0 /data/
 ​
 # 复制文件进行读写测试
 cp /var/log/messages /data/
 ll /data/
 df -TH

管理端可验证锁定状态:

复制代码
rbd ls -p rbd-data1 -l
# LOCK 列显示 excl,表示镜像已被客户端独占锁定
五、镜像空间扩容
复制代码
 # 把 data-img2 这个虚拟磁盘的容量从原来的 5G 直接拉到 8G。
 rbd resize --pool rbd-data1 --image data-img2 --size 8G
 ​
 #虚拟硬盘”的物理容量就变大了,但你的客户端系统还不知道
 # 客户端识别新空间(ext4 文件系统)
 resize2fs /dev/rbd0
 # 若为 xfs 文件系统,使用:
 # xfs_growfs /data/
 ​
 # 查看扩容结果
 fdisk -l /dev/rbd0
六、开机自动挂载

在客户端编辑 /etc/rc.d/rc.local,添加:

复制代码
 rbd --user shijie -p rbd-data1 map data-img2
 mount /dev/rbd0 /data/

赋予执行权限:

复制代码
 chmod a+x /etc/rc.d/rc.local

重启后验证:

复制代码
 rbd showmapped
 df -TH
七、卸载与删除镜像
1. 卸载镜像
复制代码
 # 卸载文件系统并取消映射
 umount /data
 rbd --user shijie -p rbd-data1 unmap data-img2
2. 删除镜像(谨慎操作)

直接删除:

复制代码
 rbd rm --pool rbd-data1 --image data-img1

回收站机制(推荐先移入回收站)

删除的镜像数据无法恢复,但是还有另外一种方法可以先把镜像移动到回收站,后期确认删除的时候再从回收站删除即可。

复制代码
 # 查看镜像状态
 rbd status --pool rbd-data1 --image data-img2
 ​
 # 移入回收站 
 将 data-img2 这个镜像从正常镜像列表里移除,放入池的回收站里。
 rbd trash move --pool rbd-data1 --image data-img2
 ​
 # 查看回收站列表
 rbd trash list --pool rbd-data1
 ​
 # 从回收站还原(需指定镜像 ID)
 rbd trash restore --pool rbd-data1 --image data-img2 --image-id d42b6b8b4567
 ​
 # 确认删除后从回收站永久清除
 rbd trash rm --pool rbd-data1 --image-id <id>
八、镜像快照管理
1. 快照命令概览
复制代码
 snap create (snap add)    # 创建快照
 snap limit set            # 设置快照数量上限
 snap limit clear          # 清除快照数量限制
 snap list (snap ls)       # 列出快照
 snap protect              # 保护快照(防止被删除)
 snap unprotect            # 取消保护
 snap purge                # 删除所有未保护快照
 snap remove (snap rm)     # 删除指定快照
 snap rename               # 重命名快照
 snap rollback (snap revert) # 回滚至某快照
2. 创建快照
复制代码
 rbd snap create --pool rbd-data1 --image data-img2 --snap img2-snap-20251215
 ​
 rbd snap list --pool rbd-data1 --image data-img2
 SNAPID NAME SIZE TIMESTAMP
 4 img2-snap-20251215 8 GiB Tue Dec 
3. 回滚快照
复制代码
 # 客户端需先卸载并取消映射
 umount /data
 rbd unmap /dev/rbd0  #把映射的本地设备 /dev/rbd0 断开
 ​
 # 管理端执行回滚
 rbd snap rollback --pool rbd-data1 --image data-img2 --snap img2-snap-20251215
 ​
 rbd snap rollback   RBD 快照子命令,执行回滚操作
 --pool rbd-data1    指定存储池名称,告诉系统这个镜像在哪个池里
 --image data-img2   指定要回滚的镜像名称,即你要恢复哪个“虚拟磁盘”
 --snap img2-snap-20251215   指定回滚到哪一个快照点,即你要恢复到哪个时间点的状态
 ​
 # 客户端重新映射并挂载验证
 rbd --user shijie -p rbd-data1 map data-img2
 mount /dev/rbd0 /data/
 ll /data/
 ​
 --user shijie   指定连接 Ceph 集群用的认证用户,这里用的是普通用户 client.shijie,而非默认的 admin
 -p rbd-data1    指定存储池名称,与 --pool rbd-data1 等价
 map data-img2   映射操作,把 data-img2 这个镜像挂载到本机,变成 /dev/rbd0(或 rbd1 等)
4. 删除快照
复制代码
 rbd snap remove --pool rbd-data1 --image data-img2 --snap img2-snap-20201215
 rbd snap list --pool rbd-data1 --image data-img2
5. 快照数量限制
复制代码
 # 设置上限
 rbd snap limit set --pool rbd-data1 --image data-img2 --limit 30
 rbd snap limit set --pool rbd-data1 --image data-img2 --limit 20
 rbd snap limit set --pool rbd-data1 --image data-img2 --limit 15
 ​
 # 清除上限
 rbd snap limit clear --pool rbd-data1 --image data-img2
6.RBD 镜像克隆与 flatten

场景:

你们公司要快速部署 50 台云主机的开发环境。传统做法每台云主机都要创建新磁盘、装系统,至少花半小时。

用克隆的方法
  1. 先手工做一个 5G 的 RBD 镜像,装上 CentOS 系统和开发环境。

  2. 给这个镜像打快照并保护:

    复制代码
     rbd snap create mypool/base-img@v1
     rbd snap protect mypool/base-img@v1
  3. 然后批量克隆:

    复制代码
     for i in {1..50}; do
         rbd clone mypool/base-img@v1 mypool/vm-$i
     done

    秒级完成! 因为克隆只是创建一个引用,不实际拷贝数据。

  4. 50 台云主机分别挂载 mypool/vm-1mypool/vm-50,直接开机就能用。

为什么需要 flatten

克隆后的子镜像依赖于父快照,你不能删那个父快照。当你想清理空间时:

复制代码
 rbd flatten mypool/vm-1

执行后 vm-1 就把所有父数据复制一份到自己身上,彻底脱离父子关系。之后父快照可以删除。

九、验证内核模块

挂载 RBD 后,内核自动加载 libceph.ko 模块,可用以下命令验证:

复制代码
 lsmod | grep ceph

K8s 为什么需要 Ceph?

二、理解第一个操作:创建存储池和镜像

三、理解第二个操作:创建用户和权限

[四、理解 K8s 节点上的操作](#四、理解 K8s 节点上的操作)

五、理解两种挂载方式

[方式二:通过 Secret 挂载(推荐)](#方式二:通过 Secret 挂载(推荐))

[base64 编码是干什么的?](#base64 编码是干什么的?)

六、理解"动态存储卷供给"

动态供给是怎么工作的?

[七、理解 MySQL 案例](#七、理解 MySQL 案例)

[八、理解 CephFS 案例](#八、理解 CephFS 案例)

九、整个流程总结

K8s 本身的问题

K8s 是用来管理容器的。容器一重启,里面的数据就没了(容器是无状态的)。但很多应用需要持久化存储,比如:

  • MySQL 数据库的文件不能丢

  • Nginx 的网页文件需要多个容器共享

解决方案

K8s 本身不提供存储,它需要外挂存储。Ceph 就是一个完美的外挂存储:

  • 提供 RBD(块存储)→ 像一块硬盘,只能被一个 Pod 独享

  • 提供 CephFS(文件存储)→ 像 NFS,可以被多个 Pod 同时共享

二、理解第一个操作:创建存储池和镜像
复制代码
 ceph osd pool create laowang-rbd-pool1 32 32
 ceph osd pool application enable laowang-rbd-pool1 rbd
 rbd pool init -p laowang-rbd-pool1
 rbd create laowang-img-img1 --size 3G --pool laowang-rbd-pool1 --image-format 2 --image-feature layering

在 Ceph 集群里准备一块 3GB 的虚拟硬盘,后面给 K8s Pod 用。

每步拆解:

  1. 创建存储池 laowang-rbd-pool1:在 Ceph 里划出一个"区域"

  2. 启用 RBD:声明这个区域是用来存放块设备的

  3. 初始化:让这个池准备好接受 RBD 镜像

  4. 创建镜像 laowang-img-img1:真正创建了一块 3GB 的虚拟硬盘


三、理解第二个操作:创建用户和权限
复制代码
 ceph auth get-or-create client.laowang mon 'allow r' osd 'allow * pool=laowang-rbd-pool1'

创建一个专门给 K8s 用的 Ceph 账号,只允许访问这一个存储池,不能碰其他池。

为什么不用 admin?

admin 是超级管理员,能删所有数据。如果 K8s 里有人搞破坏或配置错误,用 admin 账号可能会把整个 Ceph 集群的数据都毁了。所以创建受限账号最安全。

权限解释:

  • mon 'allow r':只能查看集群状态 客户端地图

  • osd 'allow * pool=laowang-rbd-pool1':只能对 laowang-rbd-pool1 这个池做任何操作,其他池碰不了

四、理解 K8s 节点上的操作

为什么 K8s 节点要装 ceph-common

K8s 节点本身不认识 Ceph。安装 ceph-common 后,节点才能:

  • 识别 rbd 命令

  • 能执行 rbd map 把 Ceph 镜像映射成本地 /dev/rbd0 设备

  • 然后才能把这个设备挂进容器

为什么要同步认证文件?

ceph.conf.keyring 文件就像身份证。K8s 节点拿着它们才能向 Ceph 集群证明"我是合法用户"。

为什么要配主机名解析?

Ceph 集群内部用主机名通信(比如 ceph-mon1)。K8s 节点如果不认识这些名字,就找不到 Ceph 的 MON 节点,也就连不上集群。

五、理解两种挂载方式

方式一:keyring 文件直接挂载

复制代码
 volumes:
 - name: rbd-data1           # 给这个卷起个名字,后面挂载时引用用
   rbd:                      # 指定卷类型为 Ceph RBD(块存储)
     monitors: ['172.31.6.104:6789', ...]   # MON 节点地址,客户端先连这里获取集群地图
     pool: laowang-rbd-pool1               # 存储池名称,虚拟磁盘在这个池里
     image: laowang-img-img1               # RBD 映像名称,就是之前 rbd create 的那个
     user:  client.laowang                 # Ceph 用户名(对应之前 ceph auth get-or-create 创建的)
     keyring: /etc/ceph/ceph.client.laowang.keyring  # 密钥文件在宿主机上的路径

大白话 :Pod 的 YAML 里直接写死了宿主机上的 keyring 文件路径。K8s 创建这个 Pod 时,去宿主机上找这个文件,用来认证,然后把 laowang-img-img1 这块虚拟硬盘挂进容器。

缺点:每台 K8s 节点上都必须放这个 keyring 文件。万一某台节点忘了放,Pod 调度到那台节点上就启动失败。

方式二:通过 Secret 挂载(推荐)
复制代码
 # 第一步:把 key 做成 K8s Secret
 apiVersion: v1
 kind: Secret
 metadata:
   name: ceph-secret-laowang
 type: "kubernetes.io/rbd"
 data:
   key: QVFCNEw3OWcvaGU3SEJBQXZKUTdzSTN6ZFNzVFVMMjFOeDZ6TFE9PQ==
 ---
 # 第二步:Pod 引用 Secret
 volumes:
 - name: rbd-data1
   rbd:
     user: client.laowang
     secretRef:
       name: ceph-secret-laowang-laowang    # 引用了上面创建的 Secret

大白话 :把 Ceph 用户的 key(经过 base64 编码)存成 K8s 的 Secret 对象。Pod 通过 secretRef 引用这个 Secret,K8s 自动把 key 注入到 Pod 的挂载操作中。

优点

  • 不需要在每个节点放 keyring 文件

  • key 只存在 K8s 里,更安全

  • Secret 可以统一管理、更新、轮转

base64 编码是干什么的?

K8s Secret 要求值是 base64 编码的字符串,不是加密,只是把二进制数据转成纯文本。你可以轻松解码:

复制代码
 ceph auth print-key client.laowang
 QVFCNEw3OWcvaGU3SEJBQXZKUTdzSTN6ZFNzVFVMMjFOeDZ6TFE9PQ==
 ​
 echo "QVFCNEw3OWcvaGU3SEJBQXZKUTdzSTN6ZFNzVFVMMjFOeDZ6TFE9PQ==" | base64 -d
 # 输出:AQB4L79g/he7HBAAvJQ7sI3zdSsTUL21Nx6zLQ==(就是原始 key)
六、理解"动态存储卷供给"

静态供给 vs 动态供给

静态供给 动态供给
操作方式 管理员先在 Ceph 手动创建镜像,然后在 YAML 里写死镜像名 用户创建 PVC 声明需要多大空间,K8s 自动去 Ceph 创建镜像
灵活性 差,每新增一个应用都要手工先建镜像 好,按需自动创建
适用场景 固定数量应用 有状态服务(数据库)大量部署
动态供给是怎么工作的?

1. 需要一个 admin Secret

复制代码
 apiVersion: v1
 kind: Secret
 metadata:
   name: ceph-secret-admin
 type: "kubernetes.io/rbd"
 data:
   key: <admin-key-base64>

K8s 需要有创建 RBD 镜像的权限,所以要用 client.admin 的 key(因为 admin 可以创建和删除镜像)。

2. 创建 StorageClass

复制代码
 apiVersion: storage.k8s.io/v1
 kind: StorageClass
 metadata:
   name: ceph-storage-class-laowang          # 模板名称,PVC 引用用这个
 provisioner: kubernetes.io/rbd              # 使用 K8s 内置的 RBD 驱动
 parameters:
   adminId: admin                            # 用 admin 创建/删除镜像
   adminSecretName: ceph-secret-admin        # admin 的密钥存在哪个 Secret
   pool: laowang-rbd-pool1                   # 在哪个 Ceph 池里创建镜像
   userId: laowang-laowang                   # Pod 用这个用户读写
   userSecretName: ceph-secret-laowang-laowang # 普通用户的密钥
字段 含义 值如何得来
provisioner: kubernetes.io/rbd 告诉 K8s 用内置 RBD 驱动动态分配存储 固定写法
adminId: admin 有权限在 Ceph 池里创建镜像的用户 client.admin
adminSecretName admin 用户的密钥存在哪个 K8s Secret 里 上一步创建的 ceph-secret-admin
pool 在哪个 Ceph 存储池里创建镜像 之前 ceph osd pool create laowang-rbd-pool1 创建的那个池
userId: laowang-laowang Pod 实际读写数据时用的 Ceph 用户 之前 ceph auth get-or-create client.laowang 创建的用户
userSecretName 普通用户的密钥存在哪个 Secret 上一步创建的 ceph-secret-laowang-laowang

StorageClass 就像一个模板,定义了"用什么方式创建存储卷"。

3. 用户创建 PVC

复制代码
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
   name: mysql-data-pvc                     # PVC 名称,Pod 引用用这个
 spec:
   accessModes:
   - ReadWriteOnce                          # 只能一个 Pod 读写(块存储限制)
   storageClassName: ceph-storage-class-laowang  # 引用上面的 StorageClass
   resources:
     requests:
       storage: '5Gi'                       # 我要 5GB
字段 含义
kind: PersistentVolumeClaim 资源类型:PVC,表示"我要申请存储"
accessModes: ReadWriteOnce 只能被单个节点上的单个 Pod 以读写方式挂载(RBD 块存储的限制)
storageClassName 引用 StorageClass,告诉 K8s"用这个模板给我创建磁盘"
storage: '5Gi' 申请的磁盘大小,K8s 会自动在 Ceph 里创建一个 5GB 的 RBD 镜像

4. 背后发生了什么

  1. 用户创建 PVC,声明要 5GB

  2. K8s 发现 PVC 指向了 ceph-storage-class-laowang 这个 StorageClass

  3. K8s 用 admin Secret 去连接 Ceph,自动执行 rbd create ... --size 5G

  4. 新创建的 RBD 镜像自动绑定到这个 PVC

  5. 用户在自己的 Pod 里引用这个 PVC,就能用到一块 5GB 的新硬盘

验证:在 Ceph 端能看到自动创建的镜像:

复制代码
 rbd ls --pool laowang-rbd-pool1
 # 会多出一个以 "kubernetes-dynamic-pvc-" 开头的镜像名
七、理解 MySQL 案例
复制代码
 volumes:
 - name: mysql-persistent-storage
   persistentVolumeClaim:
     claimName: mysql-data-pvc    # 引用刚才创建的 PVC

MySQL 的 /var/lib/mysql 目录(存数据库文件的)挂载到了这个 PVC 上。

效果

  • MySQL Pod 写的数据存在 Ceph RBD 镜像里

  • 即使 MySQL Pod 挂了、被删了、被调度到别的节点,数据不会丢

  • 新 Pod 启动时挂载同一个 PVC,数据还在


八、理解 CephFS 案例
复制代码
 volumes:
 - name: laowang-staticdata-cephfs
   cephfs:
     monitors: [...]              # MON 节点地址
     path: /                      # CephFS 的挂载路径
     user: admin                  # 认证用户
     secretRef:
       name: ceph-secret-admin    # 密钥

和 RBD 的区别

RBD CephFS
使用方式 像一块硬盘,只能被一个 Pod 挂载(读写模式) 像一个共享文件夹,可以同时被多个 Pod 挂载
典型场景 MySQL 数据库 Nginx 静态文件、共享配置
多 Pod 共享 不支持(除非只读) 支持

案例中的效果

3 个 Nginx Pod 都挂载同一个 CephFS 目录 /data/nginx/statics。任何一个 Pod 往这个目录写文件,其他两个 Pod 立刻能看到。这就实现了多副本共享数据


九、整个流程总结
复制代码
 ┌─────────────────────────────────────────────────────┐
 │ Ceph 集群                                            │
 │ ┌───────────┐  ┌───────────┐  ┌───────────────────┐ │
 │ │ 存储池    │  │ 用户/权限 │  │ 镜像(虚拟硬盘)   │ │
 │ │ rbd-pool1 │  │ laowang    │  │ laowang-img-img1   │ │
 │ └───────────┘  └───────────┘  └───────────────────┘ │
 └─────────────────────────────────────────────────────┘
                           ↑
                           │ 网络(6789端口)
                           ↓
 ┌─────────────────────────────────────────────────────┐
 │ K8s 集群                                            │
 │ ┌──────────────┐  ┌──────────┐  ┌────────────────┐  │
 │ │ Secret       │  │ PVC/PV   │  │ Pod (MySQL)    │  │
 │ │ (存ceph key) │  │ (5GB)    │  │ /var/lib/mysql │  │
 │ └──────────────┘  └──────────┘  └────────────────┘  │
 └─────────────────────────────────────────────────────┘

1

相关推荐
珂玥c3 天前
Ceph集群新增osd
ceph
老wang你好3 天前
Ceph分布式存储系统全解析
ceph
一个行走的民16 天前
分布式系统中 Map 增量(Delta)是否需要持久化
ceph
一个行走的民18 天前
BlueStore 核心原理与关键机制
ceph
奋斗的小青年I20 天前
Proxmox VE Ceph 超融合集群落地实战
windows·ceph·vmware·pve·超融合·proxmox
一个行走的民20 天前
深度剖析 Ceph PG 分裂机制:原理、底层、实操、影响、线上避坑(最全完整版)
ceph·算法
一个行走的民20 天前
Ceph 核心概念精讲:彻底搞懂 PG、PGP、pg_num、pgp_num
ceph
Mr.王8351 个月前
Kubernetes宿主机本地盘池化管理
ceph·云原生·容器·kubernetes
一个行走的民1 个月前
CEPH OSD心跳机制
ceph