ceph(5-8)

文章目录

ceph

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 dyx"

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

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

密钥环文件

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

Ceph 根据 /etc/ceph/ceph.conf 配置文件中的 keyring 参数查找密钥环文件,默认值为/etc/ceph/ c l u s t e r . 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 使用共享秘钥解密数据,获得会话密钥。

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

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

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

管理用户账户

查看用户账户

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

bash 复制代码
[root@ceph1 ~ 14:34:18]# ceph auth list
osd.0
        key: AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
osd.1
        key: AQBOmyZpIGJCKBAAXXqnGRSmtZYVQP++gQH/Kg==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
... ...

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

bash 复制代码
[root@ceph1 ~ 14:34:36]# ceph auth get osd.0
[osd.0]
        key = AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
        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 ~ 14:34:47]# ceph auth get-key osd.0
AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==[root@ceph1 ~ 14:35:04]# ceph auth print-key osd.0
AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==[root@ceph1 ~ 14:35:20]# ceph auth print_key 
osdAQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
创建用户账户

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

  • ceph auth add

  • ceph auth get-or-create

  • ceph auth get-or-create-key

bash 复制代码
[root@ceph1 ~ 14:35:26]# ceph auth add client.app1
added key for client.app1
[root@ceph1 ~ 14:35:52]# ceph auth get-or-create client.app2
[client.app2]
        key = AQDcQilpOkCXMRAASOxF412O/RKpC9QZ+v2g5A==
[root@ceph1 ~ 14:36:12]# ceph auth get-or-create-key client.app3
AQDpQilpGl21DRAATu8mP542pl+9DmqX9Kz41A==

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

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

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

[root@ceph1 ~ 14:37:00]# ceph auth get client.app1
[client.app1]
        key = AQDIQilpmh9dJBAAGgDatq/NXhez9Jwj2uvlkg==
exported keyring for client.app1
[root@ceph1 ~ 14:37:10]# ceph auth get client.app4
[client.app4]
        key = AQD8Qilpa6D5KhAAXR31cmgnzAboUy+6fy1auQ==
        caps mon = "allow r"
exported keyring for client.app4

删除用户账户

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

  • ceph auth del

  • ceph auth rm

bash 复制代码
[root@ceph1 ~ 14:37:13]# ceph auth del client.app3
3updated
[root@ceph1 ~ 14:37:25]# ceph auth rm client.app2
updated
[root@ceph1 ~ 14:37:40]# ceph auth ls |grep client.app
installed auth entries:

client.app1
client.app4

导出和导入用户账户

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

  • ceph auth export -o

  • ceph auth get -o

bash 复制代码
[root@ceph1 ~ 14:37:53]# ceph auth export osd.0 -o ceph.osd.0.keyring.1
export auth(key=AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==)
[root@ceph1 ~ 14:38:22]# cat ceph.osd.0.keyring.1
[osd.0]
        key = AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
        caps mgr = "allow profile osd"
        caps mon = "allow profile osd"
        caps osd = "allow *"


[root@ceph1 ~ 14:38:30]# ceph auth get osd.0 -o ceph.osd.0.ketring.2
exported keyring for osd.0
[root@ceph1 ~ 14:38:55]# cat ceph.osd.0.ketring.2
[osd.0]
        key = AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
        caps mgr = "allow profile osd"
        caps mon = "allow profile osd"
        caps osd = "allow *"

要导入特定帐户的详细信息,可使用 **ceph auth import -i **命令。用户账户功能配置文件

bash 复制代码
# 先导出client.app4然后删除client.app4
[root@ceph1 ~ 14:39:01]# ceph auth export client.app4 -o ceph.client.app4.ketring
export auth(key=AQD8Qilpa6D5KhAAXR31cmgnzAboUy+6fy1auQ==)
[root@ceph1 ~ 14:39:28]# ceph auth rm client.app4
updated
[root@ceph1 ~ 14:39:42]# ceph auth get client.app4
Error ENOENT: failed to find client.app4 in keyring

# 将刚才删除的client.app4导入观察现象
[root@ceph1 ~ 14:39:50]# ceph auth import -i ceph.client.app4.ketring
imported keyring
[root@ceph1 ~ 14:40:07]# ceph auth get client.app4
[client.app4]
        key = AQD8Qilpa6D5KhAAXR31cmgnzAboUy+6fy1auQ==
        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 设置锁定或使用 rbdlist 列出 RBD 镜像。

  • class-read **,让用户能够调用类读取方法。**x 的子集。通常用在 RBD 池中。

  • class-write**,让用户能够调用类写入方法。**x 的子集。通常用在 RBD 池中。

  • ***,授予完整访问权限。**授予用户对特定守护进程或池的读取、写入和执行权限,并允许用户执行管理命令。

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

示例:

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

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

bash 复制代码
[root@ceph1 ~]# ceph auth add client.dyx mon 'allow r' osd 'allow rw'
用户账户功能配置文件

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

  • 简化用户访问权限配置。

  • 实现守护进程之间的内部通信。

  • Ceph 会在内部定义这些文件,用户无法自行创建配置文件

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

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

    bash 复制代码
    [root@ceph1 ~ 15:23:30]# ceph auth get osd.1
    [osd.1]
            key = AQBOmyZpIGJCKBAAXXqnGRSmtZYVQP++gQH/Kg==
            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 ~ 15:24:18]# ceph auth get client.bootstrap-osd
    [client.bootstrap-osd]
            key = AQDbdiZpFOovBRAA7+s5MODn+BpBURcNaPT0bA==
            caps mon = "allow profile bootstrap-osd"
    exported keyring for client.bootstrap-osd
  • rbd,授予用户读写访问 Ceph 块设备的权限。

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

示例:

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

[root@ceph1 ~ 15:25:17]# ceph auth get client.forrbd
[client.forrbd]
        key = AQBdTilpOc8gMBAAoomns/HQSkpQPiC0CTcXWg==
        caps mon = "profile rbd"
        caps osd = "profile rbd"
exported keyring for client.forrbd
限制访问范围
  • ,限制用户只能访问他们需要的池。

    示例:

    bash 复制代码
    [root@ceph1 ~ 15:25:30]# ceph auth get-or-create client.formyapp  mon 'allow r' osd 'allow rw pool=myapp'
    [client.formyapp]
            key = AQCWTilpXPjpBBAAisAk39wQSWnIpARJGVbUqA==

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

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

    示例:

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

    示例:

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

    示例:

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

    示例:

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

    示例:

    bash 复制代码
    [root@ceph1 ~ 15:29:13]# ceph auth get-or-create client.operator1 mon 'allow r,allow command "auth get-or-create",allow command "auth list"'
    [client.operator1]
            key = AQCkTylpM7ZQNBAAvi51zZ7D3b7D1oCPSaZPgA==

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

bash 复制代码
[root@ceph1 ~ 15:31:23]# ceph auth get-or-create client.dyx mon 'allow r,allow command "auth list"'
[client.dyx]
        key = AQDUTylpvLVbFBAAfD/sj6ZdZLSIn5RpgegRJg==
        
[root@ceph1 ~ 15:31:23]# ceph auth get-or-create client.dyx mon 'allow r,allow command "auth list"'
[client.dyx]
        key = AQDUTylpvLVbFBAAfD/sj6ZdZLSIn5RpgegRJg==
        
 #执行等同于auth list的auth ls都不行
 [root@ceph1 ~ 15:32:42]# ceph auth ls --id dyx
Error EACCES: access denied
[root@ceph1 ~ 15:32:54]# ceph auth list --id dyx
osd.0
        key: AQBOmyZpzkYFJBAAnS+YQLNv3RYz2syyddqIOw==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
osd.1
        key: AQBOmyZpIGJCKBAAXXqnGRSmtZYVQP++gQH/Kg==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *
osd.2
        key: AQBOmyZpeO2PKxAAb/yV9ka4XjQYTeRrjjaEuw==
        caps: [mgr] allow profile osd
        caps: [mon] allow profile osd
        caps: [osd] allow *

实践2:通过client管理ceph

bash 复制代码
[root@client ~ 16:06:23]# 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

client:

bash 复制代码
[root@client ~ 16:10:06]# mkdir /etc/ceph
[root@client ~ 16:10:42]# dnf install -y ceph-common
Ceph                                                    1.5 MB/s | 568 kB     00:00
CentOS Stream 8 - BaseOS                                 46 kB/s | 3.9 kB     00:00

... ...
  userspace-rcu-0.10.1-4.el8.x86_64

Complete!

ceph1:

bash 复制代码
# 将/etc/ceph/ceph.client.admin.keyring拷贝到client
[root@ceph1 ~ 16:11:19]# scp /etc/ceph/ceph.client.admin.keyring root@client:/etc/ceph/
The authenticity of host 'client (192.168.108.10)' can't be established.
ECDSA key fingerprint is SHA256:nOUFHRdr1rBwIb8vZxcNTeRARPN3k9zMIhLlYKBu0LE.
Are you sure you want to continue connecting (yes/no/[fingerprint])? `yes`
Warning: Permanently added 'client,192.168.108.10' (ECDSA) to the list of known hosts.
root@client's password:`123`
ceph.client.admin.keyring                             100%  151   139.3KB/s   00:00

# 将/etc/ceph.conf拷贝到cleint
[root@ceph1 ~ 16:12:07]# scp /etc/ceph/ceph.conf root@client:/etc/ceph/
root@client's password: `123`
ceph.conf                                             100%  283   304.5KB/s   00:00

client:

bash 复制代码
[root@client ~ 16:12:50]# ceph -s
  cluster:
    id:     bc5b5200-ca79-11f0-9e78-000c2974062f
    health: HEALTH_WARN
            Degraded data redundancy: 32 pgs undersized

  services:
    mon: 3 daemons, quorum ceph1.dyx.cloud,ceph2,ceph3 (age 2h)
    mgr: ceph3.bwnrnx(active, since 6h), standbys: ceph2.dvnrax, ceph1.dyx.cloud.ilnlbd
    osd: 9 osds: 9 up (since 2h), 9 in (since 2d)

  data:
    pools:   2 pools, 33 pgs
    objects: 3 objects, 0 B
    usage:   2.6 GiB used, 177 GiB / 180 GiB avail
    pgs:     32 active+undersized
             1  active+clean

第6章Ceph分布式存储 块存储管理

管理 RADOS 块设备

RADOS 块设备

块设备是服务器、笔记本电脑和其他计算系统上最为常见的长期存储设备。它们以固定大小的块存储数

**据。**块设备包括基于旋转磁盘的硬盘驱动器,以及基于非易失性存储器的固态驱动器。若要使用存储,

用户要使用文件系统格式化块设备,并将它挂载到 Linux 文件系统层次结构中。

Ceph 存储集群的RADOS 块设备 (RBD) 功能 提供虚拟块设备,并以RBD 镜像形式存储在Ceph 存储集群

的池中。

创建 RBD 镜像

存储管理员使用 rbd 命令来创建、列出、检索信息、调整大小和删除块设备镜像。

  • 创建 rbd 。使用 ceph osd pool create 命令来创建用于存储 RBD 镜像池,并使用 rbd pool

    init 命令进行初始化池。

    bash 复制代码
    [root@ceph1 ~ 09:56:59]# ceph osd pool create images_pool
    pool 'images_pool' created
    
    #等同于ceph osd pool
    [root@ceph1 ~ 09:57:05]# rbd pool init images_pool
    
    [root@ceph1 ~ 09:57:26]# 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 44 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr_devicehealth
    pool 2 'images_pool' 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,selfmanaged_snaps stripe_width 0 `application rbd`
    
    
    [root@ceph1 ~ 09:57:53]# ceph osd pool ls detail|grep images_pool
    pool 2 'images_pool' 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,selfmanaged_snaps stripe_width 0 `application rbd`
  • 创建专用用户。虽然 Ceph 管理员可以访问这个池,但建议使用受限制的 Cephx 用户访问 rbd池,仅向该受限用户授予所需 RBD 池的读写权限,而非整个集群的访问权限。

    bash 复制代码
    [root@ceph1 ~ 09:59:16]# ceph auth get-or-create client.rbd mon 'profile rbd' osd 'profile rbd' -o /etc/ceph/ceph.client.rbd.keyring
  • 创建 RBD 镜像。

    bash 复制代码
    [root@ceph1 ~ 09:59:37]# rbd create images_pool/webapp1 --size 1G
    [root@ceph1 ~ 09:59:56]# rbd ls images_pool
    webapp1
    [root@ceph1 ~ 10:00:05]# rbd ls images_pool
    webapp1
    [root@ceph1 ~ 10:00:15]# rbd pool stats images_pool
    Total Images: 1
    Total Snapshots: 0
    Provisioned Size: 1 GiB

    如果用户不指定池名称,此命令会使用默认的池名称,默认的池名称由 rbd_default_pool 参数指定。使用 ceph config set osd rbd_default_pool value 设置此参数。

访问 RADOS 块设备存储

访问 RADOS 块设备存储方法:

  • 使用 KRBD, 客户端 krbd 模块将 RBD 镜像映射为 Linux 块设备。

  • 使用 librbd ,将 RBD 存储提供给 KVM 虚拟机和 OpenStack 云实例。这些客户端使得裸机恢复服务器或虚拟机像普通的块存储一样使用 RBD镜像。在 OpenStack 环境中,OpenStack 将这些RBD 镜像连接并映射到 Linux 服务器,在那里它们可以充当引导设备。

Ceph 存储将虚拟设块设备使用的实际存储分散在集群中,以利用 IP网络提供高性能访问。

使用内核RBD(KRBD)访问Ceph块存储
映射 RBD 镜像

Ceph 客户端可以使用原生 Linux 内核模块 (krbd) 挂载 RBD 镜像。这个模块使用 /dev/rbd0 之类的名称将 RBD 镜像映射到 Linux 块设备。

示例:将 images_pool 池中的 webapp1 镜像映射为client上 /dev/rbd0 设备。

bash 复制代码
#client上操作:
[root@client ~ 10:41:44]# dnf install -y ceph-common
#ceph1上操作:
[root@ceph1 ~]# scp /etc/ceph/ceph.conf /etc/ceph/ceph.client.rbd.keyring
root@client:/etc/ceph

# 在客户端 client 上操作
[root@client ~ 10:42:16]# rbd --id rbd ls images_pool
webapp1

# 为了简化命令参数,定义CEPH_ARGS环境变量,确保ceph相关命令使用该环境变量提供的默认值。
[root@client ~ 10:43:33]# export CEPH_ARGS='--id=rbd'
[root@client ~ 10:44:05]# rbd ls images_pool
webapp1

# 使用 krbd 内核模块来映射镜像
[root@client ~ 10:44:23]# rbd device map images_pool/webapp1
/dev/rbd0

[root@client ~ 10:44:35]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  200G  0 disk
├─sda1        8:1    0    1G  0 part /boot
└─sda2        8:2    0  199G  0 part
  ├─cs-root 253:0    0   70G  0 lvm  /
  ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
  └─cs-home 253:2    0  127G  0 lvm  /home
sr0          11:0    1 12.8G  0 rom
rbd0        252:0    0    1G  0 disk

Ceph 客户端系统可以像其他块设备一样使用映射的块设备,例如使用文件系统进行格式化、挂载和卸载。

bash 复制代码
# 列出计算机中映射的 RBD 镜像
[root@client ~ 10:44:38]# rbd showmapped
id  pool         namespace  image    snap  device
0   images_pool             webapp1  -     /dev/rbd0

# 或者,等于rbd device ls
[root@client ~ 10:44:49]# rbd device list
id  pool         namespace  image    snap  device
0   images_pool             webapp1  -     /dev/rbd0

# 格式化和挂载
[root@client ~ 10:44:58]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  200G  0 disk
├─sda1        8:1    0    1G  0 part /boot
└─sda2        8:2    0  199G  0 part
  ├─cs-root 253:0    0   70G  0 lvm  /
  ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
  └─cs-home 253:2    0  127G  0 lvm  /home
sr0          11:0    1 12.8G  0 rom
rbd0        252:0    0    1G  0 disk
[root@client ~ 10:45:02]# lsblk /dev/rbd0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
rbd0 252:0    0   1G  0 disk
[root@client ~ 10:45:10]# mkfs.xfs /dev/rbd0
meta-data=/dev/rbd0              isize=512    agcount=8, agsize=32768 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=16     swidth=16 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
Discarding blocks...Done.
[root@client ~ 10:45:25]# mkdir -p /webapp/webapp1
[root@client ~ 10:45:39]# mount /dev/rbd0 /webapp/webapp1/
#已经挂载
[root@client ~ 10:45:50]# lsblk /dev/rbd0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
rbd0 252:0    0   1G  0 disk `/webapp/webapp1`

[root@client ~ 10:45:57]# echo hello world > /webapp/webapp1/index.html
[root@client ~ 10:46:16]# cat /webapp/webapp1/index.html
hello world

[root@client ~ 10:46:20]# df /webapp/webapp1/
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/rbd0        1038336 40504    997832   4% /webapp/webapp1


[root@client ~ 10:46:43]# rbd status images_pool/webapp1
Watchers:
        watcher=192.168.108.10:0/2072161355 client.54209 cookie=18446462598732840961

取消映射 RBD 镜像,使用以下命令:

bash 复制代码
# 先卸载改设备
[root@client ~ 10:47:04]# umount /webapp/webapp1/

# 取消映射
# rbd unmap images_pool/webapp1也可以
[root@client ~ 10:47:22]# rbd unmap /dev/rbd0

