[TOC]
4.1 Ceph服务管理
4.1.1 使用sysinit运行Ceph
在 RedHat 以及一些旧版的Debian/Ubuntu发行版中,sysinit是一个传统的但被推荐用于管理Ceph守护进程的方法
1 | /etc/init.d/ceph [options] [command] [dameons] |
[options]
1 | --verbose(-v) : 用于记录详细日志 |
[command]
1 | status : 显示守护进程状态 |
[dameons]
1 | mon |
根据类型启动守护进程
若要在本机启动monitor进程
1 | /etc/init.d/ceph start mon |
若在本地及远程主机上启动所有的monitor进程,添加 -a
选项
1 | /etc/init.d/ceph -a start mon |
其他类型的进程同理
1 | /etc/init.d/ceph -a start osd |
根据类型停止守护进程
1 | /etc/init.d/ceph -a stop mon |
启动及停止所有守护进程
1 | /etc/init.d/ceph -a start |
启动停止指定进程
1 | /etc/init.d/ceph -a start osd.0 |
4.1.2 把Ceph作为服务运行
1 | service ceph [options] [command] [dameons] |
[options]
1 | --verbose(-v) : 用于记录详细日志 |
[command]
1 | status : 显示守护进程状态 |
[dameons]
1 | mon |
4.2 管理CRUSH map
4.2.1 CRUSH map编译/反编译
在 ceph-deploy 部署完Ceph后,会生成一个默认的 CRUSH map,生产环境中需要定制 CRUSH map
若要获取CRUSH map的信息,需要进行反编译,修改后,编译注入会Ceph集群中,在系统运行时CRUSH map会马上生效
1 | 在任一个monitor节点上提取CRUSH map |
4.2.2 CRUSH map内部信息
CRUSH map:从软件角度表示集群的物理布局
包含一系列可用的 bucket(共同标识设备的具体物理位置)、Ceph池复制数据的规则
设备列表(device)
包含所有的OSD列表信息,由Ceph自行管理
- 在一个Ceph集群中,无论何时新增或移除一个新的OSD,CRUSH map设备列表都会自动更新。
若自行修改,则需要为OSD标注唯一的设备号
1 | devices |
bucket类型(Bucket types)
定义了CURSH map中会用到的bucket类型,表示OSD在CRUSH分层结构中的位置
- 节点bucket(nodes)表示物理位置,叶子bucket(leaves)表示ceph-osd守护进程和底层物理设备
Bucket由物理位置(磁盘、节点、机架(rack)、行(row)、开关、电源电路、房间、数据中心)的分层聚合以及它们被分配的权重(weights)组成。
CRUSH map包含很多默认的bucket类型,可以自行添加或删除bucket类型
- 添加bucket:输入ID与bucket名称
1 | types |
bucket实例(Bucket instances)
CRUSH map文件的buckets段定义了CRUSH层次结构中的bucket实例。
1 | [bucket-type] [bucket-name] { |
如:
weight :所有的磁盘无论其容量大小都要被加入到集群,Ceph需要在集群的所有磁盘上均匀读写数据。CRUSH为每个OSD分配一个权重,OSD权重越大,则物理存储容量越大。权重表示物理设备间的相对差异
alg :
uniform:所有存储设备权重都统一。当权重不统一时不能使用。在这种类型的bucket中添加或删除设备时数据都会被重新平衡(reshuffling of data)
List:链表类型的bucket将内容聚合成链表,新设备以头插法的方式插入。数据迁移最少,但移动存储设备会产生很多的数据移动。
适合很少或从不添加设备的场景,适合小集群,不适合大集群
tree:bucket被组织为带权二叉树,每个根节点都知道左右子树的总权重。提供优异的性能和重组效率
适合大项目,比链表式bucket高效
straw:在列表和树型bucket中选择一个设备时,需要计算一定数量的Hash和相对权重。采用分治法,给一些特定设备赋予更高优先级(列表开头的项目)。这会改善副本放置过程的性能,但在bucket被添加、删除或调整权重时产生重组
straw允许副本公平的放置在所有设备上。
适合:有设备删除但重组性能也很重要的场景
straw2:改进的straw算法。在设备A和B的权重都没改变时,避免数据移动。当新增设备C或删除设备C后,只会移动C上的数据到其他地方,而不会在bucket内其他设备间移动
减少了集群发生改变后的数据移动量
规则集(rules)
定义了如何从池中选择合适的bucket用于数据存放
要为每个池创建对应的CURSH规则集
1 | rule <rulename>{ |
step choose firstn {num} type {bucket-type}
在指定类型的bucket类型(一般为osd)中选取指定数量的桶,这个数字通常是存储池的副本数
step chooseleaf firstn {num} type {bucket-type}
选择 {bucket-type} 类型的一组bucket,并从各bucket的子树里选择一个叶子节点。这个数字通常是存储池的副本数
N为池副本数
num==0,选择N个bucket
0<num<N,选择num个bucket
若num<0,则选择 N-num个bucket
num=1,N=3,step choose firstn 1 type row
表示选择一个row类型的bucket
num=0,N=3,step chooseleaf firstn 0 type row
表示选择3个row类型的bucket,从各row的子树中各选一个叶子节点(osd)
4.2.3 CRUSH定位
CRUSH定位就是确定一个OSD在CRUSH map中的位置
4.2.4 Ceph中的各种map
Ceph monitor 负责监控整个集群的健康状态,以及维护集群成员关系状态 (cluster membership state)、对等节点(peer nodes)的状态,和集群的配置信息等。
Ceph monitor通过维护 cluster map 的主复制来实现这些功能。cluster map 是多个 map 的组合,包括monitor map、OSD map、PG map、CRUSH map 以及MDS map 等。这些map统称为 cluster map。
monitor map
- 集群ID
- monitor 节点名称(hostname)、IP地址和端口号等
- monitor map 被创建以来的最新版本号(epoch:每种 map 都维护着其历史版本,每个版本被称为一个epoch,epoch是一个单调递增的序列),以及最后修改时间等。
1 | ceph mon dump |
OSD map
- 集群ID
- 关于OSD的信息:数目、状态、权重、最近处于clean状态的间隔(last clean interval)及OSD主机等信息
- OSD map创建版本和最后一次修改信息
- 与池相关的信息:池名、池ID、类型、副本级别(replication level)和PG
1 | ceph osd dump |
PG map
- 最新的OSD map版本
- PG的版本、时间戳、容量充满比例(禁止客户端读写)以及容量接近充满(集群发出告警)的比例
- 跟踪每个PG ID(poolname.pgID)、对象数、状态时间戳、OSD的up集(所有副本所在OSD的有序列表,第一个为主OSD)、acting集(所有副本所在OSD的列表)
1 | ceph pg dump |
CRUSH map
- 集群的存储设备信息、故障域层次结构
- 在故障域中定义如何存储数据的规则
1 | ceph osd crush dump |
MDS map
- 集群中MDS的数目以及MDS状态
- 当前MDS map的版本,创建时间和修改时间
- 数据和元数据池的ID
1 | ceph mds dump |
4.3 横向扩展/缩容OSD集群
存储系统纵向扩展的设计方法:
- 向已有设备中添加磁盘,但到达一定程度后,会成为性能、容量以及可管理性方面的瓶颈
存储系统横向扩展的设计方法:
- 向现有的集群添加节点,包括:磁盘、CPU、内存
Ceph是一个无缝可扩展的存储系统,允许在线添加monitor和OSD节点到现有集群中,同时不造成服务下线
4.3.1 向Ceph中添加OSD节点
1 | 查看当前集群osd的详细情况 |
4.3.2 从Ceph集群中移除并关闭一个OSD
移除OSD
在移除OSD前,需要确保集群有足够的空余空间存放所移除节点上的数据
1 | 查看当前集群osd的详细情况 |
当把集群中的某个OSD标记为out时,属于它的所有PG中的数据都会被迁移至集群,直至集群再次平衡
在再平衡过程中,集群会有一段时间处于不健康状态(性能会下降),但对于客户端的数据访问服务都是正常的
1 | ceph -s #可以看到集群处于恢复模式,同时开放数服务 |
关闭OSD进程
1 | service ceph stop osd.9 |
一旦osd进程关闭,则OSD的状态是down和out
从CRUSH map中移除OSD
1 | ceph osd crush remove osd.9 |
从CRUSH map中移除OSD后,Ceph集群的状态变为健康状态
1 | ceph -s |
这时看到的是osd总数是不变的,但IN和UP状态的OSD是正常的,即OSD数量>IN数量,UP数量
从OSD map中移除OSD密钥
1 | 移除osd的验证密钥 |
此时,OSD总数与IN,UP状态的OSD数相等
从CRUSH map移除OSD所在节点信息
为保持集群清洁,执行一些清理操作
1 | ceph osd crush remove ceph-node4 |
4.3.3 替换出故障的磁盘设备
首先检查集群状态ceph -s
,若集群中没有出现故障磁盘,则状态是 HEALTH_OK
一旦OSD下线,则Ceph会将该OSD标记为 down,默认等待时间为300s
1 | ceph osd out osd.0 # 手动模拟磁盘故障 |
用新磁盘替换Ceph节点中出现故障的磁盘
一旦磁盘加入,标识磁盘在操作系统中的设备号
1 | 罗列所有磁盘 |
4.4 将池放置于不同OSD
实际生产中,需要在多种类型的存储设备上创建存储集群
- 基于SSD磁盘可以提供快速存储池
- 对于不需要更好的I/O性能的数据,可以在较慢的磁盘驱动器创建存储池
假设:
ceph-node1有三个SSD,ceph-node2和ceph-node3分别有三个SATA磁盘
现要创建一个ssd池和一个sata池,ssd池的主副本都在ceph-node1上,sata池的主副本交叉存放于ceph-node2和ceph-node3上
4.4.1 获取CURSH map
从任一个monitor节点上提取CRUSH map并反编译
1 | ceph osd getcrushmap -o crushmap-extract |
4.4.2 编辑CRUSH map
1 | vim crushmap-decompiled |
buckets定义
1 | buckets |
ruleset
1 | # rules |
为ssd池和sata池新增规则
1 | rule sata{ |
4.4.3 应用CRUSH map的修改
1 | crushtool -c crushmap-decompiled -o crushmap-compiled |
一旦将新的CRUSH map注入到Ceph集群,集群将会发生数据调整和数据恢复,并且很快进入 HEALTH_OK
状态
4.4.4 创建池
一旦集群处于健康状态,创建ssd池和sata池
1 | ceph osd pool create sata 64 64 |
为池指定规则
1 | ceph osd pool set sata crush_ruleset 3 |
4.4.5 向指定池写入数据
1 | 创建数据文件 |
4.6 身份验证和授权
4.6 监控集群
4.6.1 CLI
监控集群
集群健康状态
1 | ceph -health # 检查集群健康状况 |
集群事件
1 | ceph -w [optionss] #显示集群状态,包括Info(信息)、WRN(警告)、ERR(错误) |
集群利用率
1 | ceph df #输出集群的空间利用率统计信息 |
集群组件状态
1 | ceph status |
检查集群密钥
Ceph工作在一个基于密钥的验证系统上,所有组件之间的交互都经过基于密钥的验证系统
1 | ceph auth list# 获取所有密钥的列表 |
监控mon
monitor只有达到选举的法定人数才能保证集群功能正常
mon状态
1 | ceph mon stat #获取mon集群的状态 |
mon法定人数状态
Ceph集群中应该有超过 $\frac{1}{2}$ 的可用mon
1 | ceph quorum_status --format json-pretty |
监控OSD
集群越大,OSD越多,磁盘故障可能性很高
OSD树视图
OSD的树视图用于查看OSD的in、up、out或down等状态时
OSD树视图展示了每个节点的所有OSD以及所在CRUSH map中的位置
1 | ceph osd tree |
展示了Ceph OSD的信息
- 权重
- up/down状态
- in/out状态
输出格式会根据CRUSH map进行规则的格式化
OSD统计
1 | ceph osd dump #获取Ceph集群和OSD的详细信息 |
输出:
OSD map版本
- OSD ID
- 状态
- 权重
- 每个OSD的健康状态,版本区间等信息
池的细节
- 池ID
- 池名
- 池类型(复制、擦除)
- CRUSH 规则集和PG
1 | ceph osd blacklist ls #查看添加到黑名单的客户端 |
CRUSH map
使用CRUSH map命令行工具比手动查看和修改CRUSH map节省时间
1 | ceph osd tree # 获取当前集群布局 |
OSD 定位指令
当OSD数量多、CRUSH map层级多时,手动的 OSD 定位会很困难,需要借助CRUSH CLI
1 | ceph osd find <OSD_ID> |
监控PG
OSD 存储PG,PG包含对象
集群整体的健康状态主要取决于PG。只有PG的状态是 active+clean 状态,集群才会保持为 HELATH_OK 状态
PG的状态
无故障操作
creating :通常当存储池正在被创建或增加一个存储池的PG数量时会出现这种状态
active :处于active状态的PG,则主PG及其副本中的数据都处于可被客户端正常IO的状态
peering(对齐) :PG的OSD都处在acting集合中。peer操作:由主OSD发起的,存储PG副本的所有OSD,就PG的所有对象和元数据状态一致。完成后,存储PG的所有OSD都彼此确认当前状态,客户端可以读写
splitting(分割中) :PG正在被分割为多个PG。
在一个存储池的PG数增加后呈现
scrubbing(清理中) :PG正在做不一致性校验
PG出错
down(失效) :包含PG必需数据的一个副本失效了,因此PG失效
degraded :PG中部分对象未达到规定副本数,处于degraded状态的PG仍可被客户端IO
OSD处于down状态,Ceph将分配到该OSD上的所有PG状态变为degraded状态
在OSD重新up之后,执行peer操作,使得所有处于degraded状态的PG变为clean
如果OSD持续处于down状态超过300s后,OSD状态变为out
Ceph将会从副本中恢复所有处于degraded状态的PG保持复制级
Ceph认为对象应该存在于某个PG中,但该对象并不可用,此时将该PG状态置为degraded并从其副本中恢复PG
remapped :当PG的acting集合变化时,会触发数据迁移。数据从老的acting集合OSD向新的acting集合OSD转移
- 在迁移过程中,仍然使用老acting集合中的OSD为客户端提供读写请求
- 迁移完成,才会启用新acting 集合中的OSD为客户端提供读写请求
inconsistent(不一致) :PG的副本出现了不一致。如:对象大小不正确,recovery后某副本出现了对象丢失
incomplete(不完整) :PG日志缺失一个时间段的数据。当包含PG所需信息的某OSD失效或不可用,会出现这种情况
stable :如果PG acting集合中的主副本OSD未向monitor报告统计结果 或 其他OSD报告主副本OSD状态变为down,则monitor将这些PG处于stable状态。
通常Peering结束前PG处于该状态
repair(修复中) :PG正在被检查,被发现的任何不一致都被尽可能地修复
OSD异常处理
backfilling :新的OSD加入集群时,Ceph通过移动其他OSD上的一些PG到新OSD上保持负载均衡。
- 在后台平滑地执行backfill,确保集群不会超载
- backfill完成,OSD可以参与到客户端的IO操作
backfill-wait :PG正在等待回填操作
recovering :当一个OSD处于 down 状态,其PG中的内容会落后与放置在其他OSD上的PG副本。一旦该OSD处于up状态,Ceph会针对这些PG启动恢复操作,使得该PG中的数据与其他PG副本保持一致
relay(重做) :OSD崩后PG正在等待客户端重新发起请求
clean :主OSD和顺位OSD已经彼此确认;所有PG都在正确位置上,未发生偏移;所有都按副本级复制完成
监控PG
1 | ceph pg stat #获取PG状态 |
- vNNNN:PG map版本号
- X:总PG数
- Y:当前状态度的PG树
- R:当前集群处处的裸数据容量
- U:当前集群已经存储的包含副本的真是数据容量
- F:剩余容量
- T:总容量
1 | ceph pg dump # 获取PG列表 |
1 | ceph pg <PG_ID> query #查询一个PG的详细信息 |
1 | ceph pg dump_stuck <PG状态> # 获取处于stuck 状态的PG列表 |
监控MDS
1 | ceph mds stat |
4.6.2 REST API
Ceph自带REST API,允许用户通过编程的方式对集群进行管理,使其可以运行为一个WSGI应用或独立的服务器,默认监听5000端口
提供了一个类似Ceph命令的通过HTTP访问的接口,以HTTP GET和PUT请求的方式提交,结果以 json、XML、txt的格式返回
1 | 1.在Ceph集群中,创建一个用户client.restapi,授予它适当的 mon、osd 和mds权限: |
- 也可以不用 nohup来运行 ceph-rest-api,但会抑制后台运行
1 | 4. ceph-rest-api将会在 0.0.0.0:5000上监听,也可以用curl访问ceph-rest-api来查询集群的健康状态: |
ceph-rest-api 支持大多数 Ceph CLI。
1 | 查看ceph-rest-api的可用命令 |
以HTML形式返回,用Web浏览器访问访问更易读
要将它运行在生产环境中,最好部署多个它的实例,每个实例都是一个封装在 Web 服务器中的 WSGI应用,前端再使用一个负载均衡器。
4.6.3 开源管理控制平台
Kraken
Python,用来统计信息和监控Cepgh集群
- 集群数据量
- mon状态
- OSD状态
- PG状态
- 支持多个mon
- 变更OSD操作
- 动态CRUSH map配置
- Ceph身份验证
- 池操作
- 块设备管理
- CPU、内存等系统指标
1 | 1. 安装karen依赖,如python-pip、screen和Firefox |
Ceph-dash工具
用尽可能简单的方法通过RESTful JSON API及Web GUI来提供监控Ceph集群
python wsgi的应用程序,通过librados直接与集群通信
- 整体集群状态及详细的问题描述
- 支持多个mon、支持每个mon的状态
- OSD状态包含处于in、out和不健康的OSD数
- 可视化存储容量图
- 实时吞吐量,包括读写速度和每秒操作数
- 可视化PG状态图
- 集群恢复状态
在拥有wsgi的Web服务器(Apache、nginx)上部署这个应用程序
Ceph-dash访问Ceph集群是只读的,不需要任何写权限,通过Python的RADOS类来使用cepgh status命令,通过REST API或WebGUI导出输出结果
部署
1 | Ceph必须安装在有Ceph访问权限的节点上 |
Calamari
4.6.4 日志
默认情况下降日志存储在 /var/log/ceph目录下
[企业级]#13故障定位方法$13.1获取集群状态