Ceph 分布式存储实战(二):存储池管理与 cephx 认证授权

Ceph 分布式存储池管理与认证授权

本文是 Ceph 分布式存储系列的第二篇,深入讲解 RADOS 数据组织结构(Pool / PG / CRUSH)、池的创建与运维(复本池、纠删码池、快照、命名空间),以及 cephx 认证协议与用户权限管理。

Ceph 数据组织结构

POOL

池是 Ceph 存储集群的逻辑分区,用于在通用名称标签下存储对象。 Ceph 为每个池分配特定数量放置组 (PG),用于对对象进行分组以进行存储。

每个池具有以下可调整属性:

  • 池 ID
  • 池名称
  • PG 数量
  • CRUSH 规则,用于确定此池的 PG 映射
  • 保护类型(复本或纠删码)
  • 与保护类型相关的参数
  • 影响集群行为的各种标志

Place Group

PG 全称为Placement group, 是构成pool的子集, 也是一系列对象的集合。一个PG仅能属于一个Pool。

Ceph 将每个 PG 映射到一组 OSD。属于同一个 PG 的所有对象都返回相同的哈希结果。

PG 数量会影响ceph的性能:

  • 如果pg数量过多,数据移动时,每个PG维护的数据量过少, ceph占用大量的cpu 和内存计算,影响集群正常客户端使用。
  • 如果pg数量过少,单个pg存储的数据就越多,移动pg会占用大量带宽,影响集群客户端使用

在以前版本中, PG的计算公式为:

  • Ceph集群PG 总数 = (OSD 数 * 100) / 最大副本数
  • 单个资源池PG总数 = (OSD 数 * 100) / 最大副本数 / 池数

以上公式中计算出的结果必须舍入到最接近2的N次幂的值。

一般情况下,PG数量设置遵循以下原则:

  • 如果OSD少于5个时, PG 数量设置为128
  • OSD数量大于5小于10时, PG数量设置为512
  • OSD数量大于10小于50时, PG数量设置为4096
  • 如果osd数量大于50,则需要借助工具进行计算,官方工具链接为: https://old.ceph.com/pgcalc/。

映射对象到OSD

客户端在进行数据读写时, 仅需向ceph提供资源池(pool)的名称和对象ID。一个完整的对象由三部分组成:对象ID、二进制数据、对象元数据。

  1. **Ceph 客户端从 MON 获取最新的集群映射复本。**集群映射向客户端提供有关集群中所有 MON、OSD 和 MDS 的信息,但不向客户提供对象的位置。

  2. 计算 PG ID。公式:PG ID=hash(Object ID)%(PG number)。

    为了计算PG ID,Ceph需要知道对象存储池的名称和对象ID:根据池的名称获取池的PG数量,然后对Ceph对象 ID 做hash运算,最终计算出PG ID。

  3. Ceph 使用 CRUSH 算法确定PG 负责哪些 OSDs (Acting Set)。 Acting Set 中的 OSD 在 Up Set 中。 Up Set 中的第一个 OSD 是对象归置组的当前主 OSD,Up Set 中的其他 OSD 是辅助 OSD。

  4. Ceph 客户端直接跟主 OSD 通信以读写对象。

客户端访问ceph流程

  1. 客户端向MON集群发起连接请求。
  2. 客户端和MON建立连接后,它将索引最新版本的cluster map,从而获取到MON、 OSD和MDS的信息,但不包括对象的存储位置。
  3. client根据CRUSH算法计算出对象对应的PG和OSD。
  4. client根据上步中计算得出主OSD的位置,然后和其进行通信,完成对象的读写。

在 ceph 中,客户端自行计算对象存储位置的速度要比通过和ceph组件交互来查询对象存储位置快很多,因此,在数据读写时,都是客户端根据CRUSH完成对象的位置计算。

Ceph 数据读取流程
  1. 客户端通过MON获取到cluster map。
  2. client通过cluster map获取到主OSD节点信息,并向其发送读取请求。
  3. 主OSD将client请求的数据返回给client。
Ceph 数据写入流程
  1. 客户端通过 MON 获取到 cluster map。
  2. 客户端通过cluster map获取到主OSD节点信息,并向其发送写入请求。
  3. 主OSD收到写入请求后,将数据写入,并向两个备OSD发起数据写入指令。
  4. 两个备OSD将数据写入后返回确认到主OSD。
  5. 主OSD收到所有备OSD写入完成后的确认后,向客户端返回写入完成的确认。

Ceph 采用数据强一致性来保证数据的同步。强一致性会导致数据写入有较大的延迟,因此ceph进行了优化,将数据的写入分两次进行:

  • 第一次当所有数据都写入OSD节点的缓存后,向client发送一次确认, client就会认为数据写入完成,继续进行后面操作。
  • 第二次当所有数据都从缓存写入到磁盘后,再向client发送一次确认, client就会认为数据彻底写入,从而根据需要删除对应的本地数据。

数据保护

Ceph 存储支持:复本池 和纠删码池。

  • replicated pool(复本池),通过将各个对象复本到多个 OSD 来发挥作用。此池类型会创建多个对象复本,需要较多存储空间,但其通过冗余提高了读取操作的可用性。

  • Erasure code pool(纠删代码池),需要较少的存储空间和网络带宽,但因为要进行奇偶校验计算,所以会占用较多的 CPU处理时间。

注意:池一旦创建完成,池的类型便无法更改。

池类型选择:

  • 对于不需要频繁访问且不需要低延迟的数据,推荐使用纠删码池。
  • 对于需要频繁访问并且要具备快速读取性能的数据,推荐使用复本池。

创建池

创建复本池

Ceph 为每个对象创建多个复本来保护复本池中的数据。Ceph 使用CRUSH 故障域来确定存储数据的操作集的主要 OSD。然后,主要 OSD 会查找池的当前复本数量,并计算要写入对象的次要 OSD。在主要 OSD 收到写入确认并完成数据写入后,主要 OSD 会向 Ceph 客户端确认写入操作已成功。如果一个或多个 OSD 出现故障,这一过程可保护对象中的数据。

创建复本池语法:

bash 复制代码
ceph osd pool create pool-name pg-num pgp-num replicated crush-rule-name

其中:

  • pool_name,指定新池的名称。

  • pg_num,指定池的放置组 (PG) 总数。

  • pgp_num,指定池的有效放置组数量。将它设置为与 pg_num 相等。该值可省略。

  • replicated ,指定池的类型为复本池;如果命令中未包含此参数,这是默认值。

  • crush-rule-name,指定池的 CRUSH 规则集的名称。

    osd_pool_default_crush_replicated_ruleset 配置参数设置其默认值。

示例:

bash 复制代码
[root@ceph1 ~]# ceph osd pool create pool_web 32 32 replicated
pool 'pool_web' created

[root@ceph1 ~]# ceph osd pool ls
device_health_metrics
pool_web

创建纠删代码池

纠删代码池使用纠删代码保护对象数据。 在纠删代码池中存储的对象分割为多个数据区块,这些数据区块存储在不同的 OSD 中。编码块的数量是根据数据块计算的,并存储在不同的 OSD 中。当 OSD 出现故障时,可利用编码块重构对象数据。主要 OSD 接收写入操作,然后将载荷编码为 K+M 块,并将它们发给纠删代码池中的次要OSD。

以下概括了纠删代码池的工作方式:

  • 每个对象的数据分割为 k 个数据区块,计算出 m 个编码区块。

  • 对象存储在总共 k + m 个 OSD 中。

  • 编码区块大小与数据区块大小相同。