#查看现象
[root@client ~ 10:47:33]# rbd device ls

# 或者
[root@client ~ 10:47:48]# rbd device unmap /dev/rbd0
rbd: '/dev/rbd0' is not a block device
rbd: unmap failed: (22) Invalid argument

注意:rbd map 和 rbd unmap 命令需要 root 特权。

**==注意:==两个客户端可以同时将同一个RBD镜像映射为块设备。**但如果块设备含有普通的单挂载文件系统,则建议每次将数据块设备连接到一个客户端。如果将含有普通文件系统的 RADOS 块设备同时挂载到两个或多个客户端上,可能会造成文件系统损坏和数据丢失。

持久映射 RBD 镜像

rbdmap 服务可在系统启动自动映射 RBD **镜像到系统。**此服务在 /etc/ceph/rbdmap 文件中查找已映射的镜像及其凭据。当 系统识别到 RBD 镜像时,读取 /etc/fstab 文件中记录,并挂载镜像。

下列步骤对 rbdmap 进行配置,以持久映射已包含文件系统的 RBD 镜像:

  1. 在 /etc/ceph/rbdmap RBD 映射文件内创建一个单行条目。此条目必须指定 RBD 池和镜像的名称。还必须引用 Cephx 用户,该用户具有镜像的读写权限并且具有相应的密钥环文件。确保客户端系统上存在 Cephx 用户的密钥环文件。

    bash 复制代码
    [root@client ~ 12:26:13]# yum install -y vim
    [root@client ~ 12:26:38]# vim /etc/ceph/rbdmap
    [root@client ~ 12:27:53]# cat /etc/ceph/rbdmap
    # RbdDevice             Parameters
    #poolname/imagename     id=client,keyring=/etc/ceph/ceph.client.keyring
    images_pool/webapp1 id=rbd,keyring=/etc/ceph/ceph.client.rbd.keyring
  2. 在客户端系统上的 /etc/fstab 文件中为 RBD 创建一个条目。

块设备的名称:/dev/rbd/pool_name/image_name,指定 _netdev 挂载选项,等待 rbdmap 服务映射镜像后,再挂载文件系统。

bash 复制代码
[root@client ~ 12:27:13]# vim /etc/fstab
[root@client ~ 12:28:12]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Wed Oct 22 02:55:44 2025
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/cs-root     /                       xfs     defaults        0 0
UUID=d204fa67-28d1-4fa5-97fe-6bc0b96d63c7 /boot                   xfs     defaults        0 0
/dev/mapper/cs-home     /home                   xfs     defaults        0 0
/dev/mapper/cs-swap     none                    swap    defaults        0 0
`/dev/rbd/images_pool/webapp1 /webapp/webapp1 xfs _netdev 0 0`
  1. 确认块设备映射正常工作。使用 rbdmap map 和 rbdmap unmap 命令来挂载和卸载镜像。

  2. 启用 rbdmap systemd 服务。

bash 复制代码
[root@client ~ 12:27:44]# systemctl enable rbdmap.service
Created symlink /etc/systemd/system/multi-user.target.wants/rbdmap.service → /usr/lib/systemd/system/rbdmap.service.
  1. 重启系统验证。
bash 复制代码
[root@client ~ 12:27:49]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  200G  0 disk
├─sda1        8:1    0    1G  0 part /boot
└─sda2        8:2    0  199G  0 part
  ├─cs-root 253:0    0   70G  0 lvm  /
  ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
  └─cs-home 253:2    0  127G  0 lvm  /home
sr0          11:0    1 12.8G  0 rom

#开机自动挂载
[root@client ~ 12:28:19]# reboot
[root@client ~ 12:29:35]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  200G  0 disk
├─sda1        8:1    0    1G  0 part /boot
└─sda2        8:2    0  199G  0 part
  ├─cs-root 253:0    0   70G  0 lvm  /
  ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
  └─cs-home 253:2    0  127G  0 lvm  /home
sr0          11:0    1 12.8G  0 rom
`rbd0        252:0    0    1G  0 disk /webapp/webapp1`

如需更多信息,请参见 rbdmap(8)。

使用 librbd 库访问 Ceph块存储-配合虚拟化
使用 librbd 库访问 Ceph 块存储

librbd 库为用户空间应用提供对 RBD 镜像的直接访问。它继承 librados 的功能,将数据块映射到 Ceph对象存储中的对象,并且实施相关的功能来访问 RBD 镜像和创建快照与克隆。

OpenStack libvirt 等云和虚拟化解决方案使用 librbd RBD **镜像作为块设备提供给它们管理的云实例和虚拟机。**例如,RBD 镜像可以存储 QEMU 虚拟机镜像。

  • 使用 RBD 克隆功能时,虚拟化容器可以在不复制引导镜像的情况下引导虚拟机。

  • 使用写时复制 (COW) 机制,在将数据写入到克隆中的未分配对象时,会将数据从父级复制到克隆。

  • 使用读时复制 (COR) 机制,在从克隆中的未分配对象读取数据时,会将数据从父级复制到克隆。

RBD 缓存

Ceph 块设备是在用户空间实施(如 librbd),无法利用 Linux 页面缓存。Ceph 块设备会使用Linux系统自己的内存中缓存 ,称为 RBD 缓存。RBD 缓存的行为与 Linux 页面缓存相似。操作系统实施阻碍机制或清空请求时,Ceph 会将所有脏数据写入到 OSD。这意味着,在虚拟机正确发送清空时(例如,Linux内核 >= 2.6.32),使用回写缓存与使用物理硬盘缓存一样安全。缓存采用"最早使用"(LRU) 算法,而且在回写模式中,它可以联合毗邻的请求来获得更佳的吞吐量。

RBD 缓存对客户端而言是本地的,因为它使用发起 I/O 请求的计算机上的 **RAM。**例如,如果用户的OpenStack 平台安装中有 Nova 计算节点,并且它们将 librbd 用于其虚拟机,则发起 I/O 请求的OpenStack 客户端会将本地 RAM 用于其 RBD 缓存。

RBD 缓存模式
  • 未启用缓存,读取和写入前往 Ceph 对象存储。数据在写入所有相关的 OSD 日志和写入 OSD 设备完成后,Ceph 集群确认写入。

  • 回写缓存(write-back) ,需要考量两个值:未清空缓存字节数 U最大脏缓存字节数 M。如果U < M,则此时缓存写入完成即确认写入完成,否则在数据写回到磁盘后确认,直到 U < M 为止。

  • 直写缓存(Write-through) ,将最大脏字节数设置为 0,以强制使用直写模式。数据首先写入缓存,然后再写入所有相关的 OSD 日志和写入 OSD 设备完成后,Ceph 集群确认写入。使用直写模式,以最大程度降低服务器故障时数据丢失或文件系统损坏的风险,提供很好的读IO。

RBD 缓存参数
  • rbd_cache,定义是否启用 RBD 缓存,可用值 true 和 false,默认值true。

  • rbd_cache_policy,定义 RBD 缓存模式,可用值:

    • writearound,默认值,写入数据时不经过缓存直接写入后端硬盘。
    • writeback,回写。
    • writethrough,直写。
  • rbd_cache_size,定义每个 RBD 镜像的缓存大小,以字节为单位。默认值 32 MB。

  • rbd_cache_max_dirty,定义每个 RBD 镜像允许的最大脏字节数。默认值 24 MB。

  • rbd_cache_target_dirty,定义每个 RBD 镜像开始抢先清空的脏字节数。默认值 16 MB。

  • rbd_cache_max_dirty_age,定义清空前的最大页面期限,以秒为单位。默认值 1。

  • rbd_cache_writethrough_until_flush,定义启动直写模式,直至执行第一次清空,可用值 true和 false,默认值TRUE。

示例:查看并设置以上参数。

bash 复制代码
[root@ceph1 ~ 13:47:14]# ceph config ls |grep rbd_cache
rbd_cache
rbd_cache_policy
rbd_cache_writethrough_until_flush
rbd_cache_size
rbd_cache_max_dirty
rbd_cache_target_dirty
rbd_cache_max_dirty_age
rbd_cache_max_dirty_object
rbd_cache_block_writes_upfront

[root@ceph1 ~ 13:47:25]# for arg in $(ceph config ls |grep rbd_cache)
 do
 echo -n "$arg: "
 ceph config get client $arg
 done
rbd_cache: true
rbd_cache_policy: writearound
rbd_cache_writethrough_until_flush: true
rbd_cache_size: 33554432
rbd_cache_max_dirty: 25165824
rbd_cache_target_dirty: 16777216
rbd_cache_max_dirty_age: 1.000000
rbd_cache_max_dirty_object: 0
rbd_cache_block_writes_upfront: false

# 设置客户端
[root@ceph1 ~ 13:48:28]# ceph config set client rbd_cache_policy writethrough

[root@ceph1 ~ 13:49:20]# ceph config get client rbd_cache_policy
writethrough

# 设置全局
[root@ceph1 ~ 13:50:04]# ceph config set global rbd_cache_policy writethrough
RBD 镜像格式
RBD 镜像布局

RBD 镜像中的所有对象的名称以各个 RBD 块名称前缀字段中包含的值为开头,可使用rbd info 命令来显示。此前缀后是句点 (.),后跟对象编号。对象编号字段的值是 12 个字符的十六进制数字。

bash 复制代码
[root@client ~ 14:16:28]# rbd info images_pool/webapp1 --id rbd
rbd image 'webapp1':
        size 1 GiB in 256 objects
        order 22 (4 MiB objects)
        snapshot_count: 0
        id: d3cbc5a952d0
        block_name_prefix: rbd_data.d3cbc5a952d0
        format: 2
        features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
        op_features:
        flags:
        create_timestamp: Mon Dec  1 09:59:56 2025
        access_timestamp: Mon Dec  1 09:59:56 2025
        modify_timestamp: Mon Dec  1 09:59:56 2025

Ceph 块设备允许将数据分条存储在Ceph 存储集群中的多个对象存储设备 (OSD) 上。

RBD 镜像阶数

镜像阶数是用于定义 RBD **镜像的对象大小。**镜像阶数基于 <<(按位左移)C 运算符来定义二进制偏移值。此运算符按照右侧运算对象来偏移左侧运算对象。

例如,1 << 2 = 4。十进制 1 在二进制中是 1,因此 1 << 2 = 4 运算的结果是二进制的 100,也就是十进制的 4。

镜像阶数的值必须在12 到 25 之间,其中 12 = 4 KiB,13 = 8 KiB,以此类推。例如,镜像阶数默认为22,生成 4 MiB 对象。用户可使用 rbd create 命令的 --order 选项来覆盖默认值。

用户也可通过 --object-size **选项指定对象的大小。**此参数必须指定介于 4096 字节 (4 KiB) 和33,554,432字节 (32 MiB) 之间的对象大小,以字节、K 或 M 表示(例如,4096、8 K 或 4 M)。

bash 复制代码
[root@client ~ 14:16:36]# rbd help create
usage: rbd create [--pool <pool>] [--namespace <namespace>] [--image <image>]
                  [--image-format <image-format>] [--new-format]
                  [--order <order>] [--object-size <object-size>]
                  [--image-feature <image-feature>] [--image-shared]
                  [--stripe-unit <stripe-unit>]
                  [--stripe-count <stripe-count>] [--data-pool <data-pool>]
                  [--mirror-image-mode <mirror-image-mode>]
                  [--journal-splay-width <journal-splay-width>]
                  [--journal-object-size <journal-object-size>]
                  [--journal-pool <journal-pool>]
                  [--thick-provision] --size <size> [--no-progress]
                  <image-spec>

Create an empty image.

Positional arguments
  <image-spec>              image specification
                            (example: [<pool-name>/[<namespace>/]]<image-name>)

Optional arguments
  -p [ --pool ] arg         pool name
  --namespace arg           namespace name
  --image arg               image name
  --image-format arg        image format [default: 2]
  --object-size arg         object size in B/K/M [4K <= object size <= 32M]
  --image-feature arg       image features
                            [layering(+), exclusive-lock(+*), object-map(+*),
                            deep-flatten(+-), journaling(*)]
  --image-shared            shared image
  --stripe-unit arg         stripe unit in B/K/M
  --stripe-count arg        stripe count
  --data-pool arg           data pool
  --mirror-image-mode arg   mirror image mode [journal or snapshot]
  --journal-splay-width arg number of active journal objects
  --journal-object-size arg size of journal objects [4K <= size <= 64M]
  --journal-pool arg        pool for journal objects
  --thick-provision         fully allocate storage and zero image
  -s [ --size ] arg         image size (in M/G/T) [default: M]
  --no-progress             disable progress output

Image Features:
  (*) supports enabling/disabling on existing images
  (-) supports disabling-only on existing images
  (+) enabled by default for new images if features not specified
RBD 镜像格式

与每个 RBD 镜像关联的参数有三个:

  • image_format,RBD 镜像格式版本。默认值为 2,即最新的版本。版本 1 已弃用,而且不支持克隆和镜像等功能。

  • stripe_unit,一个对象中存储的连续字节数(默认为 object_size)。

  • stripe_count,一个条带跨越的 RBD 镜像对象数量(默认为 1)。

对于 RBD 格式 2 镜像,用户可以更改以上各个参数的值。设置必须与下列等式一致:

bash 复制代码
stripe_unit * stripe_count = object_size

例如: stripe_unit = 1048576, stripe_count = 8 for default 8 MiB objects

bash 复制代码
[root@client ~ 14:16:41]# rbd create --stripe-unit=1M -stripe-count=8 --size 1G images_pool/webapp2 --id rbd
rbd: the argument for option '--size' is invalid
[root@client ~ 14:16:54]# rbd create --stripe-unit=1M --stripe-count=8 --size 1G images_pool/webapp2 --id rbd
[root@client ~ 14:17:10]# rbd info images_pool/webapp2 --id rbd
rbd image 'webapp2':
        size 1 GiB in 256 objects
        order 22 (4 MiB objects)
        snapshot_count: 0
        id: d474d0cea2b3
        block_name_prefix: rbd_data.d474d0cea2b3
        format: 2
        features: layering, striping, exclusive-lock, object-map, fast-diff, deep-flatten
        op_features:
        flags:
        create_timestamp: Mon Dec  1 14:17:06 2025
        access_timestamp: Mon Dec  1 14:17:06 2025
        modify_timestamp: Mon Dec  1 14:17:06 2025
        stripe unit: 1 MiB
        stripe count: 8
使用 rbd 命令管理镜像
status

用于查看哪些客户端在使用该镜像。

bash 复制代码
[root@client ~ 14:46:29]# rbd status images_pool/webapp1 --id rbd
Watchers:
        watcher=192.168.108.10:0/3706715988 client.54260 cookie=18446462598732840963
[root@client ~ 14:46:47]# rbd status images_pool/webapp2 --id rbd
Watchers: none
du

用于查看镜像大小使用情况。

bash 复制代码
[root@client ~ 14:47:12]# rbd du images_pool/webapp1 --id rbd
NAME     PROVISIONED  USED
webapp1        1 GiB  36 MiB
resize

用于扩展和缩减镜像。

bash 复制代码
# 扩展未在使用的镜像
[root@client ~ 14:47:29]# rbd resize images_pool/webapp2 --size 2G --id rbd
Resizing image: 100% complete...done.

[root@client ~ 14:48:12]# rbd du images_pool/webapp2 --id rbd
NAME     PROVISIONED  USED
webapp2        2 GiB   0 B

[root@client ~ 14:48:39]# ceph osd pool ls --id rbd
device_health_metrics
images_pool

# 扩展正在使用的镜像
[root@client ~ 14:48:45]# rbd resize images_pool/webapp1 --size 2G --id rbd
Resizing image: 100% complete...done.
[root@client ~ 14:49:14]# df -h /dev/rbd0
Filesystem      Size  Used Avail Use% Mounted on
/dev/rbd0      `1014M `  40M  975M   4% /webapp/webapp1

[root@client ~ 14:49:23]# xfs_growfs /webapp/webapp1/
meta-data=/dev/rbd0              isize=512    agcount=8, agsize=32768 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=16     swidth=16 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 262144 to 524288
[root@client ~ 14:49:43]# df -h /dev/rbd0
Filesystem      Size  Used Avail Use% Mounted on
/dev/rbd0       `2.0G`   48M  2.0G   3% /webapp/webapp1

# 缩减镜像
[root@client ~ 14:49:47]# rbd resize images_pool/webapp2 --size 1G --id rbd
rbd: shrinking an image is only allowed with the --allow-shrink flag

[root@client ~ 14:51:04]# rbd resize images_pool/webapp2 --size 1G --allow-shrink --id rbd
Resizing image: 100% complete...done.
[root@client ~ 14:51:07]# rbd du images_pool/webapp2 --id rbd
NAME     PROVISIONED  USED
webapp2        `1 GiB `  0 B
# 缩减正在使用的镜像(xfs文件系统不支持缩减)
rename mv

用于重命名镜像,该操作不支持跨池。

bash 复制代码
# 创建新池
[root@ceph1 ~ 14:46:04]# ceph osd pool create images_pool_2 32 32
pool 'images_pool_2' created

# 重命名
[root@ceph1 ~ 14:53:08]# rbd rename images_pool/webapp2 images_pool/webapp02
[root@ceph1 ~ 14:53:34]# rbd ls images_pool
webapp02
webapp1


[root@ceph1 ~ 14:53:51]# rbd mv images_pool/webapp02 images_pool/webapp2
[root@ceph1 ~ 14:54:18]# rbd ls images_pool
webapp1
webapp2

