存储集群
存储设备
有两个在磁盘上存储数据的 Ceph
守护程序:
- Ceph OSD 是大多数数据存储在
Ceph
中的地方。一般而言,每个OSD
都由单个存储设备支持。OSD
还可以由多种设备组合来支持,例如用于大多数数据的HDD
和用于某些元数据的SSD
。群集中OSD
的数量通常取决于存储的数据量,每个存储设备的容量以及冗余(复制或Erasure
)的级别和类型 - Ceph Monitor 管理关键的群集状态,例如群集成员身份和身份验证信息。对于较小的群集,只需要几 GB 的容量,尽管对于较大的群集,监控器数据库可以达到数十或数百GB的容量
OSD 后端
OSD
可以通过两种方式管理它们存储的数据。从 Luminous 12.2.z
版本开始,新的默认(推荐)后端是 BlueStore
。在 Luminous
之前,默认(也是唯一的选项)是 FileStore
BlueStore
BlueStore
是专用于存储的后端,专门用于管理 Ceph OSD
中的数据。BlueStore
的主要功能包括:
- 直接管理存储设备:
BlueStore
构建在裸磁盘设备之上,直接使用原始块设备或分区 RocksDB
的元数据管理:嵌入RocksDB
的键/值数据库管理内部元数据,例如从对象名称到磁盘上块位置的映射- 完整的数据和元数据校验和:默认情况下,所有写入
BlueStore
的数据和元数据都受到一个或多个校验和的保护。未经验证,不会从磁盘读取任何数据或元数据或将其返回给用户 - 内联压缩:写入的数据在写入磁盘之前可以选择压缩
- 多设备元数据分层:
BlueStore
允许将其内部日志写入单独的高速设备,以提高性能。如果有大量的快速存储可用,内部元数据也可以存储在更快的设备上 - 高效的写时复制:
RBD
和CephFS
快照依赖于在BlueStore
中有效实现的写时复制克隆机制。这将为常规快照和Erasure Code
(依赖克隆实现高效的两阶段提交)提供高效的IO
FILESTORE
-
FileStore
是在Ceph
中存储对象的传统方法。它依赖于标准文件系统(建议使用XFS
)以及键/值数据库(传统上是LevelDB
,现在是RocksDB
)来处理某些元数据 -
FileStore
经过了充分的测试,并在生产中广泛使用,但是由于其总体设计和对用于存储对象数据的传统文件系统的依赖,因此存在许多性能缺陷 - 尽管
FileStore
通常能够在大多数POSIX
兼容文件系统(包括btrfs
和ext4
)上运行,但是我们仅建议使用XFS
。btrfs
和ext4
都有已知的错误和缺陷,使用它们可能会导致数据丢失。默认情况下,所有Ceph
工具都使用XFS
配置 Ceph
当你启动 Ceph
服务时,初始化过程
将激活一系列在后台运行的守护程序。一个 Ceph 的存储集群上运行三种类型的守护程序:
Ceph Monitor
Ceph Manager
Ceph OSD
支持 Ceph File System
的 Ceph
存储集群至少运行一台 Ceph Metadata Server
;支持 Ceph Object Storage
的 Ceph
集群至少运行一个 Gateway
守护程序
配置源
每个 Ceph 守护进程,进程和库都将从以下列出的几个来源中提取其配置。如果同时存在,则列表后面的源将覆盖列表前面的源
- 编译的默认值
- 监视器集群的集中式配置数据库
- 存储在本地主机上的配置文件
- 环境变量
- 命令行参数
- 管理员设置的运行时替代
Ceph
进程在启动时要做的第一件事之一就是解析命令行参数,环境和本地配置文件提供的配置选项。然后,该过程将与监视器群集联系,以检索整个群集集中存储的配置。一旦可获得完整的配置视图,则将继续执行守护程序或进程
配置段
-
全局配置(
global
):global
的配置会影响Ceph
存储集群中的所有守护进程和客户端 -
监视器配置(
mon
):影响ceph-mon
,并覆盖相同设置的global
-
管理器配置(
mgr
):影响ceph-mgr
,并覆盖相同设置的global
-
OSD
配置:影响ceph-osd
,并覆盖相同设置的global
-
元数据服务器配置(
mds
):影响ceph-mds
,并覆盖相同设置的global
client
:客户端配置,影响所有的Ceph
客户端(例如,已安装的Ceph
文件系统,已安装的Ceph
块设备等)以及Rados Gateway
守护程序
使用 CLI 命令配置集群
# 查看集群所有可配置对象
$ ceph config dump
# 获取指定对象的配置信息
$ ceph config get
# 例如查看 mon 的配置信息
$ ceph config get mon
# 修改指定组件的配置
$ ceph config set
用户授权
当 Ceph
在启用身份验证和授权的情况下运行(默认情况下启用)时,您必须指定用户名和包含指定用户的私钥的密钥环(通常是通过命令行)。如果您未指定用户名,则 Ceph
将 client.admin
用作默认用户名。如果您未指定密钥环,则 Ceph
将通过 keyring
在 Ceph
的设置中寻找密钥环。例如,如果在不指定用户或密钥环的情况下执行命令:ceph health
$ ceph health
# ceph 将解释如下
$ ceph -n client.admin --keyring=/etc/ceph/ceph.client.admin.keyring health
# 或者, 可以使用 CEPH_ARGS 环境变量来避免重新输入用户名和密码
无论 Ceph
客户端的类型是什么(例如,块设备,对象存储,文件系统,本机 API 等),Ceph
都将所有数据存储作为对象在 pool
中。Ceph
用户必须有权访问 pool
才能读取和写入数据。此外,Ceph
用户必须具有执行权限才能使用 Ceph
的管理命令
用户
Ceph
用户具有用户类型 Type
的概念。出于用户管理的目的,类型始终为 client
Ceph
识别用户分隔形式由用户类型和用户 ID
组成:例如,TYPE.ID
,client.admin
,或 client.user1
引入用户类型的原因是因为 Ceph
监视器,OSD
和 Metadata Servers
也使用 Cephx
协议,但它们不是客户端。区分用户类型有助于区分客户端用户和其他用户-简化访问控制,用户监控和可追溯性
在使用 Ceph
命令行时,如果指定 --user
或 --id
则可省略用户类型,如果指定 --name
或 -n
则必须指定类型和名称
对象存储和文件系统
Ceph 存储群集用户
与 Ceph
对象存储用户和 Ceph
文件系统用户不同
Ceph 对象网关
使用 Ceph
存储群集用户在网关守护程序和存储群集之间进行通信,但是网关对最终用户具有自己的用户管理功能
Ceph 文件系统
使用 POSIX
语义,与 Ceph
文件系统关联的用户空间与 Ceph
存储集群用户不同
授权
Ceph
使用 caps
来描述授权经过身份验证的用户行使监视器,OSD
和 MDS
的功能
caps
可以根据应用程序标记来限制对池中数据,池中的名称空间或一组池的访问。Ceph
管理用户在创建或更新用户时设置用户的 caps
caps
语法格式:
{daemon-type} '{cap-spec}[, {cap-spec} ...]'
监控器授权:
# mon cap 包括 r, w, x 访问设置 或 profile {name}
$ mon 'allow {access-spec} [network {network/prefix}]'
$ mon 'profile {name}'
# {access-spec} 语法
$ * | all | [r][w][x]
# 可选的 [network {network/prefix}] 表示限制授权客户端网络来源(例如10.3.0.0/16)
OSD授权:
# OSD cap 包括 r, w, x, class-read, class-write 访问设置 或 profile {name}; 此外 OSD 还支持 pool 和 namespace 的设置
$ osd 'allow {access-spec} [{match-spec}] [network {network/prefix}]'
$ osd 'profile {name} [pool={pool-name} [namespace={namespace-name}]] [network {network/prefix}]'
# {access-spec} 语法是以下情况之一
$ * | all | [r][w][x] [class-read] [class-write]
$ class {class name} [{method name}]
# {match-spec} 语法是以下情况之一
$ pool={pool-name} [namespace={namespace-name}] [object_prefix {prefix}]
$ [namespace={namespace-name}] tag {application} {key}={value}
Manager 授权:
# mgr cap 包括 r, w, x 访问设置 或 profile {name}
$ mgr 'allow {access-spec} [network {network/prefix}]'
$ mgr 'profile {name} [{key1} {match-type} {value1} ...] [network {network/prefix}]'
# 还可以为特定命令, 内置管理器服务导出的所有命令或特定附加模块导出的所有命令指定管理器功能
$ mgr 'allow command "{command-prefix}" [with {key1} {match-type} {value1} ...] [network {network/prefix}]'
$ mgr 'allow service {service-name} {access-spec} [network {network/prefix}]'
$ mgr 'allow module {module-name} [with {key1} {match-type} {value1} ...] {access-spec} [network {network/prefix}]'
# {access-spec} 语法
$ * | all | [r][w][x]
# {service-name} 语法是以下情况之一
mgr | osd | pg | py
# {match-type} 语法是以下情况之一
= | prefix | regex
用户管理
添加用户
添加用户会创建一个用户名和一个秘钥。用户的密钥使用户可以通过 Ceph 存储群集进行身份验证。用户授权使用户在 ceph-mon
,ceph-osd
或 ceph-mds
上进行读取,写入或执行
添加用户的方式有以下几种:
ceph auth add
:此命令是添加用户的规范方法。它将创建用户,生成秘钥并添加指点权限ceph auth get-or-creat
:创建用户并返回用户名和密钥。如果用户已存在,则返回用户名和密钥ceph auth get-or-create-key
:创建用户并返回密钥。如果用户已存在,返回密钥
一般情况下,一个用户至少需要在 ceph-mon
上具有读取功能,在 ceph-osd
上具有读写功能
示例:
[root@ceph01 ~]# ceph auth add client.john mon 'allow r' osd 'allow rw pool=liverpool'
added key for client.john
[root@ceph01 ~]# ceph auth get-or-create client.paul mon 'allow r' osd 'allow rw pool=liverpool'
[client.paul]
key = AQBn5/peFEb0NhAA1PNAW7BNdW98xsIEsSyh1A==
[root@ceph01 ~]# ceph auth get-or-create client.george mon 'allow r' osd 'allow rw pool=liverpool' -o george.keyring
[root@ceph01 ~]# cat george.keyring
[client.george]
key = AQB75/peKljJCBAAmXGwZJHVVGbQ/jFKnHQH/A==
[root@ceph01 ~]# ceph auth get-or-create-key client.ringo mon 'allow r' osd 'allow rw pool=liverpool' -o ringo.key
[root@ceph01 ~]# cat ringo.key
AQCT5/peSuHhJxAAr8sgvdoYO6iQnSr48NG3lA==
查看用户
# 列出当前集群中的所有用户
[root@ceph01 ~]# ceph auth ls
installed auth entries:
client.admin
key: AQCiA/heKdmdBxAAfmu1yxvJA0DAZWx1gOB1lQ==
caps: [mds] allow *
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
......
# 查看指定用户的信息
[root@ceph01 ~]# ceph auth get client.admin
exported keyring for client.admin
[client.admin]
key = AQCiA/heKdmdBxAAfmu1yxvJA0DAZWx1gOB1lQ==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
# 导出用户
[root@ceph01 ~]# ceph auth export client.admin -o client.admin
export auth(key=AQCiA/heKdmdBxAAfmu1yxvJA0DAZWx1gOB1lQ==)
[root@ceph01 ~]# cat client.admin
[client.admin]
key = AQCiA/heKdmdBxAAfmu1yxvJA0DAZWx1gOB1lQ==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
# 打印用户秘钥
[root@ceph01 ~]# ceph auth print-key client.admin
AQCiA/heKdmdBxAAfmu1yxvJA0DAZWx1gOB1lQ==
修改用户权限
# 语法
$ ceph auth caps USERTYPE.USERID {daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]' [{daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]']
# 示例
# 获取当前用户信息
[root@ceph01 ~]# ceph auth get client.john
exported keyring for client.john
[client.john]
key = AQBU5/pew+gMLBAAbBj2BK+nrqt8Gm7zk/xRug==
caps mon = "allow r"
caps osd = "allow rw pool=liverpool"
# 修改 mon 权限为 rw, osd 权限为 rwx, 添加 mgr 只读权限
[root@ceph01 ~]# ceph auth caps client.john mon 'allow rw' osd 'allow rwx pool=liverpool' mgr 'allow r'
updated caps for client.john
[root@ceph01 ~]# ceph auth get client.john
exported keyring for client.john
[client.john]
key = AQBU5/pew+gMLBAAbBj2BK+nrqt8Gm7zk/xRug==
caps mgr = "allow r"
caps mon = "allow rw"
caps osd = "allow rwx pool=liverpool"
删除用户
# 语法
$ ceph auth del {TYPE}.{ID}
# 删除 client.john
[root@ceph01 ~]# ceph auth del client.john
updated
# 查看用户, 发现已经不存在
[root@ceph01 ~]# ceph auth get client.john
Error ENOENT: failed to find client.john in keyring
导入用户
# 语法
$ ceph auth import -i /etc/ceph/ceph.keyring
# 示例
[root@ceph01 ~]# ceph auth import -i /etc/ceph/ceph.keyring
# 注意:ceph 存储集群将添加新用户, 生成其密钥和权限; 并将更新现有用户和密钥即权限
池(pool)管理
pool
是 ceph
存储数据时的逻辑分区,它起到 namespace
的作用。每个 pool
包含一定数量的 PG
,PG
里的对象被映射到不同的 OSD
上,因此 pool
是分布到整个集群的
除了隔离数据,我们也可以分别对不同的 pool
设置不同的策略,比如副本数、数据清洗次数、数据块及对象大小等
查看池
# 列出集群中的所有池
[root@ceph01 ~]# ceph osd lspools
1 device_health_metrics
2 cephfs_data
3 cephfs_metadata
......
# 查看池的规则
[root@ceph01 ~]# ceph osd pool get cephfs_data crush_rule
crush_rule: replicated_rule
# 列出集群中池的详细信息
[root@ceph01 ~]# ceph osd dump
创建池
# 创建池
# 语法
$ ceph osd pool create {pool-name} [{pg-num} [{pgp-num}]] [replicated] \
[crush-rule-name] [expected-num-objects]
$ ceph osd pool create {pool-name} [{pg-num} [{pgp-num}]] erasure \
[erasure-code-profile] [crush-rule-name] [expected_num_objects] [--autoscale-mode=]
# 示例
[root@ceph01 ~]# ceph osd pool create test_pool 16 16
pool 'test_pool' created
{pool-name}
:pool
名称,集群唯一{pg-num}
:pool
放置组总数,默认为 8,不适用于大多数情况{pgp-num}
:pool
用于放置目的的放置组总数,这应等于展示位置组的总数,默认为 8{replicated|erasure}
:replicated
类型通过保留对象的多个副本(默认是3),以便OSD
发生故障时恢复;erasure
类型实现类似于RAID5
功能。replicated
需要更多存储空间,但比erasure
更加安全,erasure
需要较少的存储空间且性能相对较好,安全性相对较差。默认为replicated
[crush-rule-name]
:用于此池的CRUSH
规则的名称。指定的规则必须存在[erasure-code-profile=profile]
:仅用于erasure pool
--autoscale-mode=<on,off,warn>
:自动缩放模式,如果将自动缩放模式设置为on
或warn
,则可以让系统根据实际使用情况自动调整或建议对池中的放置组数量进行更改,默认行为由osd pool default pg autoscale mode
选项控制,使用ceph config get osd osd_pool_default_pg_autoscale_mode
查看[expected-num-objects]
:pool
预期对象数
关联池
# 将 pool 关联到应用程序。池在使用前需要与应用程序关联
[root@ceph01 ~]# ceph osd pool application enable test_pool rbd
enabled application 'rbd' on pool 'test_pool'
删除池
# 设置 mon 参数, 运行删除 pool
[root@ceph01 ~]# ceph config set mon mon_allow_pool_delete true
# 删除 pool, 要求指定两次 pool 以确定
[root@ceph01 ~]# ceph osd pool delete test_pool test_pool --yes-i-really-really-mean-it
pool 'test_pool' removed
pool 参数
# 设置 pool 参数, 语法如下
$ ceph osd pool set {pool-name} {key} {value}
# 具体参数设置参考 https://ceph.readthedocs.io/en/latest/rados/operations/pools/#set-pool-values
# 获取 pool 参数, 语法如下
$ ceph osd pool get {pool-name} {key}
# 可获取 key 信息参考 https://ceph.readthedocs.io/en/latest/rados/operations/pools/#get-pool-values
# 设置对象副本数
$ ceph osd pool set {poolname} size {num-replicas}
# 设置最小副本数
$ ceph osd pool set {poolname} min_size 2
# 获取对象副本数
$ ceph osd dump | grep 'replicated size'
常用管理命令
# 重命名池
$ ceph osd pool rename {current-pool-name} {new-pool-name}
# 列出集群中所有池的使用信息
$ rados df
# 获得集群中所有池或指定池的 I/O 信息
$ ceph osd pool stats [{pool-name}]
# 创建快照
$ ceph osd pool mksnap {pool-name} {snap-name}
# 查看快照
$ rados lssnap -p {pool-name}
# 删除快照
$ ceph osd pool rmsnap {pool-name} {snap-name}