与复本相比,纠删代码使用存储容量的效率更高。复本池维护对象的 n 个复本,而纠删代码仅维护 k + m 个区块。

例如,具有 3 个复本的复本池要使用 3 倍存储空间。而 k=4 和 m=2 的纠删代码池仅要使用 1.5 倍存储空间。

支持以下 k+m 值,其对应的可用与原始比为:

  • 4+2(比率为 1:1.5)
  • 8+3(比率为 1:1.375)
  • 8+4(比率为 1:1.5)

纠删代码池有效容量百分比:k / (k+m)。例如,如果用户有 64 个 OSD(每个 4 TB,总计 256 TB)并且 k=8 和 m=4,那么公式为 8 / (8+4) * 64 * 4 = 170.67。然后,将原始存储容量除以开销就能得出该比率。256 TB/170.67 TB 等于 1.5 比率。

创建纠删代码池语法:

bash 复制代码
ceph osd pool create pool-name pg-num pgp-num erasure erasure-code-profile crush-rule-name
  • pool-name,指定新池的名称。
  • pg-num,指定池的放置组 (PG) 总数。
  • pgp-num,指定池的有效放置组数量。通常而言,这应当与 PG 总数相等。
  • erasure,指定池的类型是纠删代码池。
  • erasure-code-profile,指定池使用的纠删代码配置文件的名称。默认情况下,Ceph 使用 default 配置文件。
  • crush-rule-name 是要用于这个池的 CRUSH 规则集的名称。如果不设置,Ceph 将使用纠删代码池配置文件中定义的规则集。

**纠删代码池无法使用对象映射功能。**对象映射是对象的一个索引,用于跟踪 rbd 对象的块会被分配到哪里,可用于提高大小调整、导出、扁平化和其他操作的性能。

示例:

bash 复制代码
[root@ceph1 ~]# ceph osd pool create pool_era 32 32 erasure
pool 'pool_era' created

[root@ceph1 ~]# ceph osd pool ls
device_health_metrics
pool_web
pool_era

查看默认纠删代码配置

bash 复制代码
[root@ceph1 ~]# ceph osd erasure-code-profile ls
default

[root@ceph1 ~]# ceph osd erasure-code-profile get default
k=2
m=2
plugin=jerasure
technique=reed_sol_van

管理纠删代码配置文件

纠删代码配置文件可配置纠删代码池用于存储对象的数据区块和编码区块的数量,以及要使用的纠删代码插件和算法。

创建纠删代码配置文件语法如下:

bash 复制代码
ceph osd erasure-code-profile set profile-name arguments

可用的参数如下:

  • k,在不同 OSD 之间拆分的数据区块数量。默认值为 2。
  • m,数据变得不可用之前可以出现故障的 OSD 数量。默认值为 1。
  • directory,此可选参数是插件库的位置。默认值为 /usr/lib64/ceph/erasure-code。
  • plugin,此可选参数定义要使用的纠删代码算法。
  • crush-failure-domain,此可选参数定义 CRUSH 故障域,它控制区块放置。默认设置为 host,这样可确保对象的区块放置到不同主机的 OSD 上。如果设置为 osd,则对象的区块可以放置到同一主机的 OSD 上。如果主机出现故障,则该主机上的所有 OSD 都会出现故障。故障域可用于确保将区块放置到不同数据中心机架或其他定制的主机上的 OSD 上。
  • crush-device-class,此可选参数选择仅将这一类别设备支持的 OSD 用于池。典型的类别可能包括 hdd、ssd 或nvme。
  • crush-root,此可选参数设置 CRUSH 规则集的根节点。
  • key=value,插件可以具有对该插件唯一的键值参数。
  • technique,每个插件提供一组不同的技术来实施不同的算法。

示例:

bash 复制代码
[root@ceph1 ~]# ceph osd erasure-code-profile set ceph k=4 m=2

列出现有的就删代码配置文件

bash 复制代码
[root@ceph1 ~]# ceph osd erasure-code-profile ls
ceph
default

Ceph 会在安装期间创建 default 配置文件。这个配置文件已配置为将对象分割为2个数据区块和2个编码区块。

查看现有配置文件的详细信息

bash 复制代码
[root@ceph1 ~]# ceph osd erasure-code-profile get ceph
crush-device-class=
crush-failure-domain=host
crush-root=default
jerasure-per-chunk-alignment=false
k=4
m=2
plugin=jerasure
technique=reed_sol_van
w=8

删除现有的配置文件

bash 复制代码
[root@ceph1 ~]# ceph osd erasure-code-profile rm ceph
[root@ceph1 ~]# ceph osd erasure-code-profile ls
default

重要:现有纠删代码配置文件是无法修改或更改,只能创建新的配置文件。

查看 池 状态

使用 ceph osd pool ls 命令,可以列出池清单。

bash 复制代码
[root@ceph1 ~]# ceph osd pool ls
device_health_metrics
pool_web
pool_era

使用 ceph osd pool ls detail 命令,可以列出池清单和池的详细配置。

bash 复制代码
[root@ceph1 ~]# ceph osd pool ls detail
pool 1 'device_health_metrics' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 31 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr_devicehealth
pool 2 'pool_web' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 34 flags hashpspool stripe_width 0
pool 3 'pool_era' erasure profile default size 4 min_size 3 crush_rule 1 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 41 flags hashpspool stripe_width 8192

使用 ceph osd lspools 命令,也可以列出池清单。

bash 复制代码
[root@ceph1 ~]# ceph osd lspools
1 device_health_metrics
2 pool_web
3 pool_era

使用 ceph osd pool stats 命令,可以列出池状态信息,池被哪些客户端使用。

bash 复制代码
[root@ceph1 ~]# ceph osd pool stats
pool device_health_metrics id 1
  nothing is going on

pool pool_web id 2
  nothing is going on

pool pool_era id 3
  nothing is going on

使用 ceph df 命令,可以查看池容量使用信息。

bash 复制代码
[root@ceph1 ~]# ceph df
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    180 GiB  177 GiB  2.6 GiB   2.6 GiB       1.42
TOTAL  180 GiB  177 GiB  2.6 GiB   2.6 GiB       1.42

--- POOLS ---
POOL                   ID  PGS  STORED  OBJECTS  USED  %USED  MAX AVAIL
device_health_metrics   1    1     0 B        0   0 B      0     56 GiB
pool_web                2   32     0 B        0   0 B      0     56 GiB
pool_era                3   32     0 B        0   0 B      0     84 GiB
[root@ceph1 ~]#

管理 池

管理 池 应用类型

使用 ceph osd pool application 命令,管理池 Ceph 应用类型。应用类型有cephfs(用于 Ceph 文件系统) 、rbd(Ceph 块设备)和 rgw(RADOS 网关)。

bash 复制代码
[root@ceph1 ~]# ceph osd pool application <tab><tab>
disable  enable   get      rm       set 

# 启用池的类型为rbd
[root@ceph1 ~]# ceph osd pool application enable pool_web rbd
enabled application 'rbd' on pool 'pool_web'

[root@ceph1 ~]# ceph osd pool ls detail | grep pool_web
pool 2 'pool_web' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 44 flags hashpspool stripe_width 0 `application rbd`  <------ #看这的变化     