# 跨池重命名
[root@ceph1 ~ 14:54:25]# rbd rename images_pool/webapp2 images_pool_2/webapp02
rbd: mv/rename across pools not supported
source pool: images_pool dest pool: images_pool_2
cp

用于复制镜像。

bash 复制代码
#实验前观察
[root@client ~ 15:03:53]# ceph osd lspools --id rbd
1 device_health_metrics
2 images_pool
3 images_pool_2
[root@client ~ 15:04:23]# rbd ls images_pool --id rbd
webapp1
webapp2
[root@client ~ 15:04:29]# rbd ls images_pool_2 --id rbd

#打这条命令之前可以先rbd ls -p images_pool_2查看下
[root@ceph1 ~ 15:06:10]# rbd cp images_pool/webapp2 images_pool_2/webapp2
[root@ceph1 ~ 15:06:18]# rbd ls -p images_pool
webapp1
webapp2
[root@ceph1 ~ 15:06:31]# rbd ls -p images_pool_2
webapp2
trash

使用垃圾箱管理镜像。

bash 复制代码
# 将镜像放入垃圾箱
#先查看下images_pool
[root@ceph1 ~ 15:06:41]# rbd ls images_pool
webapp1
webapp2
[root@ceph1 ~ 15:06:50]# rbd trash mv images_pool/webapp2
[root@ceph1 ~ 15:07:01]# rbd ls images_pool
webapp1
[root@ceph1 ~ 15:07:10]# rbd trash ls images_pool
d474d0cea2b3 webapp2

# 恢复垃圾箱中镜像,必须使用id
[root@ceph1 ~ 15:07:26]# rbd trash restore -p images_pool d474d0cea2b3
[root@ceph1 ~ 15:07:43]# rbd ls images_pool
webapp1
webapp2
[root@ceph1 ~ 15:08:13]# rbd trash ls images_pool
d474d0cea2b3 webapp2


# 删除垃圾箱中镜像
[root@ceph1 ~ 15:07:53]# rbd trash mv images_pool/webapp2
[root@ceph1 ~ 15:09:12]# rbd trash ls images_pool
d474d0cea2b3 webapp2
[root@ceph1 ~ 15:09:18]# rbd trash rm -p images_pool d474d0cea2b3
Removing image: 100% complete...done.
[root@ceph1 ~ 15:09:24]# rbd ls images_pool
webapp1
rm

用于删除镜像。

bash 复制代码
[root@ceph1 ~ 15:09:34]# rbd rm images_pool_2/webapp2
Removing image: 100% complete...done.

[root@ceph1 ~ 15:09:58]# rbd ls images_pool_2

管理 RADOS 块设备快照

RBD 镜像功能

使用 格式 2 的RBD 镜像支持若干可选功能:

  • layering,镜像分层功能,该功能支持快照和克隆。

  • striping,提高性能的分条 v2 功能,由 librbd 提供支持。

  • exclusive-lock,独占锁定功能。

  • object-map,对象映射功能(依赖 exclusive-lock)。

  • fast-diff,快速 diff 命令功能(依赖 object-map 和 exclusive-lock)。

  • deep-flatten,扁平化 RBD 镜像的所有快照。

  • journaling,日志功能(依赖 exclusive-lock)。

  • data-pool,EC 数据池功能。

在RBD的features中,源代码定义如下

bash 复制代码
#define RBD_FEATURE_LAYERING (1ULL<<0)
#define RBD_FEATURE_STRIPINGV2 (1ULL<<1)
#define RBD_FEATURE_EXCLUSIVE_LOCK (1ULL<<2)
#define RBD_FEATURE_OBJECT_MAP (1ULL<<3)
#define RBD_FEATURE_FAST_DIFF (1ULL<<4)
#define RBD_FEATURE_DEEP_FLATTEN (1ULL<<5)
#define RBD_FEATURE_JOURNALING (1ULL<<6)
#define RBD_FEATURE_DATA_POOL (1ULL<<7)
(1ULL<<0) 2^0=1
(1ULL<<1) 2^1=2
(1ULL<<2) 2^2=4
(1ULL<<3) 2^3=8
(1ULL<<4) 2^4=16
(1ULL<<5) 2^5=32
(1ULL<<6) 2^6=64
(1ULL<<7) 2^7=128

集群中 RBD 镜像默认启用功能:

bash 复制代码
layering, exclusive-lock, object-map, fast-diff, deep-flatten
bash 复制代码
[root@ceph1 ~ 15:34:56]# ceph config get client rbd_default_features
layering,exclusive-lock,object-map,fast-diff,deep-flatten
  • 使用命令 ceph config set client rbd_default_features value 命令设置镜像默认功能。

  • /etc/ceph/ceph.conf 的 [client] 中 rbd_default_features 参数定义镜像支持的功能。

  • 命令行创建image时候,可以通过 --image-feature feature-name 指定镜像功能。

禁用 object-map 功能

bash 复制代码
[root@ceph1 ~ 15:36:20]# rbd feature disable images_pool/webapp1 object-map

启用 object-map 功能

bash 复制代码
[root@ceph1 ~ 15:35:21]# rbd feature enable images_pool/webapp1 object-map

有些功能是永久性的,不能直接禁用和启用,例如 layering。

bash 复制代码
[root@ceph1 ~ 15:37:40]# rbd feature disable images_pool/webapp1 layering
rbd: failed to update image features: 2025-12-01T15:37:53.750+0800 7f8a1e3d53c0 -1 librbd::Operations: cannot update immutable features

(22) Invalid argument
RBD 快照

RBD 快照使用 COW 技术 ,实现最大程度减少维护快照所需的存储空间。在将写入 I/O 请求应用到 RBD快照镜像前,集群会将原始数据复制到 I/O 操作所影响对象的 PG 中的另一区域。快照在创建时不会占用存储空间,随着所包含对象的变化而增大。RBD 镜像支持增量快照。

快照 COW 技术在对象级别上运行,不受对 RBD 镜像发出的写入 I/O 请求大小的限制。如果用户在有快照的 RBD 镜像中写入一个字节,则 Ceph 会将整个受影响的对象从 RBD 镜像复制到快照区域。

注意: 在拍摄快照前,一定要完成以下任一操作:

  1. 卸载文件系统。
  2. 使用 fsfreeze命令冻结文件系统,只允许读操作。

使用 rbd snap create 命令,创建 Ceph 块设备的快照。

bash 复制代码
# 重新创建一个镜像
[root@client ~ 15:38:10]# rbd create images_pool/webapp --size 2G --id rbd
[root@client ~ 15:38:42]# rbd map images_pool/webapp --id rbd
/dev/rbd1
[root@client ~ 15:38:47]# mkfs.xfs /dev/rbd/images_pool/webapp
meta-data=/dev/rbd/images_pool/webapp isize=512    agcount=8, agsize=65536 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1    bigtime=0 inobtcount=0
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=16     swidth=16 blks
naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
Discarding blocks...Done.
[root@client ~ 15:39:05]# mkdir /webapp/webapp
[root@client ~ 15:39:13]# mount /dev/rbd/images_pool/webapp /webapp/webapp
[root@client ~ 15:39:29]# echo hello world > /webapp/webapp/index.html
[root@client ~ 15:39:47]# cat /webapp/webapp/index.html
hello world

# 卸载文件系统
[root@client ~ 15:39:53]# umount /webapp/webapp

# 拍摄快照
[root@client ~ 15:40:40]# rbd snap create images_pool/webapp@snap1 --id rbd
Creating snap: 100% complete...done.
[root@client ~ 15:40:46]# rbd snap ls images_pool/webapp --id rbd
SNAPID  NAME   SIZE   PROTECTED  TIMESTAMP
     4  snap1  2 GiB             Mon Dec  1 15:40:42 2025
     
# 挂载文件系统,并写入新数据
[root@client ~ 15:41:19]# mount /dev/rbd/images_pool/webapp /webapp/webapp
[root@client ~ 15:41:27]# echo hello dyx >/webapp/webapp/index.html
[root@client ~ 15:41:42]# cat /webapp/webapp/index.html
hello dyx

使用 rbd snap ls 命令,列出块设备快照。

bash 复制代码
[root@client ~ 15:42:03]# rbd snap ls images_pool/webapp --id rbd
SNAPID  NAME   SIZE   PROTECTED  TIMESTAMP
     4  snap1  2 GiB             Mon Dec  1 15:40:42 2025

RBD 快照是创建于特定时间的 RBD 镜像的只读副本。

重要提示:镜像快照和镜像具有相同的文件系统,同一客户端不允许挂载具有相同UUID的文件系统。

bash 复制代码
#将/webapp/webapp里的index.html删除,通过挂载/webapp/webapp@snap1找回来
[root@client ~ 15:42:10]# rm /webapp/webapp/index.html
rm: remove regular file '/webapp/webapp/index.html'? y

# 在挂载快照前,需要卸载原始镜像
[root@client ~ 15:42:27]# umount /dev/rbd/images_pool/webapp

[root@client ~ 15:42:38]# mkdir /webapp/webapp-snap1
[root@client ~ 15:43:17]# rbd map images_pool/webapp@snap1 --id rbd
/dev/rbd2
[root@client ~ 15:43:23]# mount /dev/rbd/images_pool/webapp@snap1 /webapp/webapp-snap1/
mount: /webapp/webapp-snap1: WARNING: device write-protected, mounted read-only.

#将快照里的文件复制出来,实现数据找回
[root@client ~ 15:43:47]# cat /webapp/webapp-snap1/index.html
hello world

使用 rbd snap rollback 命令,回滚块设备快照,并用快照中的数据覆盖镜像的当前版本

bash 复制代码
[root@client ~ 15:44:02]# rbd snap rollback images_pool/webapp@snap1 --id rbd
Rolling back to snapshot: 0% complete...failed.
rbd: rollback failed: (30) Read-only file system

使用 rbd snap rm 命令,删除 Ceph 块设备的快照。

bash 复制代码
[root@client ~ 15:44:17]# umount /dev/rbd/images_pool/webapp@snap1
[root@client ~ 15:44:36]# rbd unmap images_pool/webapp@snap1

[root@client ~ 15:45:25]# rbd snap rm images_pool/webapp@snap1 --id rbd
Removing snap: 100% complete...done.

[root@client ~ 15:45:50]# rbd snap create images_pool/webapp@snap1 --id rbd
Creating snap: 100% complete...done.

使用 rbd snap purge 命令,删除镜像所有快照。

bash 复制代码
[root@client ~ 15:46:28]# rbd snap create images_pool/webapp@snap1 --id rbd
[root@client ~ 15:47:36]# rbd snap create images_pool/webapp@snap2 --id rbd
Creating snap: 100% complete...done.
[root@client ~ 15:47:52]# rbd snap ls images_pool/webapp --id rbd
SNAPID  NAME   SIZE   PROTECTED  TIMESTAMP
     6  snap1  2 GiB             Mon Dec  1 15:45:52 2025
     7  snap2  2 GiB             Mon Dec  1 15:47:43 2025

[root@client ~ 15:47:56]# rbd snap purge images_pool/webapp --id rbd
Removing all snapshots: 100% complete...done.
[root@client ~ 15:48:12]# rbd snap ls images_pool/webapp --id rbd

提示:镜像存在快照时,将无法删除 RBD 镜像。

RBD 克隆

RBD 克隆是 RBD 镜像的可读写副本,它使用受保护的 RBD 快照克隆。RBD 克隆也可以被扁平化,转换

为独立于来源的 RBD 镜像。

克隆过程有三个步骤:

  1. 创建快照

    bash 复制代码
    [root@client ~ 16:25:42]# rbd snap create images_pool/webapp@snap1
    Creating snap: 100% complete...done.
    [root@client ~ 16:26:31]# rbd snap ls images_pool/webapp
    SNAPID  NAME   SIZE   PROTECTED  TIMESTAMP
        10  snap1  2 GiB             Mon Dec  1 16:26:28 2025
  2. 保护快照以免被删除

    bash 复制代码
    [root@client ~ 16:26:45]# rbd snap protect images_pool/webapp@snap1
    [root@client ~ 16:27:19]# rbd snap ls images_pool/webapp
    SNAPID  NAME   SIZE   PROTECTED  TIMESTAMP
        10  snap1  2 GiB  `yes`        Mon Dec  1 16:26:28 2025
  3. 使用受保护的快照创建克隆

    bash 复制代码
    [root@client ~ 16:27:21]# rbd clone images_pool/webapp@snap1 images_pool/webapp-clone-1
    [root@client ~ 16:28:08]# rbd map images_pool/webapp-clone-1
    /dev/rbd2
    [root@client ~ 16:29:12]# mkdir /webapp/webapp-clone-1
    
    # 挂载clone前确保镜像和快照不要挂载
    [root@client ~ 16:28:24]# rbd map images_pool/webapp-clone-1
    rbd: warning: image already mapped as /dev/rbd2
    /dev/rbd3
    [root@client ~ 16:29:03]# lsblk
    NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda           8:0    0  200G  0 disk
    ├─sda1        8:1    0    1G  0 part /boot
    └─sda2        8:2    0  199G  0 part
      ├─cs-root 253:0    0   70G  0 lvm  /
      ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
      └─cs-home 253:2    0  127G  0 lvm  /home
    sr0          11:0    1 12.8G  0 rom
    rbd0        252:0    0    2G  0 disk /webapp/webapp1
    rbd1        252:16   0    2G  0 disk
    rbd2        252:32   0    2G  0 disk
    rbd3        252:48   0    2G  0 disk
    
    # 挂载clone前确保镜像和快照不要挂载
    [root@client ~ 16:29:52]# mount /dev/rbd/images_pool/webapp-clone-1  /webapp/webapp-clone-1
    [root@client ~ 16:30:14]# df /webapp/webapp-clone-1/
    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/rbd3        2086912 47860   2039052   3% /webapp/webapp-clone-1

    新创建的克隆可以像常规 RBD 镜像一样运作,克隆支持 COW 和 COR技术,默认只支持 COW。

    COW 会将父快照数据复制到克隆中,然后将写入 I/O 请求应用到克隆。

    bash 复制代码
    [root@ceph1 ~ 16:30:30]# ceph config get client rbd_clone_copy_on_read
    false

    RBD 克隆未启用 COR 功能时,父 RBD 快照和克隆相同的数据会直接从父快照读取。相对于客户端而言,父快照的 OSD 具有较高的延迟,这种操作会提高读取的代价。

    如果用户启用了 COR,并且克隆中尚未存在数据,则 Ceph 会在处理读取 I/O 请求前先从父快照复制数

    **据到克隆。**通过为客户端或全局设置运行 ceph config set client rbd_clone_copy_on_read true命令或 ceph ceph config set global rbd_clone_copy_on_read true 命令来激活 COR 功能。原始数据不会被覆盖。

    bash 复制代码
    # ceph config set client rbd_clone_copy_on_read true
    # ceph config get client rbd_clone_copy_on_read
    true

    如果不对 RBD 克隆启用 COR,则克隆无法满足的每个读取操作都会对克隆的父级发出 I/O 请求。

    克隆 COW COR 步骤在对象级别上运行,不受 I/O 请求大小的限制。要读取或写入 RBD 克隆的单个字节,Ceph 会将整个对象从父镜像或快照复制到克隆

    查看基于特定快照的克隆列表

    bash 复制代码
    [root@client ~ 16:31:07]# rbd clone images_pool/webapp@snap1 images_pool/webapp-clone-2
    [root@client ~ 16:31:52]# rbd children images_pool/webapp@snap1
    images_pool/webapp-clone-1
    images_pool/webapp-clone-2

    扁平化克隆,Ceph 会将所有缺失的数据从父级复制到克隆,然后移除对父级的引用。克隆会变成独立的RBD 镜像,不再是受保护快照的子级。

    bash 复制代码
    [root@client ~ 16:32:07]# rbd flatten images_pool/webapp-clone-1
    Image flatten: 100% complete...done.
    [root@client ~ 16:32:25]# rbd children images_pool/webapp@snap1
    images_pool/webapp-clone-2
挂载克隆镜像

通过镜像快照克隆出来的镜像,具有原镜像相同的文件系统,而同一客户端不允许挂载具有相同UUID的文件系统。怎么处理?

答案:修改文件系统UUID。

假设客户端将克隆出来的镜像映射为/dev/rbd4设备。操作如下:

bash 复制代码
[root@client ~ 16:32:50]# rbd map images_pool/webapp-clone-2
/dev/rbd4
[root@client ~ 16:32:58]# blkid |grep rbd
/dev/rbd0: UUID="f9e0a2d9-f6cb-4062-b4b5-e21c2595568c" BLOCK_SIZE="512" TYPE="xfs"
/dev/rbd1: UUID="e7d14f68-f96f-4dd9-bdba-defe48667fe4" BLOCK_SIZE="512" TYPE="xfs"
/dev/rbd2: UUID="e7d14f68-f96f-4dd9-bdba-defe48667fe4" BLOCK_SIZE="512" TYPE="xfs"
/dev/rbd3: UUID="e7d14f68-f96f-4dd9-bdba-defe48667fe4" BLOCK_SIZE="512" TYPE="xfs"
/dev/rbd4: UUID="e7d14f68-f96f-4dd9-bdba-defe48667fe4" BLOCK_SIZE="512" TYPE="xfs"

# 生成新的 UUID
[root@client ~ 16:33:43]# uuidgen
975e714e-0ff7-48d7-bfd5-af3feecf9ba1

