存储集群
存储设备
有两个在磁盘上存储数据的
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 <who>
# 例如查看 mon 的配置信息
$ ceph config get mon
# 修改指定组件的配置
$ ceph config set <who> <option> <value>
# 例如修改配置以允许用户删除 pool
$ ceph config set mon "mon_allow_pool_delete" true
# 查看当前组件的运行时配置信息
$ ceph config show <who>
# 例如查看 osd 组件信息
$ ceph config show osd.0
# 将从输入文件中提取配置文件,并将所有有效选项移至监视器的配置数据库。监视器无法识别,无效或无法控制的任何设置都将在输出文件中存储的简短配置文件中返回 。此命令对于从旧版配置文件过渡到基于集中式监视器的配置很有用。
$ ceph config assimilate-conf -i <input file> -o <output file>
# 查看指定组件的所有选项
$ ceph config show-with-defaults <who>
# 例如查看 osd 组件支持的所有选项
$ ceph config show osd.0
用户授权
当
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)管理
查看池
# 列出集群中的所有池
[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=<on,off,warn>]
# 示例
[root@ceph01 ~]# ceph osd pool create test_pool 16 16
pool 'test_pool' created
-
:{pool-name}
名称,集群唯一pool
-
{pg-num}
放置组总数,默认为 8,不适用于大多数情况pool
-
{pgp-num}
用于放置目的的放置组总数,这应等于展示位置组的总数,默认为 8pool
-
{replicated|erasure}
类型通过保留对象的多个副本(默认是3),以便replicated
发生故障时恢复;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}