# 使用set子命令,设置池的应用类型详细配置
[root@ceph1 ~]# ceph osd pool application set pool_web rbd app1 apache
set application 'rbd' key 'app1' to 'apache' on pool 'pool_web'
# 这里添加的设置,app1=apache仅供参考,没有实际意义。

# 使用get子命令,查看池的应用类型详细配置
[root@ceph1 ~]# ceph osd pool application get pool_web
{
    "rbd": {
        "app1": "apache"
    }
}

# 使用rm子命令,删除池的应用类型详细配置
[root@ceph1 ~]# ceph osd pool application rm pool_web rbd app1
removed application 'rbd' key 'app1' on pool 'pool_web'

[root@ceph1 ~]# ceph osd pool application get pool_web
{
    "rbd": {}
}

# 禁用池的类型
[root@ceph1 ~]# ceph osd pool application disable pool_web rbd --yes-i-really-mean-it
disable application 'rbd' on pool 'pool_web'

[root@ceph1 ~]# ceph osd pool ls detail | grep pool_web
pool 2 'pool_web' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 47 flags hashpspool stripe_width 0

管理 池 配额

使用 ceph osd pool get-quota 命令,获取池配额信息:池中能够存储的最大字节数或最大对象数量。

bash 复制代码
[root@ceph1 ~]# ceph osd pool get-quota pool_web
quotas for pool 'pool_web':
  max objects: N/A
  max bytes  : N/A

使用 ceph osd pool set-quota 命令,可以设置池配额来限制池中能够存储的最大字节数或最大对象数量。

当存储对象达到限额是,整个池会无法使用

bash 复制代码
[root@ceph1 ~]# ceph osd pool set-quota pool_web max_objects 100000
set-quota max_objects = 100000 for pool pool_web
[root@ceph1 ~]# ceph osd pool set-quota pool_web max_bytes 10G
set-quota max_bytes = 10737418240 for pool pool_web

[root@ceph1 ~]# ceph osd pool get-quota pool_web
quotas for pool 'pool_web':
  max objects: 100k objects  (current num objects: 0 objects)
  max bytes  : 10 GiB  (current num bytes: 0 bytes)

当池使用量达到池配额时,操作将被阻止。用户可通过将该值设置为 0 来删除配额。

bash 复制代码
[root@ceph1 ~]# ceph osd pool set-quota pool_web max_objects 0
set-quota max_objects = 0 for pool pool_web
[root@ceph1 ~]# ceph osd pool set-quota pool_web max_bytes 0
set-quota max_bytes = 0 for pool pool_web

[root@ceph1 ~]# ceph osd pool get-quota pool_web
quotas for pool 'pool_web':
  max objects: N/A
  max bytes  : N/A

管理 池 配置

查看池配置

使用 ceph osd pool get 命令,查看池配置。

bash 复制代码
# 查看池所有配置
[root@ceph1 ~]# ceph osd pool get pool_web all
size: 3                              #副本数3                      
min_size: 2
pg_num: 32
pgp_num: 32
crush_rule: replicated_rule
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
bulk: false

# 查看池特定配置
[root@ceph1 ~]# ceph osd pool get pool_web nodelete
nodelete: false

# 备用命令
[root@ceph1 ~]# ceph osd pool get pool_web all | grep nodelete
nodelete: false
设置池配置

使用 ceph osd pool set 命令,可以修改池配置选项。

bash 复制代码
# 设置池不可删除
[root@ceph1 ~]# ceph osd pool set pool_web nodelete true
set pool 2 nodelete to true
[root@ceph1 ~]# ceph osd pool get pool_web nodelete
nodelete: true

# 将 nodelete 重新设置为 FALSE,即可允许删除池
root@ceph1 ~]# ceph osd pool set pool_web nodelete false
set pool 2 nodelete to false
[root@ceph1 ~]# ceph osd pool get pool_web nodelete
nodelete: false

管理 池 复本数

使用以下命令,更改池的复本数量。

bash 复制代码
[root@ceph1 ~]# ceph osd pool set pool_web size 2    
set pool 2 size to 2           #2 size to 2???没变,别闹这里说的时pool2 的size 变成2,pool2是谁??

[root@ceph1 ~]# ceph osd pool get pool_web all
size: 2                    #这里确实从之前的3变成了2
min_size: 1
pg_num: 32
pgp_num: 32
crush_rule: replicated_rule
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
bulk: false

池的默认复本数量由 osd_pool_default_size 配置参数定义,默认值为 3。

bash 复制代码
[root@ceph1 ~]# ceph config get mon osd_pool_default_size
3

使用以下命令定义创建新池的默认复本数量。

bash 复制代码
[root@ceph1 ~]# ceph config set mon osd_pool_default_size 2
[root@ceph1 ~]# ceph config get mon osd_pool_default_size
2

osd_pool_default_min_size 参数定义集群必须提供多少个对象复本才能接受 I/O 请求。复本数为3的池,该值为2;复本数为2的池,该值为1。

使用以下命令定义池的最小复本数量。

bash 复制代码
[root@ceph1 ~]# ceph config get mon osd_pool_default_min_size
0                                        #参数值为0是特殊设置,意味着集群将自动使用存储池的size值作为最小副本数计算,举例说明:如果某存储池size=3,那么min_size会自动设为2(即size/2+1取整)

[root@ceph1 ~]# ceph config set mon osd_pool_default_min_size 1
[root@ceph1 ~]# ceph config get mon osd_pool_default_min_size
1

管理 池 PG 数

使用以下命令,更改池 PG 数量。

bash 复制代码
[root@ceph1 ~]# ceph osd pool set pool_web pg_num 64         #思考PG设置多少合适???
set pool 2 pg_num to 64

[root@ceph1 ~]# ceph osd pool get pool_web all             
size: 2
min_size: 1
pg_num: 64                                            #确实PG变为了64
pgp_num: 64
crush_rule: replicated_rule
hashpspool: true
nodelete: false
nopgchange: false
nosizechange: false
write_fadvise_dontneed: false
noscrub: false
nodeep-scrub: false
use_gmt_hitset: 1
fast_read: 0
pg_autoscale_mode: on
bulk: false

**Ceph 存储默认在池上配置放置组自动扩展。**自动扩展允许集群计算放置组的数量,并且自动选择适当的 pg_num 值。

集群中的每个池都有一个 pg_autoscale_mode 选项,其值可以是 on、off 或 warn。

  • on:启用自动调整池的 PG 数。
  • off:禁用池的 PG 自动扩展。
  • warn:在 PG 数需要调整时引发运行状况警报并将集群运行状况更改为 HEALTH_WARN。

集群配置放置组自动扩展,需要在 Ceph MGR 节点上启用 pg_autoscaler 模块,并将池的自动扩展模式设置为 on:

bash 复制代码
[root@ceph1 ~]# ceph mgr module enable pg_autoscaler      
module 'pg_autoscaler' is already enabled (always-on)

[root@ceph1 ~]# ceph osd pool set pool_web pg_autoscale_mode off      #pool_web池pb_autoscale_mode设置为off
set pool 2 pg_autoscale_mode to off
[root@ceph1 ~]# ceph osd pool autoscale-status
POOL                     SIZE  TARGET SIZE  RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO  BIAS  PG_NUM  NEW PG_NUM  AUTOSCALE  BULK
device_health_metrics      0                 3.0        179.9G  0.0000                                  1.0       1              on         False
pool_web                   0                 2.0        179.9G  0.0000                                  1.0      64              off        False
pool_era                   0                 2.0        179.9G  0.0000                                  1.0      32              on         False