# 修改 xfs 文件系统 UUID
[root@client ~ 16:34:08]# xfs_admin -U 975e714e-0ff7-48d7-bfd5-af3feecf9ba1 /dev/rbd4
Clearing log and setting UUID
writing all SBs
new UUID = 975e714e-0ff7-48d7-bfd5-af3feecf9ba1

# 挂载测试
[root@client ~ 16:34:31]# mkdir /webapp/webapp-clone-2
[root@client ~ 16:34:50]# mount /dev/rdb4 /webapp/webapp-clone-2
mount: /webapp/webapp-clone-2: special device /dev/rdb4 does not exist.

#查看现象
[root@client ~ 16:35:06]# lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  200G  0 disk
├─sda1        8:1    0    1G  0 part /boot
└─sda2        8:2    0  199G  0 part
  ├─cs-root 253:0    0   70G  0 lvm  /
  ├─cs-swap 253:1    0    2G  0 lvm  [SWAP]
  └─cs-home 253:2    0  127G  0 lvm  /home
sr0          11:0    1 12.8G  0 rom
rbd0        252:0    0    2G  0 disk /webapp/webapp1
rbd1        252:16   0    2G  0 disk
rbd2        252:32   0    2G  0 disk
rbd3        252:48   0    2G  0 disk /webapp/webapp-clone-1
rbd4        252:64   0    2G  0 disk

导入和导出 RBD 镜像

导入和导出 RBD 镜像

利用 RBD 导出与导入机制,用户可以在同一集群中,也可以使用另一独立集群维护拥有完整功能和可访问性的 RBD 镜像操作副本。

用户可以将这些副本用于各种不同的用例,包括:

  • 利用实际的数据卷测试新版本

  • 利用实际的数据卷运行质量保障流程

  • 实施业务连续性方案

  • 将备份进程从生产块设备分离

导出 RBD 镜像

Ceph 存储提供 rbd export 命令来将 RBD 镜像导出到文件。此命令可以将 RBD 镜像或 RBD镜像快照导

出到指定的目标文件。

rbd export 命令的语法如下:

bash 复制代码
[root@ceph1 ~ 09:27:58]# rbd help export
usage: rbd export [--pool <pool>] [--namespace <namespace>] [--image <image>]
                  [--snap <snap>] [--path <path>] [--no-progress]
                  [--export-format <export-format>]
                  <source-image-or-snap-spec> <path-name>

Export image to file.

Positional arguments
  <source-image-or-snap-spec>  source image or snapshot specification
                               (example:
                               [<pool-name>/[<namespace>/]]<image-name>[@<snap-n
                               ame>])
  <path-name>                  export file (or '-' for stdout)

Optional arguments
  -p [ --pool ] arg            source pool name
  --namespace arg              source namespace name
  --image arg                  source image name
  --snap arg                   source snapshot name
  --path arg                   export file (or '-' for stdout)
  --no-progress                disable progress output
  --export-format arg          format of image file

--export-format 选项可指定导出数据的格式,允许用户将较早的 RBD 格式 1 镜像转换为较新的格式 2镜像。

示例:

bash 复制代码
[root@ceph1 ~ 09:28:31]# rbd ls images_pool
webapp
webapp-clone-1
webapp-clone-2
webapp1
[root@ceph1 ~ 09:28:45]# rbd export images_pool/webapp webapp.img
Exporting image: 100% complete...done.
[root@ceph1 ~ 09:28:58]# ls
-  anaconda-ks.cfg  ceph.pub  webapp.img
导入 RBD 镜像

Ceph 存储提供 rbd import 命令来从文件导入 RBD 镜像。此命令会新建一个镜像,并从指定的源路径导入数据。

rbd import 命令的语法如下:

bash 复制代码
[root@ceph1 ~ 09:30:01]# rbd help import
usage: rbd import [--path <path>] [--dest-pool <dest-pool>]
                  [--dest-namespace <dest-namespace>] [--dest <dest>]
                  [--image-format <image-format>] [--new-format]
                  [--order <order>] [--object-size <object-size>]
                  [--image-feature <image-feature>] [--image-shared]
                  [--stripe-unit <stripe-unit>]
                  [--stripe-count <stripe-count>] [--data-pool <data-pool>]
                  [--mirror-image-mode <mirror-image-mode>]
                  [--journal-splay-width <journal-splay-width>]
                  [--journal-object-size <journal-object-size>]
                  [--journal-pool <journal-pool>]
                  [--sparse-size <sparse-size>] [--no-progress]
                  [--export-format <export-format>] [--pool <pool>]
                  [--image <image>]
                  <path-name> <dest-image-spec>

Import image from file.

Positional arguments
  <path-name>               import file (or '-' for stdin)
  <dest-image-spec>         destination image specification
                            (example: [<pool-name>/[<namespace>/]]<image-name>)

Optional arguments
  --path arg                import file (or '-' for stdin)
  --dest-pool arg           destination pool name
  --dest-namespace arg      destination namespace name
  --dest arg                destination image name
  --image-format arg        image format [default: 2]
  --object-size arg         object size in B/K/M [4K <= object size <= 32M]
  --image-feature arg       image features
                            [layering(+), exclusive-lock(+*), object-map(+*),
                            deep-flatten(+-), journaling(*)]
  --image-shared            shared image
  --stripe-unit arg         stripe unit in B/K/M
  --stripe-count arg        stripe count
  --data-pool arg           data pool
  --mirror-image-mode arg   mirror image mode [journal or snapshot]
  --journal-splay-width arg number of active journal objects
  --journal-object-size arg size of journal objects [4K <= size <= 64M]
  --journal-pool arg        pool for journal objects
  --sparse-size arg         sparse size in B/K/M [default: 4K]
  --no-progress             disable progress output
  --export-format arg       format of image file

Image Features:
  (*) supports enabling/disabling on existing images
  (-) supports disabling-only on existing images
  (+) enabled by default for new images if features not specified
  • --export-format 选项指定待导入数据的格式,必须确保 rbd export 和 rbd import 命令使用的--export-format 参数值一致。

  • 在导入格式 2 的导出数据时,使用 --stripeunit、--stripe-count、--object-size 和 --image-feature选项可创建新的 RBD 格式 2镜像。

同一集群导入

bash 复制代码
[root@ceph1 ~ 09:29:02]# rbd import webapp.img images_pool/webapp-backup
Importing image: 100% complete...done.
[root@ceph1 ~ 09:29:36]# rbd ls images_pool
webapp
webapp-backup
webapp-clone-1
webapp-clone-2
webapp1
[root@ceph1 ~ 09:29:39]# rbd info images_pool/webapp-backup
rbd image 'webapp-backup':
        size 2 GiB in 512 objects
        order 22 (4 MiB objects)
        snapshot_count: 0
        id: faa76dd04bbf
        block_name_prefix: rbd_data.faa76dd04bbf
        format: 2
        features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
        op_features:
        flags:
        create_timestamp: Tue Dec  2 09:29:29 2025
        access_timestamp: Tue Dec  2 09:29:29 2025
        modify_timestamp: Tue Dec  2 09:29:29 2025
[root@ceph1 ~ 09:30:01]#
管道导出和导入进程

将短划线 (-) 字符指定为导出操作的目标文件会导致输出转到标准输出 (stdout)。用户还可使用短划线字符 (-) 将 stdout 或标准输入 (stdin) 指定为导出目标或导入来源。

用户可以将这两个命令传送到一个命令中。

bash 复制代码
# 同一集群导出和导入
[root@ceph1 ~ 09:51:50]# rbd export images_pool/webapp - | rbd import - images_pool/webapp-backup2
Exporting image: 100% complete...done.
Importing image: 100% complete...done.
[root@ceph1 ~ 09:52:33]# ls
-  anaconda-ks.cfg  ceph.pub  webapp.img
[root@ceph1 ~ 09:52:37]# rbd ls images_pool
webapp
webapp-backup
webapp-backup2
webapp-clone-1
webapp-clone-2
webapp1

7 Ceph 分布式存储 对象存储管理

对象存储介绍

对象存储简介

对象存储是一个基于对象的存储服务, 提供海量、 安全、 高可靠、 低成本的数据存储能力。

对象存储将数据存储为离散项,每一项也是一个对象。每个对象都具有唯一的对象ID(也称对象密钥),用户可在不了解对象位置的情况下,通过对象ID进行存储或检索。

对象存储中的对象实际是一个文件数据与其相关属性信息的集合体, 包括三个部分:

  • Key:键值,即对象的名称,为经过 UTF-8 编码的长度大于0且不超过1024的字符序列。一个桶里的每个对象必须拥有唯一的对象键值。

  • Metadata:元数据,即对象的描述信息,包括系统元数据和用户元数据,这些元数据以键值对(Key-Value)的形式被上传到对象存储中。元数据由对象存储产生,在处理对象数据时使用,包括Date, Content-length,Last-modify, ETag等。

  • Data:数据,即文件的数据内容。

对象存储在扁平的命名空间中 ,称为,是对象存储存储对象的容器。 桶中的所有对象都处于同一逻辑层级, 去除了文件系统中的多层级树形目录结构。每个桶都有自己的存储类别、 访问权限、 所属区域等属性, 用户可以在不同区域创建不同存储类别和访问权限的桶, 并配置更多高级属性来满足不同场景的存储诉求。

对象存储特征
  • 接入灵活:支持多种形态客户端,如通过用对象存储接口、 RESTful接口、 SDK等。

  • 访问协议简单:使用http或https协议访问。

  • 访问网络不受限:通过互联网或局域网都进行访问。

  • 结构扁平化:对象直接存放在桶中,无目录结构。

RADOS 网关介绍

RADOS 网关简介
  • RADOS GateWay ,也称对象网关 (RGW),为客户端提供标准对象存储 API 来访问 Ceph **集群。**Ceph 存储支持 Amazon S3(简单存储服务)和 OpenStack Swift(OpenStack 对象存储)两种常用的对象 API。Amazon S3 将对象存储的扁平命名空间称为存储桶,而 OpenStack Swift 则将其称为容器。

  • 守护进程 radosgw librados 库的基础上构建,提供基于 Beast HTTP、WebSocket 和网络协议库的 Web 服务接口,作为处理 API 请求的前端。

  • radosgw是Ceph存储的客户端,用于访问对象存储中对象。

RADOS 网关中用户只能访问网关,不能像cephx 用户一样直接访问存储集群。提交 Amazon S3 或OpenStack Swift API 请求时,RADOS 网关客户端会使用这些网关用户帐户进行身份验证。网关用户通过 RADOS 网关完成身份验证后,网关会使用 cephx 凭据向存储集群进行身份验证,以处理对象请求。也可通过集成基于 LDAP 的外部身份验证服务来管理网关用户。

RADOS 网关会为默认区域创建多个池:

  • .rgw.root,存储信息记录。

  • .default.rgw.control,控制池。

  • .default.rgw.meta,存储 user_keys 和其他关键元数据。

  • .default.rgw.log,包含所有存储桶/容器和对象操作(如创建、读取和删除)的日志。

  • .default.rgw.buckets.index,存储存储桶的索引。

  • .default.rgw.buckets.data,存储存储桶数据。

  • .default.rgw.buckets.non-ec,用于对象元数据上传。

用户也可以手动创建这些池。建议这些池名称以区域名称为前缀,例如区域名称是 us-east-1,则池名称可以是 .us-east-1.rgw.buckets.data。

RADOS 网关架构

Ceph RADOS 网关支持多站点部署:在多个 Ceph 存储集群之间自动复制对象数据。常见的用例是在地理上分隔的集群之间进行主动/主动复制,以便于灾难恢复。

  • 区域(zone),每个区域会关联一个或多RADOS 网关,这些网关关联Ceph存储。

  • 区域组(zone group),区域组是由一个或多个区域的集合。存储在区域组中某个区域中的数据会被复制到该区域组中的所有其他区域每个区域组中会有一个区域为该组的主区域 ,该组中的其他区域为次要区域。

  • (realm) ,代表所有对象和存储桶的全局命名空间。域中含有一个或多个区域组,各自包含一个或多个区域。域中会指定一个区域组为主区域组 ,其他都是次要区域组。域 (realm) 中的所有RADOS 网关都从位于主区域组中主区域中的 RADOS 网关拉取配置。因为主区域组中的主区域负责处理所有元数据更新,所以创建用户等操作都必须在主区域进行。

每个域有关联的期间 (period),每个期间有关联的时期 (epoch)。

  • 期间 (period),用于跟踪特定时间域、区域组和区域的配置状态。每个期间有一个唯一 ID,包含域配置,并且知道前一个期间的 ID。

  • 时期 (epoch),用于跟踪特定域期间的配置版本号。

更新规则:

  • 更新主区域的配置时,RADOS 网关服务使用当前时间更新期间。这个新期间会变成域的当前期间,该期间的时期值会增加一。

  • 至于其他配置更改,只有时期会递增,期间不会变化。

RADOS 网关用例

Ceph 对象存储因其高扩展性、高可靠性和灵活性,适用于多种场景,包括大规模数据存储、云服务、备份归档、大数据分析、多媒体存储、容器存储、灾难恢复、混合云、科学计算和物联网数据存储等。

以下是常见的使用场景及原因:

  1. 大规模数据存储
  • 场景: 适用于需要存储海量非结构化数据的场景,如视频、图片、日志等。

  • 原因: Ceph 对象存储能轻松扩展到 PB 甚至 EB 级别,适合处理大规模数据。

  1. 云存储服务
  • 场景: 用于公有云或私有云中的对象存储服务。

  • 原因: Ceph 兼容 S3 和 Swift API,便于与现有云平台集成,提供高可用性和持久性。

  1. 备份和归档
  • 场景: 用于长期数据备份和归档。

  • 原因: Ceph 提供高可靠性和低成本存储,支持数据压缩和加密,适合长期保存。

  1. 大数据分析
  • 场景: 存储大数据分析中的原始数据或中间结果。

  • 原因: Ceph 的高吞吐量和低延迟特性,适合大数据应用的读写需求。

  1. 多媒体内容存储与分发
  • 场景: 用于存储和分发视频、音频等多媒体内容。

  • 原因: Ceph 的高并发读写能力,适合内容分发网络(CDN)的需求。

  1. 容器存储
  • 场景: 为 Kubernetes 等容器平台提供持久化存储。

  • 原因: Ceph 支持 RBD 和 CephFS,适合容器环境中的动态存储需求。

  1. 灾难恢复
  • 场景: 用于跨地域的数据复制和灾难恢复。

  • 原因: Ceph 支持多站点复制,确保数据在灾难发生时的高可用性。

  1. 混合云存储
  • 场景: 在混合云环境中统一管理数据。

  • 原因: Ceph 可在私有云和公有云之间无缝迁移数据,提供一致的存储体验。

  1. 科学计算与高性能计算(HPC)
  • 场景: 存储科学计算和 HPC 中的大量数据。

  • 原因: Ceph 的高吞吐量和并行访问能力,适合科学计算中的大规模数据处理。

  1. 物联网(IoT)数据存储
  • 场景: 存储物联网设备生成的海量数据。

  • 原因: Ceph 的高扩展性和高可靠性,适合处理物联网设备产生的大量数据。

RADOS 网关部署

Ceph 使用 Ceph 编排器来部署 (或删除) RADOS 网关服务 ,用于管理单个集群或多个集群。使用集中式配置数据库中的 client.rgw.* 部分来定义新 RADOS 网关守护进程的参数和特征。

对象存储网关部署流程:

  1. 创建对象存储域
  2. 创建对象网关
创建对象存储域

示例:

用法:

bash 复制代码
[root@ceph1 ~ 10:36:25]# radosgw-admin --help
usage: radosgw-admin <cmd> [options...]
commands:
  user create                create a new user
  user modify                modify user
  user info                  get user info
  user rename                rename user
  user rm                    remove user
  user suspend               suspend a 
  ... ...
bash 复制代码
# 创建 realm
[root@ceph1 ~ 10:36:49]# radosgw-admin realm create --rgw-realm=webapp --default
{
    "id": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
    "name": "webapp",
    "current_period": "36611139-993b-4bda-b176-e4ab5574701f",
    "epoch": 1
}

[root@ceph1 ~ 10:37:15]# radosgw-admin realm list
{
    "default_info": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
    "realms": [
        "webapp"
    ]
}


# 创建 zonegroup,并将其设置为 master
[root@ceph1 ~ 10:37:25]# radosgw-admin zonegroup create --rgw-realm=webapp --rgw-zonegroup=video --master --default
{
    "id": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
    "name": "video",
    "api_name": "video",
    "is_master": "true",
    "endpoints": [],
    "hostnames": [],
    "hostnames_s3website": [],
    "master_zone": "",
    "zones": [],
    "placement_targets": [],
    "default_placement": "",
    "realm_id": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
    "sync_policy": {
        "groups": []
    }
}
[root@ceph1 ~ 10:38:07]# radosgw-admin zonegroup list
{
    "default_info": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
    "zonegroups": [
        "video"
    ]
}

# 创建 zone,并将其设置为 master
[root@ceph1 ~ 10:38:26]# radosgw-admin zone create --rgw-realm=webapp --rgw-zonegroup=video --rgw-zone=storage --master --default
{
    "id": "cd24c698-986d-4131-92be-547e0851cf7c",
    "name": "storage",
    "domain_root": "storage.rgw.meta:root",
    "control_pool": "storage.rgw.control",
    "gc_pool": "storage.rgw.log:gc",
    "lc_pool": "storage.rgw.log:lc",
    "log_pool": "storage.rgw.log",
    "intent_log_pool": "storage.rgw.log:intent",
    "usage_log_pool": "storage.rgw.log:usage",
    "roles_pool": "storage.rgw.meta:roles",
    "reshard_pool": "storage.rgw.log:reshard",
    "user_keys_pool": "storage.rgw.meta:users.keys",
    "user_email_pool": "storage.rgw.meta:users.email",
    "user_swift_pool": "storage.rgw.meta:users.swift",
    "user_uid_pool": "storage.rgw.meta:users.uid",
    "otp_pool": "storage.rgw.otp",
    "system_key": {
        "access_key": "",
        "secret_key": ""
    },
    "placement_pools": [
        {
            "key": "default-placement",
            "val": {
                "index_pool": "storage.rgw.buckets.index",
                "storage_classes": {
                    "STANDARD": {
                        "data_pool": "storage.rgw.buckets.data"
                    }
                },
                "data_extra_pool": "storage.rgw.buckets.non-ec",
                "index_type": 0
            }
        }
    ],
    "realm_id": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
    "notif_pool": "storage.rgw.log:notif"
}
[root@ceph1 ~ 10:39:16]# radosgw-admin zone list
{
    "default_info": "cd24c698-986d-4131-92be-547e0851cf7c",
    "zones": [
        "storage"
    ]
}

# 提交配置
[root@ceph1 ~ 10:39:33]# radosgw-admin period update --rgw-realm=webapp --commit
{
    "id": "d81dcf94-e4c8-492c-9abe-32bd542e9e40",
    "epoch": 1,
    "predecessor_uuid": "36611139-993b-4bda-b176-e4ab5574701f",
    "sync_status": [],
    "period_map": {
        "id": "d81dcf94-e4c8-492c-9abe-32bd542e9e40",
        "zonegroups": [
            {
                "id": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
                "name": "video",
                "api_name": "video",
                "is_master": "true",
                "endpoints": [],
                "hostnames": [],
                "hostnames_s3website": [],
                "master_zone": "cd24c698-986d-4131-92be-547e0851cf7c",
                "zones": [
                    {
                        "id": "cd24c698-986d-4131-92be-547e0851cf7c",
                        "name": "storage",
                        "endpoints": [],
                        "log_meta": "false",
                        "log_data": "false",
                        "bucket_index_max_shards": 11,
                        "read_only": "false",
                        "tier_type": "",
                        "sync_from_all": "true",
                        "sync_from": [],
                        "redirect_zone": ""
                    }
                ],
                "placement_targets": [
                    {
                        "name": "default-placement",
                        "tags": [],
                        "storage_classes": [
                            "STANDARD"
                        ]
                    }
                ],
                "default_placement": "default-placement",
                "realm_id": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
                "sync_policy": {
                    "groups": []
                }
            }
        ],
        "short_zone_ids": [
            {
                "key": "cd24c698-986d-4131-92be-547e0851cf7c",
                "val": 1768757404
            }
        ]
    },
    "master_zonegroup": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
    "master_zone": "cd24c698-986d-4131-92be-547e0851cf7c",
    "period_config": {
        "bucket_quota": {
            "enabled": false,
            "check_on_raw": false,
            "max_size": -1,
            "max_size_kb": 0,
            "max_objects": -1
        },
        "user_quota": {
            "enabled": false,
            "check_on_raw": false,
            "max_size": -1,
            "max_size_kb": 0,
            "max_objects": -1
        }
    },
    "realm_id": "f687b94f-71fa-4ade-b009-eb19f7dad77f",
    "realm_name": "webapp",
    "realm_epoch": 2
}
RADOS 网关部署

RADOS 网关部署-命令行

bash 复制代码
# 创建 rgw,并和已创建的 realm webapp 进行关联,数量为 3
[root@ceph1 ~ 10:40:11]# ceph orch ls
NAME                       PORTS        RUNNING  REFRESHED  AGE  PLACEMENT
alertmanager               ?:9093,9094      1/1  3m ago     5d   count:1
crash                                       3/3  3m ago     5d   *
grafana                    ?:3000           1/1  3m ago     5d   count:1
mgr                                         3/3  3m ago     5d   label:_admin
mon                                         3/3  3m ago     5d   label:_admin
node-exporter              ?:9100           3/3  3m ago     5d   *
osd.all-available-devices                     9  3m ago     5d   *
prometheus                 ?:9095           1/1  3m ago     5d   count:1
[root@ceph1 ~ 10:40:26]# ceph orch apply rgw webapp --placement="3 ceph1.dyx.cloud ceph2.dyx.cloud ceph3.dyx.cloud" --realm=webapp --zone=storage --port=8080
Scheduled rgw.webapp update...

# 查看服务
[root@ceph1 ~ 10:41:44]# ceph orch ls
NAME                       PORTS        RUNNING  REFRESHED  AGE  PLACEMENT              
alertmanager               ?:9093,9094      1/1  5m ago     5d   count:1                
crash                                       3/3  5m ago     5d   *                      
grafana                    ?:3000           1/1  5m ago     5d   count:1                
mgr                                         3/3  5m ago     5d   label:_admin           
mon                                         3/3  5m ago     5d   label:_admin           
node-exporter              ?:9100           3/3  5m ago     5d   *                      
osd.all-available-devices                     9  5m ago     5d   *                      
prometheus                 ?:9095           1/1  5m ago     5d   count:1                
rgw.webapp                 ?:8080           0/3  -          8s   ceph1.dyx.cloud;ceph2.dyx.cloud;ceph3.dyx.cloud;count:3
[root@ceph1 ~ 10:41:53]# ceph orch ls rgw
NAME        PORTS   RUNNING  REFRESHED  AGE  PLACEMENT                                  
rgw.webapp  ?:8080      3/3  4s ago     17s  ceph1.dyx.cloud;ceph2.dyx.cloud;ceph3.dyx.cloud;count:3

# 查看进程
[root@ceph1 ~ 10:42:02]# ceph orch ps --daemon-type rgw|awk '{print $1.$4}'
NAMESTATUS
rgw.webapp.ceph1.wbkkuxrunning
rgw.webapp.ceph2.fycegnrunning
rgw.webapp.ceph3.qqznrzrunning

验证对象存储是否可以访问

bash 复制代码
[root@ceph1 ~ 10:45:45]# curl http://ceph1.dyx.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>

[root@ceph1 ~ 10:45:49]# curl http://ceph2.dyx.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>

[root@ceph1 ~ 10:45:53]# curl http://ceph3.dyx.cloud:8080
<?xml version="1.0" encoding="UTF-8"?><ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><ID>anonymous</ID><DisplayName></DisplayName></Owner><Buckets></Buckets></ListAllMyBucketsResult>

管理对象网关用户

创建用户

使用 radosgw-admin user create 命令来创建 RADOS 网关用户。

  • 必选选项 --uid 和 --display-name ,指定唯一的帐户名和人性化显示名。

  • 可选选项 --access-key 和 --secret,指定自定义 AWS 帐户和机密密钥。

示例:

bash 复制代码
[root@ceph1 ~ 11:25:18]# radosgw-admin user create --uid="operator" --display-name="s3 operator" --email="operator@example.com" --access-key="12345" --secret="67890"
{
    "user_id": "operator",
    "display_name": "s3 operator",
    "email": "operator@example.com",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "operator",
            `"access_key": "12345"`,
            `"secret_key": "67890"`
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

[root@ceph1 ~ 11:26:50]# radosgw-admin user list
[
    "operator",
    "dashboard"
]

#查看详细信息
[root@ceph1 ~ 11:27:01]# radosgw-admin user info --uid=operator
{
    "user_id": "operator",
    "display_name": "s3 operator",
    "email": "operator@example.com",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "operator",
            "access_key": "12345",
            "secret_key": "67890"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

如果未指定访问密钥和机密密钥,则自动生成,并显示在输出中。

bash 复制代码
[root@ceph1 ~ 11:27:16]# radosgw-admin user create --uid=s3user --display-name="Amazon s3 API user"
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            `"access_key": "D3W7YXILAORUJNEA240Z",`
            `"secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"`
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

**注意:**radosgw-admin 命令自动生成的访问密钥和机密密钥可能包含 JSON 转义字符()。客户端可能无法正确处理此字符。建议重新生成或手动指定密钥以避免此问题。

重新生成密钥

仅重新生成现有用户的机密密钥。

bash 复制代码
[root@ceph1 ~ 11:28:02]# radosgw-admin key create --uid=s3user --access-key="123" --gen-secret
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "123",
            "secret_key": "JGwiqTcnB9V0AIWiqcOwVxtTRz9BoeQ3CG5PtT9F"
        },
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}
添加用户访问密钥

若要为现有用户添加访问密钥,请使用 --gen-access-key 选项。创建额外的密钥可以方便地授予同一用户对需要不同或唯一密钥的多个应用的访问权限。

bash 复制代码
[root@ceph1 ~ 11:29:00]# radosgw-admin key create --uid=s3user --gen-access-key
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "123",
            "secret_key": "JGwiqTcnB9V0AIWiqcOwVxtTRz9BoeQ3CG5PtT9F"
        },
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        },
        {
            "user": "s3user",
            "access_key": "MQ6I9ITOEIQ9HP70B3KX",
            "secret_key": "XRR9kd4gAaL5COS3WDFxIPi5pCji8LSqB6FmPUsp"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}
删除用户密钥

要从用户删除访问密钥和相关的机密密钥,请使用 radosgw-admin key rm --access-key 命令。此操作非常适用于删除单个应用访问权限,并且不会影响使用其他密钥的访问权限。

bash 复制代码
[root@ceph1 ~ 11:29:38]# radosgw-admin key rm --uid=s3user --access-key="123"
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        },
        {
            "user": "s3user",
            "access_key": "MQ6I9ITOEIQ9HP70B3KX",
            "secret_key": "XRR9kd4gAaL5COS3WDFxIPi5pCji8LSqB6FmPUsp"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}
临时禁用对象网关用户

使用 radosgw-admin user suspend 命令可临时禁用 RADOS 网关用户,用户的子用户也会暂停,无法与 RADOS 网关服务交互。