[root@ceph1 ~]# ceph osd pool set pool_web pg_autoscale_mode on
set pool 2 pg_autoscale_mode to on
[root@ceph1 ~]# ceph osd pool autoscale-status
POOL                     SIZE  TARGET SIZE  RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO  BIAS  PG_NUM  NEW PG_NUM  AUTOSCALE  BULK
device_health_metrics      0                 3.0        179.9G  0.0000                                  1.0       1              on         False
pool_web                   0                 2.0        179.9G  0.0000                                  1.0      64              on         False
pool_era                   0                 2.0        179.9G  0.0000                                  1.0      32              on         False

可以在集群级别为新创建的池设置一些默认值:

  • osd_pool_default_flag_nodelete,为池设置 nodelete 标志的默认值。将值设置为 TRUE 可以防止删除池。
  • osd_pool_default_flag_nopgchange,为池设置 nopgchange 标志的默认值。将值设置为 TRUE 可以防止更改 pg_num 和pgp_num。
  • osd_pool_default_flag_nosizechange,为池设置 nosizechange 标志的默认值。将值设置为 TRUE 可以防止更改池大小。

以上这些参数需要配置在ceph集群配置ceph.conf的global块中。

管理 池 中对象

Ceph使用 rados 命令管理池的对象。

bash 复制代码
[root@ceph1 ~]# rados -h
usage: rados [options] [commands]
POOL COMMANDS
   lspools                          list pools
   cppool <pool-name> <dest-pool>   copy content of a pool
   purge <pool-name> --yes-i-really-really-mean-it
                                    remove all objects from pool <pool-name> without removing it
   df                               show per-pool and total usage
   ls                               list objects in pool


POOL SNAP COMMANDS
   lssnap                           list snaps
   mksnap <snap-name>               create snap <snap-name>
   rmsnap <snap-name>               remove snap <snap-name>

OBJECT COMMANDS
   get <obj-name> <outfile>         fetch object
   put <obj-name> <infile> [--offset offset]
                                    write object with start offset (default:0)
   append <obj-name> <infile>       append object
   truncate <obj-name> length       truncate object
   create <obj-name>                create object
   rm <obj-name> ... [--force-full] remove object(s), --force-full forces remove when cluster is full
   cp <obj-name> [target-obj]       copy object
   listxattr <obj-name>
   getxattr <obj-name> attr
   setxattr <obj-name> attr val
   rmxattr <obj-name> attr
   stat <obj-name>                  stat the named object
   stat2 <obj-name>                 stat2 the named object (with high precision time)
   touch <obj-name> [timestamp]     change the named object modification time
   mapext <obj-name>
   rollback <obj-name> <snap-name>  roll back object to snap <snap-name>

   listsnaps <obj-name>             list the snapshots of this object
   bench <seconds> write|seq|rand [-t concurrent_operations] [--no-cleanup] [--run-name run_name] [--no-hints] [--reuse-bench]
                                    default is 16 concurrent IOs and 4 MB ops
                                    default is to clean up after write benchmark
                                    default run-name is 'benchmark_last_metadata'
   cleanup [--run-name run_name] [--prefix prefix]
                                    clean up a previous benchmark operation
                                    default run-name is 'benchmark_last_metadata'
   load-gen [options]               generate load on the cluster
   listomapkeys <obj-name>          list the keys in the object map
   listomapvals <obj-name>          list the keys and vals in the object map
   getomapval <obj-name> <key> [file] show the value for the specified key
                                    in the object's object map
   setomapval <obj-name> <key> <val | --input-file file>
   rmomapkey <obj-name> <key>
   clearomap <obj-name> [obj-name2 obj-name3...] clear all the omap keys for the specified objects
   getomapheader <obj-name> [file]
   setomapheader <obj-name> <val>
   watch <obj-name>                 add watcher on this object
   notify <obj-name> <message>      notify watcher of this object with message
   listwatchers <obj-name>          list the watchers of this object
   set-alloc-hint <obj-name> <expected-object-size> <expected-write-size>
                                    set allocation hint for an object
   set-redirect <object A> --target-pool <caspool> <target object A> [--with-reference]
                                    set redirect target
   set-chunk <object A> <offset> <length> --target-pool <caspool> <target object A> <taget-offset> [--with-reference]
                                    convert an object to chunked object
   tier-promote <obj-name>           promote the object to the base tier
   unset-manifest <obj-name>         unset redirect or chunked object
   tier-flush <obj-name>             flush the chunked object
   tier-evict <obj-name>             evict the chunked object

IMPORT AND EXPORT
   export [filename]
       Serialize pool contents to a file or standard out.
   import [--dry-run] [--no-overwrite] < filename | - >
       Load pool contents from a file or standard in

ADVISORY LOCKS
   lock list <obj-name>
       List all advisory locks on an object
   lock get <obj-name> <lock-name> [--lock-cookie locker-cookie] [--lock-tag locker-tag] [--lock-description locker-desc] [--lock-duration locker-dur] [--lock-type locker-type]
       Try to acquire a lock
   lock break <obj-name> <lock-name> <locker-name> [--lock-cookie locker-cookie]
       Try to break a lock acquired by another client
   lock info <obj-name> <lock-name>
       Show lock information
   options:
       --lock-tag                   Lock tag, all locks operation should use
                                    the same tag
       --lock-cookie                Locker cookie
       --lock-description           Description of lock
       --lock-duration              Lock duration (in seconds)
       --lock-type                  Lock type (shared, exclusive)

SCRUB AND REPAIR:
   list-inconsistent-pg <pool>      list inconsistent PGs in given pool
   list-inconsistent-obj <pgid>     list inconsistent objects in given PG
   list-inconsistent-snapset <pgid> list inconsistent snapsets in the given PG

CACHE POOLS: (for testing/development only)
   cache-flush <obj-name>           flush cache pool object (blocking)
   cache-try-flush <obj-name>       flush cache pool object (non-blocking)
   cache-evict <obj-name>           evict cache pool object
   cache-flush-evict-all            flush+evict all objects
   cache-try-flush-evict-all        try-flush+evict all objects

GLOBAL OPTIONS:
   --object-locator object_locator
        set object_locator for operation
   -p pool
   --pool=pool
        select given pool by name
   --target-pool=pool
        select target pool by name
   --pgid PG id
        select given PG id
   -f [--format plain|json|json-pretty]
   --format=[--format plain|json|json-pretty]
   -b op_size
        set the block size for put/get ops and for write benchmarking
   -O object_size
        set the object size for put/get ops and for write benchmarking
   --max-objects
        set the max number of objects for write benchmarking
   --obj-name-file file
        use the content of the specified file in place of <obj-name>
   -s name
   --snap name
        select given snap name for (read) IO
   --input-file file
        use the content of the specified file in place of <val>
   --create
        create the pool or directory that was specified
   -N namespace
   --namespace=namespace
        specify the namespace to use for the object
   --all
        Use with ls to list objects in all namespaces
        Put in CEPH_ARGS environment variable to make this the default
   --default
        Use with ls to list objects in default namespace
        Takes precedence over --all in case --all is in environment
   --target-locator
        Use with cp to specify the locator of the new object
   --target-nspace
        Use with cp to specify the namespace of the new object
   --striper
        Use radostriper interface rather than pure rados
        Available for stat, get, put, truncate, rm, ls and
        all xattr related operations