bash 复制代码
[root@ceph1 ~ 11:30:26]# radosgw-admin user suspend --uid=s3user
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
   #变成了1
   `"suspended": 1,`
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        },
        {
            "user": "s3user",
            "access_key": "MQ6I9ITOEIQ9HP70B3KX",
            "secret_key": "XRR9kd4gAaL5COS3WDFxIPi5pCji8LSqB6FmPUsp"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

注意:suspended的值为1。

临时启用对象网关用户

使用 radosgw-admin user enable 命令可启用 RADOS 网关用户。

bash 复制代码
[root@ceph1 ~ 11:30:47]# radosgw-admin user enable --uid=s3user
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    `"suspended": 0,`
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        },
        {
            "user": "s3user",
            "access_key": "MQ6I9ITOEIQ9HP70B3KX",
            "secret_key": "XRR9kd4gAaL5COS3WDFxIPi5pCji8LSqB6FmPUsp"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

注意:suspended的值为0。

修改用户信息

用户可修改用户信息,如电子邮件、显示名、密钥和访问控制级别。

bash 复制代码
[root@ceph1 ~ 11:31:26]# radosgw-admin user modify --uid=s3user --access=full
{
    "user_id": "s3user",
    "display_name": "Amazon s3 API user",
    "email": "",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "s3user",
            "access_key": "D3W7YXILAORUJNEA240Z",
            "secret_key": "LBOQA6RTGGjaCXgmevgPGN1yfUMtVAZWspuih4bu"
        },
        {
            "user": "s3user",
            "access_key": "MQ6I9ITOEIQ9HP70B3KX",
            "secret_key": "XRR9kd4gAaL5COS3WDFxIPi5pCji8LSqB6FmPUsp"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

--access 选项用于控制子用户访问权限,控制级别有:read、write、 readwrite 和 full。full 访问级别包括 readwrite 级别和访问控制管理功能。

删除用户

若要移除用户,同时删除其对象和存储桶,需使用 --purge-data 选项。

bash 复制代码
[root@ceph1 ~ 11:31:51]# radosgw-admin user list
[
    "operator",
    "dashboard",
    "s3user"
]
[root@ceph1 ~ 11:32:36]# radosgw-admin user rm --uid=s3user --purge-data
[root@ceph1 ~ 11:32:42]# radosgw-admin user list
[
    "operator",
    "dashboard"
]

使用 Amazon S3 API 问对象存储

Amazon S3 API 介绍

在混合云环境中,用户希望应用可以通过相同的 API 无缝混用私有企业、公共云资源和存储位置。Ceph存储支持使用 Amazon S3 API 接口管理对象存储资源。

Amazon S3 API 称命名空间为存储桶,用于存储对象。要使用 Amazon S3 API 管理对象和存储桶,应用需通过 RADOS 网关用户进行身份验证。每个用户都有一个识别用户的 access key 和一个对用户进行身份验证的 secret key。

使用 Amazon S3 API 时,需考虑对象和元数据的大小限制:

  • 对象大小介于 0B 和 5 TB 之间。

  • 单次上传操作的最大大小为 5GB。

  • 使用分段上传功能可上传 100MB 以上的对象。

  • 单个 HTTP 请求中的元数据大小最大为 16,000 字节。

安装 Amazon S3 API 客户端

Amazon S3 API 客户端有多个,例如 awscli、cloudberry、cyberduck 和 curl。

这里我们讲解 aws **工具。**aws工具由awscli 软件包提供。

以下演示通过pip方式安装。

bash 复制代码
# 准备 aliyun 源 pip 仓库
[root@client ~ 11:42:39]# mkdir .pip
[root@client ~ 11:42:47]# cat > .pip/pip.conf << 'EOF'
 [global]
 index-url = http://mirrors.aliyun.com/pypi/simple/

 [install]
 trusted-host=mirrors.aliyun.com
 EOF
 
 # 安装软件包
 [root@client ~ 11:43:02]# pip3 install awscli
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
Collecting awscli
  Downloading http://mirrors.aliyun.com/pypi/packages/6c/48/8cf68d31f3f8606904acc4d98965a2c020acd5e1b9a821b8a7fafdbbc81a/awscli-1.24.10-py3-none-any.whl (3.9MB)
    100% |████████████████████████████████| 3.9MB 12.5MB/s
Requirement already satisfied: PyYAML<5.5,>=3.10 in /usr/lib64/python3.6/site-packages (from awscli)
Collecting docutils<0.17,>=0.10 (from awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/81/44/8a15e45ffa96e6cf82956dd8d7af9e666357e16b0d93b253903475ee947f/docutils-0.16-py2.py3-none-any.whl (548kB)
    100% |████████████████████████████████| 552kB 11.9MB/s
Collecting rsa<4.8,>=3.1.2 (from awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/e9/93/0c0f002031f18b53af7a6166103c02b9c0667be528944137cc954ec921b3/rsa-4.7.2-py3-none-any.whl
Collecting colorama<0.4.5,>=0.2.5 (from awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/44/98/5b86278fbbf250d239ae0ecb724f8572af1c91f4a11edf4d36a206189440/colorama-0.4.4-py2.py3-none-any.whl
Collecting botocore==1.26.10 (from awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/09/b8/794e0bd260198538ded90c26b353ddb632eab01950d4e7e2e2b8ee510d12/botocore-1.26.10-py3-none-any.whl (8.8MB)
    100% |████████████████████████████████| 8.8MB 11.7MB/s
Collecting s3transfer<0.6.0,>=0.5.0 (from awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/7b/9c/f51775ebe7df5a7aa4e7c79ed671bde94e154bd968aca8d65bb24aba0c8c/s3transfer-0.5.2-py3-none-any.whl (79kB)
    100% |████████████████████████████████| 81kB 13.9MB/s
Collecting pyasn1>=0.1.3 (from rsa<4.8,>=3.1.2->awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/d1/75/4686d2872bf2fc0b37917cbc8bbf0dd3a5cdb0990799be1b9cbf1e1eb733/pyasn1-0.5.1-py2.py3-none-any.whl (84kB)
    100% |████████████████████████████████| 92kB 10.3MB/s
Collecting urllib3<1.27,>=1.25.4 (from botocore==1.26.10->awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/33/cf/8435d5a7159e2a9c83a95896ed596f68cf798005fe107cc655b5c5c14704/urllib3-1.26.20-py2.py3-none-any.whl (144kB)
    100% |████████████████████████████████| 153kB 9.6MB/s
Collecting jmespath<2.0.0,>=0.7.1 (from botocore==1.26.10->awscli)
  Downloading http://mirrors.aliyun.com/pypi/packages/07/cb/5f001272b6faeb23c1c9e0acc04d48eaaf5c862c17709d20e3469c6e0139/jmespath-0.10.0-py2.py3-none-any.whl
Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in /usr/lib/python3.6/site-packages (from botocore==1.26.10->awscli)
Requirement already satisfied: six>=1.5 in /usr/lib/python3.6/site-packages (from python-dateutil<3.0.0,>=2.1->botocore==1.26.10->awscli)
Installing collected packages: docutils, pyasn1, rsa, colorama, urllib3, jmespath, botocore, s3transfer, awscli
Successfully installed awscli-1.24.10 botocore-1.26.10 colorama-0.4.4 docutils-0.16 jmespath-0.10.0 pyasn1-0.5.1 rsa-4.7.2 s3transfer-0.5.2 urllib3-1.26.20
使用 Amazon S3 API 客户端
aws 命令帮助信息
bash 复制代码
[root@client ~ 11:43:29]# aws
Note: AWS CLI version 2, the latest major version of the AWS CLI, is now stable and recommended for general use. For more information, see the AWS CLI version 2 installation instructions at: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: the following arguments are required: command
配置 AWS CLI 凭据

配置 AWS CLI 工具默认凭据:使用 operator 用户,输入 12345 作为访问密钥,67890 作为机密密钥。

bash 复制代码
[root@client ~ 11:47:13]# aws configure
AWS Access Key ID [None]: `12345`
AWS Secret Access Key [None]: `67890`
Default region name [None]:`回车`
Default output format [None]:`回车`

配置信息保存在~/.aws目录。

bash 复制代码
[root@client ~ 11:47:38]# ls .aws
config  credentials

[root@client ~ 11:47:49]# cat .aws/config
[default]
[root@client ~ 11:47:55]# cat .aws/credentials
[default]
aws_access_key_id = 12345
aws_secret_access_key = 67890

注意:aws 命令默认使用default中凭据。

如果想配置多个凭据,配置如下:

bash 复制代码
[root@client ~ 11:48:00]# aws configure --profile=ceph
AWS Access Key ID [None]: `12345`
AWS Secret Access Key [None]: `67890`
Default region name [None]:`回车`
Default output format [None]:`回车`

[root@client ~ 11:48:29]# cat .aws/config
[default]
[profile ceph]

[root@client ~ 11:48:36]# cat .aws/credentials
[default]
aws_access_key_id = 12345
aws_secret_access_key = 67890
[ceph]
aws_access_key_id = 12345
aws_secret_access_key = 67890
创建存储桶

可以通过选项 --profile 指定凭据,--endpoint 指定服务器位置。

bash 复制代码
[root@client ~ 13:51:57]# scp 192.168.108.11:/etc/hosts /etc/hosts
The authenticity of host '192.168.108.11 (192.168.108.11)' can't be established.
ECDSA key fingerprint is SHA256:nOUFHRdr1rBwIb8vZxcNTeRARPN3k9zMIhLlYKBu0LE.
Are you sure you want to continue connecting (yes/no/[fingerprint])? `yes`
Warning: Permanently added '192.168.108.11' (ECDSA) to the list of known hosts.
root@192.168.108.11's password:`123`
hosts                                                 100%  438   587.9KB/s   00:00

[root@client ~ 13:52:53]# aws --endpoint=http://ceph1.dyx.cloud:8080 s3 mb s3://webapp  
make_bucket: webapp
查看存储桶清单

示例:

bash 复制代码
[root@client ~ 13:53:18]# aws --endpoint=http://ceph1.dyx.cloud:8080 s3 ls
2025-12-02 13:53:11 webapp

radosgw-admin 命令也支持存储桶操作,例如使用 radosgw-admin bucket listradosgw-admin bucket rm 命令。

bash 复制代码
[root@ceph1 ~ 14:22:25]# radosgw-admin buckets list
[
    "webapp"
]
上传对象到存储桶

cp 子命令支持三种复制方向:

  • <LocalPath> <S3Uri> ,将本地文件上传到对象存储中。

  • <S3Uri> <LocalPath> ,下载对象存储中对象到本地。

  • <S3Uri> <S3Uri> ,将对象存储中对象复制到对象存储中。

示例:

bash 复制代码
[root@client ~ 14:22:47]# echo hello world > welcome-pub.html
[root@client ~ 14:23:07]#
[root@client ~ 14:23:07]# echo hello dyx > welcome-pri.html


[root@client ~ 14:23:24]# aws --endpoint=http://ceph1.dyx.cloud:8080 s3 cp welcome-pub.html s3://webapp/ --acl=public-read-write
upload: ./welcome-pub.html to s3://webapp/welcome-pub.html


[root@client ~ 14:24:20]# aws s3 cp welcome-pri.html s3://webapp --endpoint=http://ceph1.dyx.cloud:8080
upload: ./welcome-pri.html to s3://webapp/welcome-pri.html
查看存储桶中对象
bash 复制代码
[root@client ~ 14:24:59]# aws s3 ls s3://webapp --endpoint=http://ceph1.dyx.cloud:8080
2025-12-02 14:24:55         10 welcome-pri.html
2025-12-02 14:24:15         12 welcome-pub.html
下载存储桶中对象
bash 复制代码
# 下载单个
[root@client ~ 14:25:26]# aws s3 cp s3://webapp/welcome-pri.html /tmp --endpoint=http://ceph1.dyx.cloud:8080
download: s3://webapp/welcome-pri.html to ../tmp/welcome-pri.html
[root@client ~ 14:26:12]# ls /tmp/welcome-pri.html
/tmp/welcome-pri.html

# 使用选项 --recursive 递归下载bucket中所有对象
[root@client ~ 14:26:19]# aws s3 cp s3://webapp /tmp --recursive --endpoint=http://ceph1.dyx.cloud:8080
download: s3://webapp/welcome-pub.html to ../tmp/welcome-pub.html
download: s3://webapp/welcome-pri.html to ../tmp/welcome-pri.html

# 使用wget或者curl下载
[root@client ~ 14:27:16]# yum install -y wget

#Welcome-pub.html可以正常下载
[root@client ~ 14:27:32]# wget http://ceph1.dyx.cloud:8080/webapp/welcome-pub.html
--2025-12-02 14:28:04--  http://ceph1.dyx.cloud:8080/webapp/welcome-pub.html
Resolving ceph1.dyx.cloud (ceph1.dyx.cloud)... 192.168.108.11
Connecting to ceph1.dyx.cloud (ceph1.dyx.cloud)|192.168.108.11|:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 12 [text/html]
Saving to: 'welcome-pub.html.1'

welcome-pub.html.1    100%[=========================>]      12  --.-KB/s    in 0s

2025-12-02 14:28:04 (45.1 KB/s) - 'welcome-pub.html.1' saved [12/12]

#Welcome-pri.html不可以下载,因为权限不允许
[root@client ~ 14:28:04]# wget http://ceph1.dyx.cloud:8080/webapp/welcome-pri.html
--2025-12-02 14:28:10--  http://ceph1.dyx.cloud:8080/webapp/welcome-pri.html
Resolving ceph1.dyx.cloud (ceph1.dyx.cloud)... 192.168.108.11
Connecting to ceph1.dyx.cloud (ceph1.dyx.cloud)|192.168.108.11|:8080... connected.
HTTP request sent, awaiting response... 403 Forbidden
2025-12-02 14:28:10 ERROR 403: Forbidden.
删除存储桶中对象
bash 复制代码
[root@client ~ 14:28:10]# aws s3 rm s3://webapp/welcome-pri.html --endpoint=http://ceph1.dyx.cloud:8080
delete: s3://webapp/welcome-pri.html

[root@client ~ 14:28:47]# aws s3 ls s3://webapp --endpoint=http://ceph1.dyx.cloud:8080
2025-12-02 14:24:15         12 welcome-pub.html
删除存储桶
bash 复制代码
# 非空的存储桶不能删除
[root@client ~ 14:29:53]# aws s3 rb s3://webapp --endpoint=http://ceph1.dyx.cloud:8080
remove_bucket failed: s3://webapp argument of type 'NoneType' is not iterable


# 清空存储桶,再次删除
[root@client ~ 14:29:59]# aws s3 rm s3://webapp --recursive --include "welcome-*" --endpoint=http://ceph1.dyx.cloud:8080
delete: s3://webapp/welcome-pub.html

[root@client ~ 14:31:20]# aws s3 rb s3://webapp --endpoint=http://ceph1.dyx.cloud:8080
remove_bucket: webapp

用户配额管理

设置配额可限制用户或存储桶可消耗的存储量。

user 级别

--quota-scope 选项设置为 user 来应用用户配额。

启用用户配额

示例:operator用户的配额设置为最多 1024 个对象。

bash 复制代码
[root@ceph1 ~ 15:18:54]# radosgw-admin quota enable --quota-scope=user --uid=operator
[root@ceph1 ~ 15:19:28]# radosgw-admin quota set --quota-scope=user --uid=operator --max-objects=1024

# 查看用户配额
[root@ceph1 ~ 15:20:07]# radosgw-admin user info --uid=operator
{
    "user_id": "operator",
    "display_name": "s3 operator",
    "email": "operator@example.com",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "operator",
            "access_key": "12345",
            "secret_key": "67890"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 1024
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}

# 查看空间使用情况
[root@ceph1 ~ 15:20:22]# radosgw-admin user stats --uid=operator
{
    "stats": {
        "size": 0,
        "size_actual": 0,
        "size_kb": 0,
        "size_kb_actual": 0,
        "num_objects": 0
    },
    "last_stats_sync": "0.000000",
    "last_stats_update": "2025-12-02T06:31:28.392039Z"
}

禁用用户配额

示例:禁用operator用户配额。

bash 复制代码
[root@ceph1 ~ 15:20:42]# radosgw-admin quota set --quota-scope=user --uid=operator --max-objects=-1
[root@ceph1 ~ 15:21:15]# radosgw-admin quota disable --quota-scope=user --uid=operator
[root@ceph1 ~ 15:21:45]# radosgw-admin user info --uid=operator
{
    "user_id": "operator",
    "display_name": "s3 operator",
    "email": "operator@example.com",
    "suspended": 0,
    "max_buckets": 1000,
    "subusers": [],
    "keys": [
        {
            "user": "operator",
            "access_key": "12345",
            "secret_key": "67890"
        }
    ],
    "swift_keys": [],
    "caps": [],
    "op_mask": "read, write, delete",
    "default_placement": "",
    "default_storage_class": "",
    "placement_tags": [],
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "user_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": -1
    },
    "temp_url_keys": [],
    "type": "rgw",
    "mfa_ids": []
}
bucket 级别

--quota-scope 选项设置为 bucket 来应用存储桶配额。

启用 bucket 配额

示例:webapp 存储桶被设置为最多 1024 个对象。

bash 复制代码
[root@client ~ 15:22:15]# aws --endpoint=http://ceph1.dyx.cloud:8080 s3 mb s3://webapp
make_bucket: webapp

[root@ceph1 ~ 15:21:59]# radosgw-admin quota enable --quota-scope=bucket --bucket=webapp

[root@ceph1 ~ 15:23:10]# radosgw-admin quota set --quota-scope=bucket --bucket=webapp --max-objects=1024

# 查看 bucket 配额
[root@ceph1 ~ 15:23:49]# radosgw-admin bucket stats --bucket=webapp
{
    "bucket": "webapp",
    "num_shards": 11,
    "tenant": "",
    "zonegroup": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
    "placement_rule": "default-placement",
    "explicit_placement": {
        "data_pool": "",
        "data_extra_pool": "",
        "index_pool": ""
    },
    "id": "cd24c698-986d-4131-92be-547e0851cf7c.64335.2",
    "marker": "cd24c698-986d-4131-92be-547e0851cf7c.64335.2",
    "index_type": "Normal",
    "owner": "operator",
    "ver": "0#1,1#1,2#1,3#1,4#1,5#1,6#1,7#1,8#1,9#1,10#1",
    "master_ver": "0#0,1#0,2#0,3#0,4#0,5#0,6#0,7#0,8#0,9#0,10#0",
    "mtime": "2025-12-02T07:23:48.886543Z",
    "creation_time": "2025-12-02T07:22:37.301077Z",
    "max_marker": "0#,1#,2#,3#,4#,5#,6#,7#,8#,9#,10#",
    "usage": {},
    "bucket_quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        #webapp 存储桶被设置为最多 1024 个对象。
        `"max_objects": 1024`
    }
}

禁用 bucket 配额

示例:

bash 复制代码
[root@ceph1 ~ 15:24:04]# radosgw-admin quota set --quota-scope=bucket --bucket=webapp --max-objects=-1

[root@ceph1 ~ 15:25:20]# radosgw-admin quota disable --quota-scope=bucket --bucket=webapp

# 查看配额和使用情况
[root@ceph1 ~ 15:25:31]# radosgw-admin bucket stats --bucket=webapp
{
    "bucket": "webapp",
    "num_shards": 11,
    "tenant": "",
    "zonegroup": "53b7f992-85ca-4085-b57d-23ca2a615a8a",
    "placement_rule": "default-placement",
    "explicit_placement": {
        "data_pool": "",
        "data_extra_pool": "",
        "index_pool": ""
    },
    "id": "cd24c698-986d-4131-92be-547e0851cf7c.64335.2",
    "marker": "cd24c698-986d-4131-92be-547e0851cf7c.64335.2",
    "index_type": "Normal",
    "owner": "operator",
    "ver": "0#1,1#1,2#1,3#1,4#1,5#1,6#1,7#1,8#1,9#1,10#1",
    "master_ver": "0#0,1#0,2#0,3#0,4#0,5#0,6#0,7#0,8#0,9#0,10#0",
    "mtime": "2025-12-02T07:25:31.219568Z",
    "creation_time": "2025-12-02T07:22:37.301077Z",
    "max_marker": "0#,1#,2#,3#,4#,5#,6#,7#,8#,9#,10#",
    "usage": {},
    "bucket_quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        #取消了配额
        `"max_objects": -1`
    }
}
global 级别

全局配额会影响集群中的所有存储桶和所有用户。

针对所有用户的配额:

bash 复制代码
[root@ceph1 ~ 15:25:46]# radosgw-admin global quota set --quota-scope user --max-objects 2048
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
    "user quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}

[root@ceph1 ~ 15:26:31]# radosgw-admin global quota enable --quota-scope user
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
    "user quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}

# 查看配额
[root@ceph1 ~ 15:26:54]# radosgw-admin global quota get --quota-scope user
{
    "user quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}

针对所有bucket配额:

bash 复制代码
[root@ceph1 ~ 15:27:23]# radosgw-admin global quota set --quota-scope bucket --max-objects 2048
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
    "bucket quota": {
        "enabled": false,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}
[root@ceph1 ~ 15:28:05]# radosgw-admin global quota enable --quota-scope bucket
Global quota changes saved. Use 'period update' to apply them to the staging period, and 'period commit' to commit the new period.
{
    "bucket quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}

# 查看配额
[root@ceph1 ~ 15:29:19]# radosgw-admin global quota get --quota-scope bucket
{
    "bucket quota": {
        "enabled": true,
        "check_on_raw": false,
        "max_size": -1,
        "max_size_kb": 0,
        "max_objects": 2048
    }
}

要在区域和期间配置中实施全局配额:

  • 使用 radosgw-admin period update --commit 命令来提交更改来实施配额。

  • 重启 RGW 实例来实施配额。

查看配额使用情况

存储管理员通过监控使用情况统计信息来确定存储消耗或用户带宽使用情况。监控还有助于查找不活动的应用或不当的用户配额。

显示用户在特定日期之间的使用情况统计信息。

bash 复制代码
[root@ceph1 ~ 15:31:30]# radosgw-admin usage show --uid=operator --start-date='2025-12-02T15:30:00' --end-date='2025-12-02T15:32:00'
{
    "entries": [],
    "summary": []
}

查看所有用户的统计信息。这些总体统计数据有助于了解对象存储模式,并规划新实例的部署以扩展RADOS 网关服务。

bash 复制代码
[root@ceph1 ~ 15:31:41]# radosgw-admin usage show --show-log-entries=false
{
    "summary": []
}

8 Ceph 分布式存储 文件系统存储管理

介绍 CephFS

介绍 CephFS
  • Ceph 文件系统 (CephFS) ,构建在 Ceph 存储之上,是一种兼容 POSIX 的文件系统。

  • 与 RBD 和 RGW 类似,CephFS 也会作为 librados 的原生接口来实施。

  • Ceph 支持在一个集群中运行多个活动 MDS,以提高元数据性能。为保持高可用性,还可配置备用MDS,以便在任何活动 MDS 出现故障时,接管其任务。

  • Ceph 支持在一个集群中部署多个活动的 CephFS 文件系统。部署多个 CephFS 文件系统需要运行多个 MDS 守护进程。

不同存储方式对比
  • **基于文件的存储:**可以像传统文件系统一样整理用户的数据,并带有目录树层次结构。数据会保存在文件中,文件会有一个名称并包含相关元数据,如修改时间戳、所有者和访问权限。

  • 基于块的存储:提供像磁盘一样运作的存储卷,整理到大小相等的区块中。通常而言,基于块的存储卷要么通过文件系统进行格式化,要么是像数据库一样可直接读写的应用。

  • **基于对象的存储:**支持将任意数据和元数据作为一个标有唯一标识符的单元存储在扁平存储池中。用户会使用 API 来存储和检索数据,而不会作为块或在文件系统层次结构中访问数据。

元数据服务器

元数据服务器 (MDS) 负责:

  • 管理目录层次结构和文件元数据(如所有者、时间戳和权限模式等),提供 CephFS 客户端访问RADOS 对象所需的信息。

  • 访问客户端缓存,并维护客户端缓存一致性。

MDS 以两种运行模式

  • 活动 MDS, 负责管理 CephFS 文件系统上的元数据。

  • 备用 MDS, 充当备份,并会在活动 MDS 无响应时切换到活动模式。

CephFS 文件系统至少需要一个活跃的 MDS 服务,最好再部署一个备用 MDS 以确保可用性。

MDS 配置选项:

  • MDS 等级,设置集群中活动 MDS 守护进程的最大数量,由 max_mds 定义。MDS 守护进程在启动时没有等级,MON 守护进程负责为它们分配1个等级,也就是集群中只有一个活动 MDS。

  • 卷、子卷和子卷组:

    • CephFS卷,对应一个 CephFS 文件系统。
    • CephFS 子卷,对应 CephFS **文件系统子目录。**在创建子卷时,用户可指定更细致的权限管理,如子卷的 UID、GID、文件模式、大小和子卷组。
    • CephFS 子卷组,对应一组子卷。
  • 文件系统关联性,将用户的 CephFS 文件系统配置为首选某一个 MDS **。**例如,用户可配置为首选在速度更快的服务器上运行的 MDS。文件系统关联性通过 mds_join_fs 选项进行配置。

  • MDS 缓存大小限制 ,通过 mds_cache_memory_limit 选项限制最大内存,mds_cache_size 选项定义最大索引节点数,以限制 MDS 缓存的大小。

  • 配额,配置用户的 CephFS **文件系统,以限制使用配额存储的字节数或文件数。**FUSE 和Kernel 客户端都支持在挂载 CephFS 文件系统时检查配额。这些客户端还负责在用户达到配额限值时,停止向 CephFS 文件系统写入数据。使用 setfattr 命令的 ceph.quota.max_bytes 和ceph.quota.max_files 选项可设置限值。

客户端访问 CephFS 过程
  1. CephFS 客户端首先会联系 MON 进行身份验证并检索集群映射。
  2. 完成上一步后,客户端从集群映射中获取到活动 MDS信息。
  3. 客户端向活动 MDS 索取文件元数据。
  4. 然后客户端直接与 OSD 通信,使用元数据来访问文件或目录。

部署 CephFS

部署 CephFS 方法:

  1. 手动部署,步骤多,可以控制每个步骤。
  2. 卷部署,步骤少,简单方便,无法控制每个步骤。
手动部署 CephFS

部署 CephFS 流程:

  1. 创建所需池
  2. 创建 CephFS 文件系统
  3. 部署 MDS 守护进程
创建 CephFS
bash 复制代码
[root@ceph1 ~ 16:06:50]# ceph osd pool create cephfs.cephfs1.data.1
pool 'cephfs.cephfs1.data.1' created
[root@ceph1 ~ 16:07:10]# ceph osd pool create cephfs.cephfs1.meta
pool 'cephfs.cephfs1.meta' created
[root@ceph1 ~ 16:07:20]# ceph osd pool set cephfs.cephfs1.meta size 3
set pool 11 size to 3
[root@ceph1 ~ 16:07:40]# ceph fs new cephfs1 cephfs.cephfs1.meta cephfs.cephfs1.data.1
  Pool 'cephfs.cephfs1.data.1' (id '10') has pg autoscale mode 'on' but is not marked as bulk.
  Consider setting the flag by running
    # ceph osd pool set cephfs.cephfs1.data.1 bulk true
new fs with metadata pool 11 and data pool 10
[root@ceph1 ~ 16:08:21]# ceph osd pool create cephfs.cephfs1.data.2
pool 'cephfs.cephfs1.data.2' created
[root@ceph1 ~ 16:08:44]# ceph fs add_data_pool cephfs1 cephfs.cephfs1.data.2
  Pool 'cephfs.cephfs1.data.2' (id '12') has pg autoscale mode 'on' but is not marked as bulk.
  Consider setting the flag by running
    # ceph osd pool set cephfs.cephfs1.data.2 bulk true
added data pool 12 to fsmap
[root@ceph1 ~ 16:09:16]# ceph orch apply mds cephfs1 --placement="3 ceph1.dyx.cloud ceph2.dyx.cloud ceph3.dyx.cloud"
Scheduled mds.cephfs1 update...
[root@ceph1 ~ 16:09:58]# ceph fs ls
name: cephfs1, metadata pool: cephfs.cephfs1.meta, data pools: [cephfs.cephfs1.data.1 cephfs.cephfs1.data.2 ]
[root@ceph1 ~ 16:10:04]# ceph fs status
cephfs1 - 0 clients
=======
RANK  STATE           MDS              ACTIVITY     DNS    INOS   DIRS   CAPS
 0    active  cephfs1.ceph1.ozyccy  Reqs:    0 /s    10     13     12      0
         POOL            TYPE     USED  AVAIL
 cephfs.cephfs1.meta   metadata  96.0k  55.9G
cephfs.cephfs1.data.1    data       0   55.9G
cephfs.cephfs1.data.2    data       0   55.9G
    STANDBY MDS
cephfs1.ceph3.iihfzy
cephfs1.ceph2.vkpvmk
MDS version: ceph version 16.2.15 (618f440892089921c3e944a991122ddc44e60516) pacific (stable)
[root@ceph1 ~ 16:10:19]# ceph df
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
hdd    180 GiB  177 GiB  2.8 GiB   2.8 GiB       1.56
TOTAL  180 GiB  177 GiB  2.8 GiB   2.8 GiB       1.56

--- POOLS ---
POOL                       ID  PGS   STORED  OBJECTS     USED  %USED  MAX AVAIL
device_health_metrics       1    1  6.1 KiB        3   18 KiB      0     56 GiB
images_pool                 2   32   53 MiB       83  159 MiB   0.09     56 GiB
images_pool_2               3   32  4.8 KiB        3   26 KiB      0     56 GiB
.rgw.root                   4   32  3.7 KiB       16  180 KiB      0     56 GiB
storage.rgw.log             5   32   23 KiB      338  1.9 MiB      0     56 GiB
storage.rgw.control         6   32      0 B        8      0 B      0     56 GiB
storage.rgw.meta            7   32  1.2 KiB        8   84 KiB      0     56 GiB
storage.rgw.buckets.index   8   32      0 B       11      0 B      0     56 GiB
storage.rgw.buckets.data    9   32      0 B        0      0 B      0     56 GiB
cephfs.cephfs1.data.1      10   32      0 B        0      0 B      0     56 GiB
cephfs.cephfs1.meta        11   32  2.3 KiB       22   96 KiB      0     56 GiB
cephfs.cephfs1.data.2      12   32      0 B        0      0 B      0     56 GiB
[root@ceph1 ~ 16:10:29]# ceph mds stat
cephfs1:1 {0=cephfs1.ceph1.ozyccy=up:active} 2 up:standby
[root@ceph1 ~ 16:10:39]# ceph orch ls mds
NAME         PORTS  RUNNING  REFRESHED  AGE  PLACEMENT                                  
mds.cephfs1             3/3  42s ago    49s  ceph1.dyx.cloud;ceph2.dyx.cloud;ceph3.dyx.cloud;count:3
[root@ceph1 ~ 16:10:47]#
删除 CephFS

删除流程如下:

  1. 删除服务
  2. 删除文件系统
  3. 删除池

删除过程如下:

bash 复制代码
[root@ceph1 ~ 16:27:18]# ceph fs set cephfs1 down true
cephfs1 marked down.

# 删除服务
[root@ceph1 ~ 16:27:03]# ceph orch rm mds.cephfs1
Removed service mds.cephfs1

# 如果需要删除 CephFS,请先备份所有数据,
# 因为删除 CephFS 文件系统会破坏该文件系统上存储的所有数据。

# 要删除 CephFS,首先要将其标记为 down
[root@ceph1 ~ 16:27:18]# ceph fs set cephfs1 down true
cephfs1 marked down.

# 然后删除 CephFS
[root@ceph1 ~ 16:27:37]# ceph fs rm cephfs1 --yes-i-really-mean-it

# 删除池
[root@ceph1 ~ 16:27:56]# ceph config set mon mon_allow_pool_delete true
[root@ceph1 ~ 16:28:21]# ceph osd pool ls
device_health_metrics
images_pool
images_pool_2
.rgw.root
storage.rgw.log
storage.rgw.control
storage.rgw.meta
storage.rgw.buckets.index
storage.rgw.buckets.data
cephfs.cephfs1.data.1
cephfs.cephfs1.meta
cephfs.cephfs1.data.2

[root@ceph1 ~ 16:28:31]# ceph osd pool rm cephfs.cephfs1.meta cephfs.cephfs1.meta --yes-i-really-really-mean-it
pool 'cephfs.cephfs1.meta' removed

[root@ceph1 ~ 16:29:26]# ceph osd pool rm cephfs.cephfs1.data.1 cephfs.cephfs1.data.1 --yes-i-really-really-mean-it
pool 'cephfs.cephfs1.data.1' removed

[root@ceph1 ~ 16:29:45]# ceph osd pool rm cephfs.cephfs1.data.2 cephfs.cephfs1.data.2 --yes-i-really-really-mean-it
pool 'cephfs.cephfs1.data.2' removed
卷部署 CephFS
创建 CephFS
bash 复制代码
# 部署三个实例
[root@ceph1 ~ 16:29:56]# ceph fs volume create cephfs2 --placement="3 ceph1.dyx.cloud ceph2.dyx.cloud ceph3.dyx.cloud"

# 查看文件系统清单
[root@ceph1 ~ 16:30:45]# ceph fs ls
name: cephfs2, metadata pool: cephfs.cephfs2.meta, data pools: [cephfs.cephfs2.data ]

# 查看mds服务状态
[root@ceph1 ~ 16:30:51]# ceph mds stat
cephfs2:1 {0=cephfs2.ceph3.sjuekk=up:active} 2 up:standby

# 查看mds服务守护进程
[root@ceph1 ~ 16:31:05]# ceph orch ls mds
NAME         PORTS  RUNNING  REFRESHED  AGE  PLACEMENT                                  
mds.cephfs2             3/3  26s ago    32s  ceph1.dyx.cloud;ceph2.dyx.cloud;ceph3.dyx.cloud;count:3
删除 CephFS
bash 复制代码
[root@ceph1 ~ 16:31:18]# ceph fs volume ls
[
    {
        "name": "cephfs2"
    }
]
[root@ceph1 ~ 16:31:26]# ceph fs volume rm cephfs2 --yes-i-really-mean-it
metadata pool: cephfs.cephfs2.meta data pool: ['cephfs.cephfs2.data'] removed
[root@ceph1 ~ 16:31:54]# ceph fs ls
No filesystems enabled

挂载 CephFS 文件系统

环境准备

创建 cephfs1 和 cephfs2。

bash 复制代码
#验证删除是否干净
[root@ceph1 ~ 09:47:45]# ceph fs ls
No filesystems enabled
[root@ceph1 ~ 09:48:13]# ceph fs volume create cephfs1 --placement="3 ceph1.dyx.cloud ceph2.dyx.cloud ceph3.dyx.cloud"
[root@ceph1 ~ 09:49:02]# ceph fs volume create cephfs2 --placement="3 ceph1.dyx.cloud ceph2.dyx.cloud ceph3.dyx.cloud"
CephFS 挂载方式

用户可使用以下方式挂载 CephFS 文件系统:

  • Kernel 挂载,要求 Linux 内核版本达到 4 或以上,从 RHEL 8 开始可用。对于之前的内核版本,请改用FUSE 客户端。

  • FUSE 挂载

这两个挂载方式各有优势和劣势:

  • Kernel 挂载,不支持配额,但速度可能较快。

  • FUSE 挂载,支持配额和 ACL。 ACL 功能需要在挂载时明确指定该功能以启用。

CephFS 挂载用户

通过 ceph fs authorize 命令,可为 CephFS 文件系统中的不同用户和文件夹提供精细的访问控制。

CephFS 文件系统支持不同访问选项:

  • **r:对指定文件夹的读取权限。**如果未指定其他限制,则会向子文件夹授予读取权限。

  • **w:对指定文件夹的写入权限。**如果未指定其他限制,则会向子文件夹授予写入权限。

  • p:除了 r 和 w 功能外,客户端还需要 p 选项才能使用布局或配额

  • s :除了 r 和 w 功能外,客户端还需要 s 选项才能创建快照

示例1:允许用户对 / 文件夹具备读取、写入、配额和快照权限,并保存用户凭据。

bash 复制代码
[root@ceph1 ~ 09:49:20]# ceph fs authorize cephfs1 client.cephfs1-all-user / rwps > /etc/ceph/ceph.client.cephfs1-all-user.keyring

示例2:允许用户读取 root 文件夹,并提供对 /dir2 文件夹的读取、写入和快照权限,并保存用户凭据。

bash 复制代码
[root@ceph1 ~ 09:51:29]# ceph fs authorize cephfs1 client.cephfs1-restrict-user / r /dir2 rw > /etc/ceph/ceph.client.cephfs1-restrict-user.keyring
CephFS 客户端挂载准备

要挂载基于 CephFS 的文件系统,请验证客户端主机是否满足以下条件:

  • 安装 ceph-common 软件包。对于 FUSE 客户端,还要安装 ceph-fuse 软件包。
bash 复制代码
[root@client ~ 09:49:11]# yum install -y ceph-common
Last metadata expiration check: 16:02:16 ago on Tue 02 Dec 2025 05:49:43 PM CST.
Package ceph-common-2:16.2.15-1.el8s.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
  • 复制 Ceph 配置文件到客户端。

    bash 复制代码
    [root@ceph1 ~ 09:54:09]# scp /etc/ceph/ceph.conf root@client:/etc/ceph/ceph.conf
    root@client's password:
    ceph.conf                                             100%  283   373.4KB/s   00:00
  • 将用户keyring复制到客户端主机上的 /etc/ceph 文件夹。

    bash 复制代码
    [root@ceph1 ~ 09:51:38]# scp /etc/ceph/ceph.client.cephfs1-restrict-user.keyring root@client:/etc/ceph/
    root@client's password:
    
    ceph.client.cephfs1-restrict-user.keyring             100%   79    41.2KB/s   00:00
    
    [root@ceph1 ~ 09:53:31]# scp /etc/ceph/ceph.client.cephfs1-all-user.keyring root@client:/etc/ceph/
    root@client's password:
    ceph.client.cephfs1-all-user.keyring                  100%   74    82.6KB/s   00:00

为了方便管理集群,我们将admin凭据复制到client。

bash 复制代码
[root@ceph1 ~ 09:53:41]# scp /etc/ceph/ceph.client.admin.keyring root@client:/etc/ceph/
root@client's password:
ceph.client.admin.keyring                             100%  151   217.6KB/s   00:00

[root@client ~ 09:54:50]# cd /etc/ceph/
[root@client ceph 09:55:52]# ls
ceph.client.admin.keyring                  ceph.client.rbd.keyring
ceph.client.cephfs1-all-user.keyring       ceph.conf
ceph.client.cephfs1-restrict-user.keyring  rbdmap
使用 Kernel 挂载 CephFS
挂载 CephFS

使用 mount.ceph 命令挂载文件系统:

bash 复制代码
# mount.ceph [src] [mount-point] [-n] [-v] [-o ceph-options]
# 或者
# mount -t ceph [src] [mount-point] [-n] [-v] [-o ceph-options]

用户可以指定逗号分隔的多个 MON 来挂载设备。标准端口 (6789) 为默认值,用户也可在各个MON 名称的后面添加冒号和非标准端口号。建议指定多个 MON,以防文件系统挂载时有些 MON 处于脱机状态。

bash 复制代码
[root@client ceph 09:55:54]# mount.ceph
usage: mount.ceph [src] [mount-point] [-n] [-v] [-o ceph-options]
options:
        -h: Print this help
        -n: Do not update /etc/mtab
        -v: Verbose
        ceph-options: refer to mount.ceph(8)

使用 CephFS Kernel 客户端时,可用选项有:

  • fs=fs-name,指定要挂载的 CephFS 文件系统名称。未提供值时,它会使用默认文件系统。

  • name=name,指定Cephx 客户端 ID。默认为 guest。

  • secret=secret_value,指定客户端的机密密钥的值。

  • secretfile=secret_key_file,指定包含此客户端机密密钥的文件的路径。

  • rsize=bytes,指定最大读取大小,以字节为单位。

  • wsize=bytes,指定最大写入大小,以字节为单位。默认为不写入。

示例1:使用不受限账户挂载 cephfs 文件系统。

bash 复制代码
[root@client ~ 09:56:06]# mkdir /mnt/cephfs1
[root@client ~ 09:56:17]# mount.ceph ceph1.dyx.cloud:/ /mnt/cephfs1 -o name=cephfs1-all-user,fs=cephfs1
[root@client ~ 09:56:56]# df -h /mnt/cephfs1/
Filesystem        Size  Used Avail Use% Mounted on
192.168.108.11:/   56G     0   56G   0% /mnt/cephfs1

[root@client ~ 09:57:04]# mkdir /mnt/cephfs1/{dir1,dir2}
[root@client ~ 09:57:23]# echo hello world > /mnt/cephfs1/dir1/welcome.txt
[root@client ~ 09:57:44]# dd if=/dev/zero of=/mnt/cephfs1/dir1/file-100M bs=1M count=100100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.134463 s, 780 MB/s
[root@client ~ 09:58:13]# yum install -y tree

[root@client ~ 09:58:27]# tree /mnt/cephfs1/
/mnt/cephfs1/
├── dir1
│   ├── file-100M
│   └── welcome.txt
└── dir2

2 directories, 2 files

# 3副本池,创建100M文件,文件系统空间减少100M
[root@client ~ 09:58:34]# df -h /mnt/cephfs1/
Filesystem        Size  Used Avail Use% Mounted on
192.168.108.11:/   56G  `100M`   56G   1% /mnt/cephfs1

# 3副本池,创建100M文件,cephfs.cephfs_data 池系统空间使用300M

[root@client ~ 09:58:48]# ceph fs status
cephfs1 - 1 clients
=======
RANK  STATE           MDS              ACTIVITY     DNS    INOS   DIRS   CAPS
 0    active  cephfs1.ceph1.ivblrq  Reqs:    0 /s    14     17     14      5
        POOL           TYPE     USED  AVAIL
cephfs.cephfs1.meta  metadata   204k  55.8G
cephfs.cephfs1.data    data     `300M`  55.8G
cephfs2 - 0 clients
=======
RANK  STATE           MDS              ACTIVITY     DNS    INOS   DIRS   CAPS
 0    active  cephfs2.ceph2.cdgapk  Reqs:    0 /s    10     13     12      0
        POOL           TYPE     USED  AVAIL
cephfs.cephfs2.meta  metadata  96.0k  55.8G
cephfs.cephfs2.data    data       0   55.8G
    STANDBY MDS
cephfs1.ceph3.ljxfix
cephfs1.ceph2.wqygob
cephfs2.ceph3.butcgy
cephfs2.ceph1.wonbsz
MDS version: ceph version 16.2.15 (618f440892089921c3e944a991122ddc44e60516) pacific (stable)

# 卸载文件系统
[root@client ~ 09:59:00]# umount /mnt/cephfs1/

示例2:使用受限账户挂载 cephfs 文件系统

bash 复制代码
# 挂载
[root@client ~ 10:30:31]# mount.ceph ceph1.dyx.cloud:/ /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1

# 验证权限
[root@client ~ 10:31:15]# touch /mnt/cephfs1/dir1/cephfs1.restrict-user-file1
touch: cannot touch '/mnt/cephfs1/dir1/cephfs1.restrict-user-file1': Permission denied
[root@client ~ 10:31:51]# touch /mnt/cephfs1/dir2/cephfs1.restrict-user-file1
[root@client ~ 10:31:59]# tree /mnt/cephfs1/
/mnt/cephfs1/
├── dir1
│   ├── file-100M
│   └── welcome.txt
└── dir2
    └── cephfs1.restrict-user-file1

2 directories, 3 files

# 卸载文件系统
[root@client ~ 10:32:06]# umount /mnt/cephfs1/
挂载特定子目录

通过 CephFS Kernel 客户端,用户可从 CephFS 文件系统挂载特定子目录。

本例从 CephFS 文件系统的 root 中挂载了名为 /dir2 的目录:

bash 复制代码
[root@client ~ 10:32:15]# mount -t cph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1
mount: /mnt/cephfs1: unknown filesystem type 'cph'.
[root@client ~ 10:33:02]# mount -t ceph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1
[root@client ~ 10:33:10]# touch /mnt/cephfs1/cephfs1.restrict-user-file12
[root@client ~ 10:33:28]# tree /mnt/cephfs1/
/mnt/cephfs1/
├── cephfs1.restrict-user-file1
└── cephfs1.restrict-user-file12

0 directories, 2 files

# 卸载文件系统
[root@client ~ 10:33:39]# umount /mnt/cephfs1/
[root@client ~ 10:33:56]#

永久挂载文件系统

要使用Kernel 客户端永久挂载 CephFS 文件系统,可以将以下格式条目添加到 /etc/fstab 文件中:

示例:(看看语法,不用操作)

bash 复制代码
ceph1.laogao.cloud:/dir2 /mnt/cephfs1 ceph name=cephfs1-restrictuser,fs=cephfs1,_netdev 0 0
使用 FUSE 挂载 CephFS

卸载之前挂载的:

bash 复制代码
[root@client ~ 10:52:43]# umount /mnt/cephfs1/
umount: /mnt/cephfs1/: not mounted.

以非 root 用户身份使用 FUSE 客户端时,需在 /etc/fuse.conf 配置文件中添user_allow_other

使用 FUSE 挂载 CephFS,需要额外安装ceph-fuse软件:

bash 复制代码
[root@client ~ 10:52:44]# dnf install -y ceph-fuse
Last metadata expiration check: 0:17:49 ago on Wed 03 Dec 2025 10:35:08 AM CST.
Dependencies resolved.
========================================================================================
 Package             Architecture     Version                      Repository      Size
 ... ...
挂载 CephFS

使用 FUSE 客户端挂载 CephFS 文件系统语法:

bash 复制代码
[root@client ~ 10:53:08]# ceph-fuse --help
usage: ceph-fuse [-n client.username] [-m mon-ip-addr:mon-port] <mount point> [OPTIONS]
  --client_mountpoint/-r <sub_directory>
                    use sub_directory as the mounted root, rather than the full Ceph tree.

usage: ceph-fuse [options] <mountpoint>

FUSE options:
    -h   --help            print help
    -V   --version         print version
    -d   -o debug          enable debug output (implies -f)
    -f                     foreground operation
    -s                     disable multi-threaded operation
    -o clone_fd            use separate fuse device fd for each thread
                           (may improve performance)
    -o max_idle_threads    the maximum number of idle worker threads
                           allowed (default: 10)
    -o allow_other         allow access by all users
    -o allow_root          allow access by root
    -o auto_unmount        auto unmount on process termination

  --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@client ~ 10:53:11]# ceph-fuse -n client.cephfs1-restrict-user /mnt/cephfs1/
ceph-fuse[2365]: starting ceph client
2025-12-03T10:53:39.728+0800 7fa2cdb133c0 -1 init, newargv = 0x5581bfed8d20 newargc=13

2025-12-03T10:53:39.728+0800 7fa2cdb133c0 -1 init, args.argv = 0x5581bfed8ed0 args.argc=4

ceph-fuse[2365]: starting fuse
[root@client ~ 10:53:39]# tree /mnt/cephfs1/
/mnt/cephfs1/
├── dir1
│   ├── file-100M
│   └── welcome.txt
└── dir2
    ├── cephfs1.restrict-user-file1
    └── cephfs1.restrict-user-file12

2 directories, 4 files


[root@client ~ 10:53:48]# umount /mnt/cephfs1/
挂载特定子目录

CephFS FUSE 客户端默认会挂载所访问文件系统的 root 目录 (/)。用户可使用 ceph-fuse -r directory 命令挂载特定目录。如果 CephFS 卷中不存在该目录,此操作会失效。

bash 复制代码
[root@client ~ 10:53:55]# ceph-fuse -n client.cephfs1-restrict-user -r /dir2 /mnt/cephfs1/
ceph-fuse[2449]: starting ceph client
2025-12-03T10:54:27.382+0800 7f4bb5f893c0 -1 init, newargv = 0x55bbb1db4c20 newargc=13

2025-12-03T10:54:27.382+0800 7f4bb5f893c0 -1 init, args.argv = 0x55bbb1db4dd0 args.argc=4

ceph-fuse[2449]: starting fuse
[root@client ~ 10:54:27]# tree /mnt/cephfs1/
/mnt/cephfs1/
├── cephfs1.restrict-user-file1
└── cephfs1.restrict-user-file12

0 directories, 2 files
[root@client ~ 10:54:34]# umount /mnt/cephfs1/

用户在配置多个 CephFS 文件系统时,CephFS FUSE 客户端会挂载默认的 CephFS 文件系统。要挂载特

定文件系统,使用 --client_fs 选项。

ceph-fuse -n client.cephfs1-restrict-user -r /dir2 --client_fs cephfs1 /mnt/cephfs1

永久挂载文件系统

要使用 FUSE 客户端永久挂载 CephFS 文件系统,可以将以下条目添加到 /etc/fstab 文件中:

bash 复制代码
ceph1.laogao.cloud /mnt/cephfs1 fuse.ceph ceph.id=cephfs1-restrict-user,_netdev 0
0

**注意:**ceph-fuse方式持久化挂载,不支持挂载特定子目录。

管理 CephFS

实验环境准备

使用受限账户挂载 cephfs。

bash 复制代码
[root@client ~ 11:34:46]# mount.ceph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1
管理快照

CephFS 默认会启用快照功能,这些快照存储在名为 .snap 的隐藏目录中

启停快照功能

使用 ceph fs set 命令停用特定 CephFS 文件系统快照功能。

bash 复制代码
[root@client ~ 11:35:39]# ceph fs set cephfs1 allow_new_snaps false
disabled new snapshots

使用 ceph fs set 命令启用特定 CephFS 文件系统快照功能。

bash 复制代码
[root@client ~ 11:36:04]# ceph fs set cephfs1 allow_new_snaps true
enabled new snapshots
创建快照

若要创建快照,在 .snap **目录中创建一个子目录。**快照名称就是新子目录名称。此快照包含 CephFS 文

件系统中所有当前文件的副本。

普通用户是没有创建快照权限的。

bash 复制代码
[root@client ~ 11:36:12]# mkdir /mnt/cephfs1/.snap/snap
mkdir: cannot create directory '/mnt/cephfs1/.snap/snap': Permission denied

[root@client ~ 11:36:30]# ceph auth get client.cephfs1-restrict-user
[client.cephfs1-restrict-user]
        key = AQCqly9pst6BKBAAI7jHqXb+2UnzTZKmoTFSOw==
        caps mds = "allow r fsname=cephfs1, allow rw fsname=cephfs1 path=/dir2"
        caps mon = "allow r fsname=cephfs1"
        caps osd = "allow rw tag cephfs data=cephfs1"
exported keyring for client.cephfs1-restrict-user

授权客户端s权限为 CephFS 文件系统制作快照。

bash 复制代码
[root@client ~ 11:38:01]# ceph auth caps client.cephfs1-restrict-user \
mds "allow r fsname=cephfs1, allow rws fsname=cephfs1 path=/dir2" \
mon "allow r fsname=cephfs1" \
osd "allow rw tag cephfs data=cephfs1"

updated caps for client.cephfs1-restrict-user

重新挂载,再次创建快照

bash 复制代码
[root@client ~ 11:38:56]# umount /mnt/cephfs1/
[root@client ~ 11:39:03]# mount.ceph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1
[root@client ~ 11:39:16]# mkdir /mnt/cephfs1/.snap/snap                     
[root@client ~ 11:39:21]# ls /mnt/cephfs1/.snap/snap
cephfs1.restrict-user-file1  cephfs1.restrict-user-file12
使用快照恢复文件

要恢复文件,可将其从快照目录复制到另一常规树中。

bash 复制代码
[root@client ~ 11:39:38]# mkdir /restore
[root@client ~ 11:39:48]# cp /mnt/cephfs1/.snap/snap/cephfs1.restrict-user-file1 /restore/

若要从 .snap 目录树中完整恢复快照,可将普通条目替换为所选快照中的副本。

bash 复制代码
[root@client ~ 11:40:27]# yum install -y rsync
[root@client ~ 11:40:49]# rsync -a /mnt/cephfs1/.snap/snap/ /restore/
删除快照

若要丢弃快照,可在 .snap 中删除对应的目录。即使快照目录不为空,rmdir 命令也会成功,无需使用递归 rm 命令。

bash 复制代码
[root@client ~ 11:40:51]# rmdir /mnt/cephfs1/.snap/snap/

db133c0 -1 init, args.argv = 0x5581bfed8ed0 args.argc=4

ceph-fuse[2365]: starting fuse

root@client \~ 10:53:39\]# tree /mnt/cephfs1/ /mnt/cephfs1/ ├── dir1 │ ├── file-100M │ └── welcome.txt └── dir2 ├── cephfs1.restrict-user-file1 └── cephfs1.restrict-user-file12 2 directories, 4 files \[root@client \~ 10:53:48\]# umount /mnt/cephfs1/ ##### **挂载特定子目录** CephFS FUSE 客户端默认会挂载所访问文件系统的 root 目录 (/)。用户可使用 ceph-fuse -r directory 命令挂载特定目录。如果 CephFS 卷中不存在该目录,此操作会失效。 ```bash [root@client ~ 10:53:55]# ceph-fuse -n client.cephfs1-restrict-user -r /dir2 /mnt/cephfs1/ ceph-fuse[2449]: starting ceph client 2025-12-03T10:54:27.382+0800 7f4bb5f893c0 -1 init, newargv = 0x55bbb1db4c20 newargc=13 2025-12-03T10:54:27.382+0800 7f4bb5f893c0 -1 init, args.argv = 0x55bbb1db4dd0 args.argc=4 ceph-fuse[2449]: starting fuse [root@client ~ 10:54:27]# tree /mnt/cephfs1/ /mnt/cephfs1/ ├── cephfs1.restrict-user-file1 └── cephfs1.restrict-user-file12 0 directories, 2 files [root@client ~ 10:54:34]# umount /mnt/cephfs1/ 用户在配置多个 CephFS 文件系统时,CephFS FUSE 客户端会挂载默认的 CephFS 文件系统。要挂载特 定文件系统,使用 **--client_fs** 选项。 `ceph-fuse -n client.cephfs1-restrict-user -r /dir2 --client_fs cephfs1 /mnt/cephfs1` ###### **永久挂载文件系统** 要使用 FUSE 客户端永久挂载 CephFS 文件系统,可以将以下条目添加到 /etc/fstab 文件中: ```bash ceph1.laogao.cloud /mnt/cephfs1 fuse.ceph ceph.id=cephfs1-restrict-user,_netdev 0 0 ``` \*\*注意:\*\*ceph-fuse方式持久化挂载,不支持挂载特定子目录。 #### **管理** **CephFS** ##### **实验环境准备** 使用受限账户挂载 cephfs。 ```bash [root@client ~ 11:34:46]# mount.ceph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1 ``` ##### **管理快照** CephFS 默认会启用快照功能,**这些快照存储在名为** **.snap** **的隐藏目录中**。 ###### **启停快照功能** 使用 ceph fs set 命令停用特定 CephFS 文件系统快照功能。 ```bash [root@client ~ 11:35:39]# ceph fs set cephfs1 allow_new_snaps false disabled new snapshots ``` 使用 **ceph fs set** 命令启用特定 CephFS 文件系统快照功能。 ```bash [root@client ~ 11:36:04]# ceph fs set cephfs1 allow_new_snaps true enabled new snapshots ``` ###### **创建快照** **若要创建快照,在** **.snap** \*\*目录中创建一个子目录。\*\*快照名称就是新子目录名称。此快照包含 CephFS 文 件系统中所有当前文件的副本。 **普通用户是没有创建快照权限的。** ```bash [root@client ~ 11:36:12]# mkdir /mnt/cephfs1/.snap/snap mkdir: cannot create directory '/mnt/cephfs1/.snap/snap': Permission denied [root@client ~ 11:36:30]# ceph auth get client.cephfs1-restrict-user [client.cephfs1-restrict-user] key = AQCqly9pst6BKBAAI7jHqXb+2UnzTZKmoTFSOw== caps mds = "allow r fsname=cephfs1, allow rw fsname=cephfs1 path=/dir2" caps mon = "allow r fsname=cephfs1" caps osd = "allow rw tag cephfs data=cephfs1" exported keyring for client.cephfs1-restrict-user ``` 授权客户端s权限为 CephFS 文件系统制作快照。 ```bash [root@client ~ 11:38:01]# ceph auth caps client.cephfs1-restrict-user \ mds "allow r fsname=cephfs1, allow rws fsname=cephfs1 path=/dir2" \ mon "allow r fsname=cephfs1" \ osd "allow rw tag cephfs data=cephfs1" updated caps for client.cephfs1-restrict-user ``` 重新挂载,再次创建快照 ```bash [root@client ~ 11:38:56]# umount /mnt/cephfs1/ [root@client ~ 11:39:03]# mount.ceph ceph1.dyx.cloud:/dir2 /mnt/cephfs1 -o name=cephfs1-restrict-user,fs=cephfs1 [root@client ~ 11:39:16]# mkdir /mnt/cephfs1/.snap/snap [root@client ~ 11:39:21]# ls /mnt/cephfs1/.snap/snap cephfs1.restrict-user-file1 cephfs1.restrict-user-file12 ``` ###### **使用快照恢复文件** 要恢复文件,可将其从快照目录复制到另一常规树中。 ```bash [root@client ~ 11:39:38]# mkdir /restore [root@client ~ 11:39:48]# cp /mnt/cephfs1/.snap/snap/cephfs1.restrict-user-file1 /restore/ ``` 若要从 .snap 目录树中完整**恢复快照**,可将普通条目替换为所选快照中的副本。 ```bash [root@client ~ 11:40:27]# yum install -y rsync [root@client ~ 11:40:49]# rsync -a /mnt/cephfs1/.snap/snap/ /restore/ ``` ###### **删除快照** 若要丢弃快照,可在 .snap 中删除对应的目录。即使快照目录不为空,rmdir 命令也会成功,无需使用递归 rm 命令。 ```bash [root@client ~ 11:40:51]# rmdir /mnt/cephfs1/.snap/snap/ ```

相关推荐
-dcr8 小时前
44.ceph分布式存储
ceph
The star"'8 小时前
ceph(1-4)
运维·ceph
wanhengidc8 小时前
云手机 网络连接与持续性的表现如何
运维·服务器·科技·游戏·智能手机
小猿成长8 小时前
Ubuntu搭建物联网平台(ThingsBoard)教程
linux·运维·ubuntu
代码不行的搬运工8 小时前
RFC6811:BGP前缀源验证
运维·服务器·bgp网络
G皮T9 小时前
【云计算】云平台上的权限管理(四):VDC、企业项目、用户组
云计算·用户组·公有云·混合云·企业项目·vdc·虚拟数据中心
月亮!10 小时前
移动端测试重磅升级:跨平台自动化测试框架深度对比
运维·网络·人工智能·测试工具·容器·自动化·测试用例
凯子坚持 c10 小时前
Docker 容器全生命周期管理与运维命令深度解析
运维·docker·php
java_logo11 小时前
MILVUS Docker 容器化部署指南
运维·人工智能·docker·容器·prometheus·milvus