BENCH OPTIONS:
   -t N
   --concurrent-ios=N
        Set number of concurrent I/O operations
   --show-time
        prefix output with date/time
   --no-verify
        do not verify contents of read objects
   --write-object
        write contents to the objects
   --write-omap
        write contents to the omap
   --write-xattr
        write contents to the extended attributes

LOAD GEN OPTIONS:
   --num-objects                    total number of objects
   --min-object-size                min object size
   --max-object-size                max object size
   --min-op-len                     min io size of operations
   --max-op-len                     max io size of operations
   --max-ops                        max number of operations
   --max-backlog                    max backlog size
   --read-percent                   percent of operations that are read
   --target-throughput              target throughput (in bytes)
   --run-length                     total time (in seconds)
   --offset-align                   at what boundary to align random op offsets

CACHE POOLS OPTIONS:
   --with-clones                    include clones when doing flush or evict

OMAP OPTIONS:
    --omap-key-file file            read the omap key from a file

GENERIC OPTIONS:
  --conf/-c FILE    read configuration from the given configuration file
  --id ID           set ID portion of my name
  --name/-n TYPE.ID set name
  --cluster NAME    set cluster name (default: ceph)
  --setuser USER    set uid to user or uid (and gid to user's gid)
  --setgroup GROUP  set gid to group or gid
  --version         show version and quit

这里我们主要讲解池中对象操作。

上传对象到池中

bash 复制代码
[root@ceph1 ~]# echo laogao1 > hosts1
[root@ceph1 ~]# rados -p pool_web put hosts hosts1   #将host1文件上传到webapp池取名为hosts
[root@ceph1 ~]# rados -p pool_web ls
hosts

查看池中对象状态

bash 复制代码
[root@ceph1 ~]# rados -p pool_web stat hosts
pool_web/hosts mtime 2025-08-21T09:52:43.000000+0800, size 8

查看池中对象存储在哪里

bash 复制代码
[root@ceph1 ~]# ceph osd map pool_web hosts
osdmap e85 pool 'pool_web' (2) object 'hosts' -> pg 2.ea1b298e (2.e) -> up ([8,2], p8) acting ([8,2], p8)

[root@ceph1 ~]# ceph osd metadata 8 | grep devices
    "bluestore_bdev_devices": "sdd",
    "devices": "sdd",
    "objectstore_numa_unknown_devices": "sdd",
    "osdspec_affinity": "all-available-devices",


[root@ceph1 ~]# ceph pg dump pgs_brief 
bash 复制代码
逐段翻译
1. osdmap e85
osdmap:Ceph 集群当前的 OSD 映射表(集群拓扑)
e85:epoch 85 → 这是第 85 版集群映射
每次加盘、删盘、故障、重启,版本号都会涨。
2. pool 'pool_web' (2)
存储池名字:pool_web
存储池 ID:2
3. object 'hosts'
你要查询的对象名:hosts
4. -> pg 2.ea1b298e (2.e)
PG = Placement Group(放置组)
Ceph 先把对象映射到 PG,再由 PG 映射到 OSD。
2:pool ID
ea1b298e:对象 hosts 经过 HASH 计算 得到的十六进制值
(2.e):简化写法 = pool 2 + PG 编号 e
PG 编号 e 是十六进制 → 等于十进制 14
也就是说:
对象 hosts → 被 Ceph 放进 PG 2.14(2.e)
5. -> up ([8,2], p8)
up:表示当前活着、可用的 OSD 列表
[8,2]:对象的两个副本分别在 osd.8 和 osd.2
p8:primary osd = 主 OSD 是 8
读写优先走主 OSD。
6. acting ([8,2], p8)
acting:表示实际负责这个 PG 的 OSD
正常情况下 up 和 acting 完全一样
如果在恢复、迁移、故障时,两者会不一样
最终结论(最关键)
你这个对象 hosts 在 Ceph 里的位置是:
plaintext
pool_web (pool-2)
  → 对象 hosts
    → 哈希到 PG 2.e (PG 14)
      → 主 OSD:osd.8
      → 副本 OSD:osd.2
数据存在 osd.8 和 osd.2 两块盘上

检索对象到本地

bash 复制代码
[root@ceph1 ~]# rados -p pool_web get hosts newhosts
[root@ceph1 ~]# cat newhosts
laogao1

追加池中对象

bash 复制代码
[root@ceph1 ~]# echo laogao2 >> hosts2
[root@ceph1 ~]# rados append -p pool_web hosts hosts2
[root@ceph1 ~]# rados get hosts newhosts -p pool_web
[root@ceph1 ~]# cat newhosts
laogao1
laogao2

删除池中对象

bash 复制代码
[root@ceph1 ~]# rados put passwd /etc/passwd -p pool_web
[root@ceph1 ~]# rados ls -p pool_web
passwd
hosts
[root@ceph1 ~]# rados rm passwd -p pool_web
[root@ceph1 ~]# rados ls -p pool_web
hosts

管理 池 快照

使用 ceph osd pool mksnap 命令,创建池快照。

bash 复制代码
[root@ceph1 ~]# ceph osd pool mksnap pool_web snap1      #给池pool_web创建快照snap1
created pool pool_web snap snap1

[root@ceph1 ~]# ceph osd pool ls detail
pool 2 'pool_web' replicated size 2 min_size 1 crush_rule 0 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode off last_change 68 lfor 0/0/60 flags hashpspool,pool_snaps stripe_width 0
        snap 1 'snap1' 2025-08-21T02:05:02.662386+0000                 #多了snap1
        
[root@ceph1 ~]# rados -p pool_web lssnap
1       snap1   2025.09.29 14:38:50
1 snaps

使用 ceph osd pool rmsnap 命令,删除池快照。

bash 复制代码
[root@ceph1 ~]# ceph osd pool rmsnap pool_web snap1
removed pool pool_web snap snap1

[root@ceph1 ~]# ceph osd pool ls detail
pool 2 'pool_web' replicated size 2 min_size 1 crush_rule 0 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode off last_change 69 lfor 0/0/60 flags hashpspool,pool_snaps stripe_width 0

[root@ceph1 ~]# rados -p pool_web lssnap
0 snaps

管理 池 快照中对象

对池某个快照中对象操作需要使用-s选项指定快照名称。

bash 复制代码
[root@ceph1 ~]# ceph osd pool mksnap pool_web snap1      #给池pool_web拍摄快照snap1
created pool pool_web snap snap1

[root@ceph1 ~]# rados -p pool_web listsnaps hosts
hosts:
cloneid snaps   size    overlap
head    -       16

#拍摄快照后,上传新的内容到hosts中
[root@ceph1 ~]# echo laogao3 > hosts3           
[root@ceph1 ~]# rados -p pool_web put hosts hosts3      
[root@ceph1 ~]# rados -p pool_web get hosts newhosts
[root@ceph1 ~]# cat newhosts
laogao3
bash 复制代码
# 查看快照中对象
[root@ceph1 ~]# rados ls -p pool_web -s snap1
selected snap 3 'snap1'
hosts

# 获取快照中对象
[root@ceph1 ~]# rados -p pool_web -s snap1 get hosts hosts-from-snap1
selected snap 3 'snap1'
[root@ceph1 ~]# cat hosts-from-snap1        #发现即使hosts文件拍摄快照后变了,从快照获取的依然没变
laogao1
laogao2

# 恢复对象内容为指定快照时内容
[root@ceph1 ~]# rados -p pool_web rollback hosts snap1
rolled back pool pool_web to snapshot snap1
[root@ceph1 ~]# rados -p pool_web get hosts newhosts
[root@ceph1 ~]# cat newhosts
laogao1
laogao2

快照是只读文件系统,无法上传和删除快照中对象。

bash 复制代码
[root@ceph1 ~]# rados put -p pool_web -s snap1 passwd /etc/passwd
selected snap 3 'snap1'
error putting pool_web/passwd: (30) Read-only file system

[root@ceph1 ~]# rados ls -p pool_web -s snap1
selected snap 3 'snap1'
hosts

[root@ceph1 ~]# rados rm -p pool_web -s snap1 hosts
selected snap 3 'snap1'
error removing pool_web>hosts: (30) Read-only file system

管理 池 命名空间

Ceph可以将整个池提供给特定应用。随着应用增加,池的数量也增加。

**建议每个 OSD 关联的PG数量为100-200。由于集群中 OSD 数量是有限的,所以PG的数量也是有限的。**创建的池越多,导致池能够分配的PG数量越少,每个PG 将会为更多的对象映射到OSD磁盘,进而导致每个 PG 的计算开销更高(负载更高),从而降低 OSD 性能。

使用命名空间,可以对池中对象进行逻辑分组,还可以限制用户只能存储或检索池中特定命名空间内的对象。借助命名空间,可以让多个应用使用同一个池,而且不必将整个池专用于各个应用,从而确保池的数量不会太多。

**命名空间目前仅支持直接使用 librados 的应用。**RBD 和 Ceph 对象网关客户端目前不支持此功能。

若要在命名空间内存储对象,客户端应用必须提供池和命名空间的名称。默认情况下,每个池包含一个具有空名称的命名空间,称为默认命名空间。

示例:

bash 复制代码
[root@ceph1 ~]# rados put -p pool_web -N myns1 hostname1 /etc/hostname
[root@ceph1 ~]# rados ls -p pool_web
hosts
[root@ceph1 ~]# rados ls -p pool_web -N myns1     #上传的hsotname1在namespace myns1中
hostname1

[root@ceph1 ~]# rados put -p pool_web -N myns2 hostname2 /etc/hostname
[root@ceph1 ~]# rados ls -p pool_web -N myns2
hostname2

[root@ceph1 ~]# rados ls -p pool_web --all
myns1   hostname1
        hosts
myns2   hostname2

[root@ceph1 ~]# rados ls -p pool_web --all --format=json-pretty
[
    {
        "namespace": "myns1",
        "name": "hostname1"
    },
    {
        "namespace": "",
        "name": "hosts"
    },
    {
        "namespace": "myns2",
        "name": "hostname2"
    }
]

重命名池

使用 ceph osd pool rename 命令,重命名池。

bash 复制代码
[root@ceph1 ~]# ceph osd pool rename pool_web pool_apache
pool 'pool_web' renamed to 'pool_apache'

**重命名池不会影响池中存储的数据。**如果用户重命名池,则会影响池级别的用户权限,则必须使用新的池名称来更新该用户的能力。

删除池

使用 ceph osd pool delete 命令,删除池。

bash 复制代码
[root@ceph1 ~]# ceph osd pool rm pool_apache
Error EPERM: WARNING: this will *PERMANENTLY DESTROY* all data stored in pool pool_apache.  If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, followed by --yes-i-really-really-mean-it.           #根据提示需要将pool name输入两次,跟上参数--yes-i-really-really-mean-it

[root@ceph1 ~]# ceph osd pool rm pool_apache pool_apache --yes-i-really-really-mean-it
Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool        #提示需要先将mon_allow_pool_delete选项配置为true才能删除pool

必须将集群级别 mon_allow_pool_delete 设置为 TRUE 才能删除池。

bash 复制代码
[root@ceph1 ~]# ceph config set mon mon_allow_pool_delete true

[root@ceph1 ~]# ceph config get mon mon_allow_pool_delete
true

[root@ceph1 ~]# ceph osd pool rm pool_apache pool_apache --yes-i-really-really-mean-it
pool 'pool_apache' removed

重要:删除池会删除池中的所有数据,而且不可逆转。

还可以通过设置池 nodelete 属性为 yes,防止池被误删除。

bash 复制代码
# ceph osd pool set pool_apache nodelete true

第 5 章 Ceph 分布式存储 认证和授权管理

Ceph 集群身份验证

cephx 协议

Ceph 存储使用 cephx 协议管理集群认证。

Ceph 中用户帐户用途:

  • Ceph 守护进程之间的内部通信。
  • 客户通通过 librados 库访问集群。
  • 集群管理。

账户名称

  • Ceph 守护进程使用的帐户与守护进程名称相匹配,例如 osd.1 或 mgr.ceph1,并在安装期间创建。

  • **使用 librados 的客户端应用所用帐户的名称具有 client. 前缀。**例如:

    • 将 OpenStack 与 Ceph 集成时,常常会创建专用的 client.openstack 用户帐户。

    • 对于 Ceph 对象网关,安装过程会创建专用的 client.rgw.hostname 用户帐户。

  • **安装程序会创建超级用户帐户 client.admin,该帐户具有访问所有内容及修改集群配置的能力。**运行ceph相关命令时,Ceph 默认使用 client.admin 帐户,除非用户通过 --name 或 --id 选项明确指定了其他用户名。

可以设置 CEPH_ARGS 环境变量来定义用户名称或用户 ID 等参数。

示例:

bash 复制代码
# export CEPH_ARGS="--id laogao"

**应用的最终用户不在 Ceph 集群中拥有帐户。**最终用户访问应用,然后由应用代表他们访问 Ceph。从 Ceph 角度来看,应用就是客户端。应用可能会通过其他机制提供自己的用户身份验证。

Ceph 对象网关有自己的用户数据库来验证 Amazon S3 或 Swift 用户的身份,Ceph 对象网关使用client.rgw.hostname 帐户来访问集群。

密钥环文件

Ceph 创建用户帐户时,为每个用户帐户生成密钥环文件,通过密钥环文件验证用户身份,必须将此文件复制到客户端系统或应用服务器上。

Ceph 根据 /etc/ceph/ceph.conf 配置文件中的 keyring 参数查找密钥环文件,默认值为/etc/ceph/cluster.cluster.cluster.name.keyring。例如,对于 client.openstack 帐户,其密钥环文件为 /etc/ceph/ceph.client.openstack.keyring。

**密钥环文件以纯文本形式存储机密密钥,**因此需要使用适当的 Linux 文件权限来保护文件,仅允许授权的Linux 用户访问。仅将 Ceph 用户的密钥环文件部署到需要用它进行身份验证的系统上。

指定用户身份

ceph、rados 和 rbd 等命令行工具,通过 --id 和 --keyring 选项指定要使用的用户帐户和密钥环文件。未指定时,命令会以 client.admin 用户进行身份验证。

示例:ceph 命令会以 client.operator3 进行身份验证并列出可用池。

bash 复制代码
# ceph --id operator3 osd lspools
  • 使用 --id 选项,不要添加 client. 前缀。
  • 使用 --name 选项,需要 client. 前缀。
  • 如果密钥环文件存储在默认的位置,则用户不需要 --keyring 选项。cephadm shell 会自动从 /etc/ceph/ 目录挂载密钥环。

Cephx 协议通信原理

**Cephx 协议使用共享机密密钥加密通信。**简要通信过程如下:

  • 客户端向监控器请求会话密钥,同时传递共享秘钥给监视器。
  • 监视器使用客户端的共享机密密钥加密会话密钥,再将会话密钥提供给客户端。
  • 由客户端解密会话密钥,然后再从监控器请求票据,以便对集群守护进程进行身份验证。

Cephx 使用共享密钥进行身份验证, 客户端和MON群集都保存着共享秘钥副本。

Cephx 协议的认证流程:

  1. client 向 MON 请求会话秘钥。

  2. MON 创建会话秘钥,同时将产生的会话秘钥分享给 MDS 和 OSD。

  3. MON 使用共享密钥加密会话密钥,并返回给 client。client 使用共享秘钥解密数据,获得会话密钥。

    后续通信都使用会话秘钥进行加密和解密。

  4. client 然后使用会话密钥加密会话,向 MON 请求票据数据。MON 使用会话密钥解密客户端请求,并创建 ticket,使用会话密钥加密返回给 client。client 使用会话密钥解密数据收到ticket。

  5. client 使用ticket与MDS和OSD进行交互。由于client、MDS和OSD都拥有MON产生的秘钥,因此它们之间可以验证ticket是否合法。

管理用户账户

查看用户账户

要列出现有用户帐户,可运行 ceph auth ls 或者 ceph auth list 命令。

bash 复制代码
[root@ceph1 ~]# ceph auth list
osd.0
        key: AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
......

要获取特定帐户的详细信息,可使用 ceph auth get 命令。

bash 复制代码
[root@ceph1 ~]# ceph auth get osd.0
[osd.0]
        key = AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
        caps mgr = "allow profile osd"
        caps mon = "allow profile osd"
        caps osd = "allow *"
exported keyring for osd.0

要获取特定帐户的key内容,可使用命令:

  • ceph auth get-key
  • ceph auth print-key
  • ceph auth print_key
bash 复制代码
[root@ceph1 ~]# ceph auth get-key osd.0
AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
[root@ceph1 ~]# ceph auth print-key osd.0
AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
[root@ceph1 ~]# ceph auth print_key osd.0
AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==

创建用户账户

要创建用户帐户,可使用命令:

  • ceph auth add
  • ceph auth get-or-create
  • ceph auth get-or-create-key
bash 复制代码
[root@ceph1 ~]# ceph auth add client.app1
added key for client.app1

[root@ceph1 ~]# ceph auth get-or-create client.app2
[client.app2]
        key = AQC2vKZoZQzOCRAAWn6PfXhyMxh3/i4KTTvKQg==
        
[root@ceph1 ~]# ceph auth get-or-create-key client.app3
AQDFvKZoF8/iDxAAV7gMq2lnCQcLs9NAQGH5Kg==

还可以在创建用户账户的时候,赋予用户账户权限。

赋予用户账户权限,稍后讲解。

bash 复制代码
[root@ceph1 ~]# ceph auth add client.app4 mon 'allow r'
added key for client.app4

删除用户账户

要创建用户帐户,可使用命令:

  • ceph auth del
  • ceph auth rm
bash 复制代码
[root@ceph1 ~]# ceph auth del client.app3
updated

[root@ceph1 ~]# ceph auth rm client.app2
updated

[root@ceph1 ~]# ceph auth ls | grep client.app
installed auth entries:

client.app1
client.app4

导出和导入用户账户

要导出特定帐户的详细信息,可使用命令:

  • ceph auth export -o
  • ceph auth get -o
bash 复制代码
[root@ceph1 ~]# ceph auth export osd.0 -o ceph.osd.0.keyring.1
export auth(key=AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==)
[root@ceph1 ~]# cat ceph.osd.0.keyring.1
[osd.0]
        key = AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
        caps mgr = "allow profile osd"
        caps mon = "allow profile osd"
        caps osd = "allow *"

[root@ceph1 ~]# ceph auth get osd.0 -o ceph.osd.0.keyring.2
exported keyring for osd.0
[root@ceph1 ~]# cat ceph.osd.0.keyring.2
[osd.0]
        key = AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
        caps mgr = "allow profile osd"
        caps mon = "allow profile osd"
        caps osd = "allow *"

要导入特定帐户的详细信息,可使用 ceph auth import -i 命令。

bash 复制代码
# 先导出client.app4然后删除client.app4
[root@ceph1 ~]# ceph auth export client.app4 -o ceph.client.app4.keyring
export auth(key=AQDnvKZoY7irCRAA5ap2HQ1nQ2ADHSJRJWtczw==)
[root@ceph1 ~]# ceph auth rm client.app4
updated
[root@ceph1 ~]# ceph auth get client.app4
Error ENOENT: failed to find client.app4 in keyring

# 将刚才删除的client.app4导入观察现象
[root@ceph1 ~]# ceph auth import -i ceph.client.app4.keyring
imported keyring
[root@ceph1 ~]# ceph auth get client.app4
[client.app4]
        key = AQDnvKZoY7irCRAA5ap2HQ1nQ2ADHSJRJWtczw==
        caps mon = "allow r"
exported keyring for client.app4

配置用户账户功能

用户账户功能

cephx 中的权限称为功能,使用功能来限制或提供对池中数据、池的命名空间或一组池的访问权限。功能还允许集群中的守护进程之间互相交互。通过守护进程类型(mon、osd、mgr 或 mds)来授予它们。

在 cephx 内,对于每个守护进程类型来说,都有多项功能可用:

  • allow,在守护进程的访问权限之前设置。
  • **r,授予读取访问权限。**每一用户帐户至少应在监控器上具有读取访问权限,以便能够检索 CRUSH 映射。
  • **w,授予写入访问权限。**客户端需要写入访问权限以在 OSD 上存储和修改对象。对于管理器 (MGR),w 授予启用或禁用模块的权限。
  • **x,授予执行扩展对象类的权限。**让用户能够调用类方法(即读取和写入)并对监控器执行身份验证操作。这使得客户端能够在对象上执行额外的操作,如使用 rados lock get 设置锁定或使用 rbd list 列出 RBD 镜像。
  • **class-read ,让用户能够调用类读取方法。**x 的子集。通常用在 RBD 池中。
  • **class-write,让用户能够调用类写入方法。**x 的子集。通常用在 RBD 池中。
  • ***,授予完整访问权限。**授予用户对特定守护进程或池的读取、写入和执行权限,并允许用户执行管 理命令。

要赋予用户帐户功能,可运行 ceph auth caps 命令,运行该命令前确保用户账户已创建。

示例:

bash 复制代码
[root@ceph1 ~]# ceph auth add client.laogao
added key for client.laogao
[root@ceph1 ~]# ceph auth caps client.laogao mon 'allow r' osd 'allow rw'
updated caps for client.laogao

在创建用户账户时,直接赋予权限。

bash 复制代码
[root@ceph1 ~]# ceph auth add client.laogao mon 'allow r' osd 'allow rw'

用户账户功能配置文件

创建用户帐户时,可使用cephx 预定义的功能配置文件:

  • 简化用户访问权限配置。
  • 实现守护进程之间的内部通信。
  • Ceph 会在内部定义这些文件,用户无法自行创建配置文件。

cephx 预定义的部分功能配置文件如下:

  • osd,授予用户作为 OSD 连接其他 OSD 或监控器的权限, 以便 OSD 能够 处理复制心跳流量和状态报告。

    bash 复制代码
    [root@ceph1 ~]# ceph auth get osd.1
    [osd.1]
            key = AQA8EqRoxyM2OBAAQuVUxOvvVZL7Ydg4niwLPQ==
            caps mgr = "allow profile osd"
            caps mon = "allow profile osd"
            caps osd = "allow *"
    exported keyring for osd.1
  • bootstrap-osd,授予用户引导 OSD 的权限,以便他们在引导 OSD 时具有添加密钥的权限。

    bash 复制代码
    [root@ceph1 ~]# ceph auth get client.bootstrap-osd
    [client.bootstrap-osd]
            key = AQCgDqRoAD+sABAAP2icy5PAW2sgh8sU/An5Pw==
            caps mon = "allow profile bootstrap-osd"
    exported keyring for client.bootstrap-osd
  • rbd,授予用户读写访问 Ceph 块设备的权限。

  • rbd-read-only,授予用户只读访问 Ceph 块设备的权限。

示例:

bash 复制代码
[root@ceph1 ~]# ceph auth add client.forrbd mon 'profile rbd' osd 'profile rbd'
added key for client.forrbd

[root@ceph1 ~]# ceph auth get client.forrbd
[client.forrbd]
        key = AQDLwqZo4W28KxAA8onfLsxAxUvYt2cKq+comQ==
        caps mon = "profile rbd"
        caps osd = "profile rbd"
exported keyring for client.forrbd

限制访问范围

  • 池,限制用户只能访问他们需要的池。

    示例:

    bash 复制代码
    [root@ceph1 ~]# ceph auth get-or-create client.formyapp1 mon 'allow r' osd 'allow rw pool=myapp'
    [client.formyapp1]
            key = AQAMxqZodL12BhAA0IyPEV6SqT+9cLpr+k1DPw==

    如果在配置功能时不指定池,则 Ceph 会将它们设置到所有现有的池。

  • 命名空间,限制用户帐户仅访问从属于特定命名空间中对象。

    示例:

    bash 复制代码
    [root@ceph1 ~]# ceph auth get-or-create client.formyapp2 mon 'allow r' osd 'allow rw namespace=photos'
    [client.formyapp2]
            key = AQA6xqZolcVtBxAAMGJtK4hes9LLfuwaoTnMFA==
  • 池和命名空间,限制用户帐户仅访问特定池中特定命名空间中对象。

    示例:

    bash 复制代码
    [root@ceph1 ~]# ceph auth get-or-create client.formyapp3 mon 'allow r' osd 'allow rw pool=myapp namespace=photos'
    [client.formyapp3]
            key = AQBmxqZo9uExExAAePkx63ERHvgGmMiEJd4GEg==
  • 对象名称前缀,限制用户帐户仅访问特定名称前缀的对象。

    示例:

    bash 复制代码
    [root@ceph1 ~]# ceph auth get-or-create client.formyapp4 mon 'allow r' osd 'allow rw object_prefix pref'
    [client.formyapp4]
            key = AQCYxqZorsmOHxAAlQMGO+Ouv719SN1/BLpy8w==
  • 文件路径,限制用户帐户仅访问 Ceph 文件系统 (CephFS) 中特定目录。

    示例:

    bash 复制代码
    # ceph fs authorize cephfs client.webdesigner /webcontent rw   
  • monitor 命令,限制用户帐户只能使用一组特定的命令。

    示例:

    bash 复制代码
    [root@ceph1 ~]# ceph auth get-or-create client.operator1 mon 'allow r, allow command "auth get-or-create", allow command "auth list"'
    [client.operator1]
            key = AQDdxqZotZpCFRAAI1DFw519uGF/EbAF2KB6GQ==

实践1:创建一个可执行ceph auth list的用户,并使用该用户执行该命令

bash 复制代码
[root@ceph1 ~]# ceph auth get-or-create client.gaoqiaodong mon 'allow r,allow command "auth list"'
[client.gaoqiaodong]
        key = AQCn56Zo8hxHFxAA1GnGWHE9RRGe6TnglJIoVg==

[root@ceph1 ~]# ceph auth get client.gaoqiaodong -o /etc/ceph/ceph.client.gaoqiaodong.keyring
exported keyring for client.gaoqiaodong

[root@ceph1 ~]# ceph auth ls --id gaoqiaodong      #执行等同于auth list的auth ls都不行
Error EACCES: access denied
[root@ceph1 ~]# ceph auth list --id gaoqiaodong       
osd.0
        key: AQA8EqRojLYOOBAAVprA9Rs0Gkg4zK0dKZUUrA==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
......

实践2:通过client管理ceph

client:

bash 复制代码
[root@client ~]# mkdir /etc/ceph

[root@client ~]# cat << 'EOF' > /etc/yum.repos.d/ceph.repo
[Ceph]
name=Ceph 
baseurl=https://mirrors.aliyun.com/centos-vault/8-stream/storage/x86_64/ceph-pacific
enabled=1
gpgcheck=0
EOF

[root@client ~]# dnf install -y ceph-common

ceph1:

bash 复制代码
# 将/etc/ceph/ceph.client.admin.keyring拷贝到client
[root@ceph1 ~]# scp /etc/ceph/ceph.client.admin.keyring root@client:/etc/ceph/
# 将/etc/ceph.conf拷贝到cleint
[root@ceph1 ~]# scp /etc/ceph/ceph.conf root@client:/etc/ceph/       

client:

bash 复制代码
[root@client ~]# ceph -s
  cluster:
    id:     2faf683a-7cbf-11f0-b5ba-000c29e0ad0e
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum ceph1.laogao.cloud,ceph2,ceph3 (age 3h)
    mgr: ceph2.oetbal(active, since 3h), standbys: ceph1.laogao.cloud.zoqmbt, ceph3.npaxvt
    osd: 9 osds: 9 up (since 3h), 9 in (since 2d)

  data:
    pools:   1 pools, 1 pgs
    objects: 0 objects, 0 B
    usage:   2.6 GiB used, 177 GiB / 180 GiB avail
    pgs:     1 active+clean
相关推荐
我们从未走散3 小时前
从内存字典到租约内核:分布式上游账号池如何做到不超卖
分布式
.冰块.4 小时前
Ceph 分布式存储实战(一):架构入门与 cephadm 集群部署
分布式·ceph·架构·cephadm
j7~5 小时前
【Redis】《一文走完服务端高并发架构演进:从单机架构到 K8S 容器编排》
分布式·架构演进·服务端高并发分布式结构演进之路·架构基本概念·架构评价指标
Flynt5 小时前
把 bug tracker 塞进 git 仓库,同步和冲突怎么解决?我把 git-bug 拆开实测了一遍
分布式·git·开源
灯澜忆梦1 天前
【RabbitMQ #3】 | Go 客户端 + SpringAMQP
分布式·golang·rabbitmq
Q26433650231 天前
【有源码】基于Spark的电商客户细分与盈利洞察分析系统-面向精准营销的电商客户细分模型构建与盈利能力可视化研究
大数据·hadoop·分布式·数据挖掘·数据分析·spark·毕业设计
fengkai45451 天前
十、Ceph 分布式存储5-8
运维·ceph·容器
新思维软件1 天前
基于无线传输的地衡系统:三节点 LoRa 组网与 MQTT 上云的分布式称重方案
分布式·stm32·单片机·嵌入式硬件·物联网·物联网开发
俊哥大数据1 天前
Flink1.20.3 实时消费 Kafka 数据并解析入湖 Paimon1.4.2 全流程实战
分布式·flink·kafka·数据湖·paimon