“网红架构师”解决你的Ceph 运维难题-Part2

栏目: 服务器 · 发布时间: 6年前

内容简介:作者介绍哈喽大家好,“网红架构师”又来给大家分享Ceph运维难题解决方法了,没看过第一部分的,点开传送门开开心心过了

作者介绍

哈喽大家好,“网红架构师”又来给大家分享Ceph运维难题解决方法了,没看过第一部分的,点开传送门 “网红架构师”解决你的ceph运维难题-Part1 点开先温习一下,接下来,我们继续第二部分的内容:

Q13. ceph -s 的全称以及报错原因

开开心心过了 mon create-initial ,这个时候执行 ceph -s ,如果你恰好在monitor节点执行,那就会显示正常的信息,但是如果你在别的节点执行 ceph -s ,很有可能会报下面的错,但是有的节点又不会,所以这里花一点篇幅介绍 ceph -s 到底是怎么工作的。

[root@root cluster]# ceph -s
2017-01-17 13:47:34.190226 7f446ccde700 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin: (2) No such file or directory
2017-01-17 13:47:34.190393 7f446ccde700 -1 monclient(hunting): ERROR: missing keyring, cannot use cephx for authentication
2017-01-17 13:47:34.190443 7f446ccde700  0 librados: client.admin initialization error (2) No such file or directory

首先,如果你要执行 ceph 开头的任何指令,你当然要安装好Ceph客户端!( yum install ceph )而 ceph -s 的全称是:

ceph \
--name client.admin \
--keyring /etc/ceph/ceph.client.admin.keyring \
--conf /etc/ceph/ceph.conf
--cluster ceph \
-s

上面两个参数很好理解,Ceph内部自身使用 CephX 进行认证,和普通的认证没什么区别,同样需要用户名和密码进行认证,那么这里默认的用户名就叫做 client.admin ,而默认的秘钥保存位置就位于以下几个位置任一:

  • /etc/ceph/ceph.client.admin.keyring
  • /etc/ceph/ceph.keyring
  • /etc/ceph/keyring
  • /etc/ceph/keyring.bin

一般我们选择第一个,因为秘钥的命名规则采用 /etc/ceph/$cluster.$name.keyring 也就是集群名加上用户名再加上keyring的后缀组成。所以在我们执行 ceph -s 的时候,默认使用的是 client.admin 用户,同时会去那四个默认位置搜索该用户的秘钥,如果和集群保存的认证信息一致,那么就会显示出集群的状态。如果在那四个位置下面无法找到秘钥文件,就会报上面的 unable to find a keyring 这样的错误,解决方法后面再说。如果这个位置下面的秘钥文件保存了错误的秘钥值,就会报下面的错误:

2017-01-17 15:59:07.625018 7f8757577700  0 librados: client.admin authentication error (1) Operation not permitted
Error connecting to cluster: PermissionError

翻译过来很简单,就是认证不通过,就好比你使用了错误的密码,去登陆系统不通过一样。这可能是由于这个节点保存了旧的集群的秘钥信息导致的。

那么正确的秘钥信息保存在哪里呢?还记得部署目录吗,在 mon create-initial 正确通过后,就会自动收集所有的秘钥,并保存在部署目录下面,眼疾手快的把部署目录的 ceph.client.admin.keyring 拷贝到 /etc/ceph 下面就会发现 ceph -s 正常显示了,不过,这不是 授权 的正确的姿势。

如果我们想要给一个节点admin权限,也就是执行所有Ceph指令的权限,我们可以前往部署目录,然后调用下面的指令:

ceph-deploy admin xxNode

这样就会把部署目录下的 ceph.client.admin.keyringceph.conf 拷贝到xxNode的 /etc/ceph 目录下,并覆盖掉原先的秘钥文件,虽然实际上也就是scp了这两个文件,但是管理Ceph遵循一定的规则是一个很好的习惯。所以,想要得到 ceph -s 的正确输出,你需要确认在 /etc/ceph 目录下有 ceph.confceph.client.admin.keyring 这两个文件,并且和集群认证信息相同即可。如果认证失败,可以前往部署目录 授权 该节点。

Q14. ceph -s 卡住了

简单介绍下 ceph -s 的流程:

  • 每当你敲下一个Ceph指令时,相当于建立了一个Ceph的客户端进程去连接集群。
  • 连接集群需要知道MON的IP地址,这个地址从 /etc/ceph/ceph.conf 里面的 mon_host 读取。
  • 有了IP客户端就拿着自己用户名和秘钥向MON进行认证,认证通过执行指令返回输出。

如果你只有一个MON,然后这个MON挂掉了,那么执行指令会返回:

[root@blog ceph]# ceph -s
2017-01-19 17:49:45.437748 7f02f44e1700  0 -- :/1314350745 >> 139.224.0.251:6789/0 pipe(0x7f02f0063e80 sd=3 :0 s=1 pgs=0 cs=0 l=1 c=0x7f02f005c4f0).fault
2017-01-19 17:49:48.442946 7f02f43e0700  0 -- :/1314350745 >> 139.224.0.251:6789/0 pipe(0x7f02e4000c80 sd=3 :0 s=1 pgs=0 cs=0 l=1 c=0x7f02e4001f90).fault

Tips: MON的端口号为6789,所以一般看到IP:6789时,就可以判断这个IP的MON可能挂了,或者MON的防火墙开开了。上面的报错还好处理, 前往MON节点,检查 ceph-mon 进程是否正常运行,正确启动MON进程就可以了。

如果你有两个MON,挂了一个,指令会返回和上面一样的信息,所以,两个MON只能坏一个,一般MON个数都是 奇数个 。如果你有三个MON,挂了一个,那么会返回下面信息,集群还是会有输出的:

[root@st001 ~]# ceph -s
2017-01-19 17:59:40.753370 7f72ac31c700  0 -- :/4173548806 >> 10.8.0.101:6789/0 pipe(0x7f72a805e9d0 sd=3 :0 s=1 pgs=0 cs=0 l=1 c=0x7f72a805fce0).fault
2017-01-19 17:59:49.754198 7f72ac21b700  0 -- 10.8.0.101:0/4173548806 >> 10.8.0.101:6789/0 pipe(0x7f729c000b90 sd=4 :0 s=1 pgs=0 cs=0 l=1 c=0x7f729c0041e0).fault
    cluster 810eaecb-2b15-4a97-84ad-7340e6cbe969
    health HEALTH_WARN
            1 mons down, quorum 1,2 st002,st003
    monmap e1: 3 mons at {st001=10.8.0.101:6789/0,st002=10.8.0.102:6789/0,st003=10.8.0.103:6789/0}
            election epoch 18, quorum 1,2 st002,st003
...

客户端会去连挂掉的MON,如果过一秒钟左右连不上,就会连接剩下的MON,剩下的还有两个在运行,就连到了运行中的MON,一切输出照旧,就是多了那个连不上的MON报错输出。

ceph -s 卡住有一种可能是:对于有三个MON的集群,挂掉了两个MON之后 ,手动去 /etc/ceph/ceph.conf 里面把挂掉的MON的IP给删除了, 只留下一个,这时候 ceph -s 的指令就会一直卡在那里,查看MON的log可以发现,那个活着的MON一直处于 probing 状态,这样的MON是不会给客户端返回信息的,所以会卡在那里。有一点需要知道的是,MON的删除比较复杂,不能仅仅通过修改配置文件里面的IP值修改MON,所以,这里正确的做法就是,将删除的IP加回去,然后 ceph -s 就会报出6789之类的错误,然后再去对应的IP的MON去启动MON服务。

那么一个集群能坏多少MON呢 ,简单的计算法法就是:

(mon个数 -1 )/ 2 取整数位

也就是说三个能坏一个,两个和一个不能坏,四个坏一个,五个坏两个等等等。当你坏的MON个数大于可以坏的个数,那么所有的指令是不能返回的。

Q15. Monitor clock skew detected

如果你部署了多个monitor,比如三个MON,而这三个MON的时间不是严格相同的,那么就会报这个错,而Ceph需要MON节点之间的时间差在0.05秒之内,所以一般会选择配置一个内部的NTP server。剩余节点指向该Server节点。

千万一定不要小看了时间对其这个问题,如果各个节点时间不对其的话,有可能会导致某些OSD无法启动,而校准后,OSD立马就启动成功了,亦或导致OSD异常挂掉等等一系列的奇怪现象,十分不利于故障排查。

然而,简单的增加 mon_clock_drift_allowed 的时间偏移大小,是治标不治本的方法,并且OSD节点的时间偏移并不会报告在 ceph -s 里面,所以根本的节点方法还是配置NTP,具体方法请参考我之前写的配置NTP一段,这里就不重复了。

Q16. CephX是什么,以及CephX的开启与关闭

在默认生成的 ceph.conf 里面有三行包含CephX的配置:

auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx

Ceph提供认证功能,想要连接集群,是需要提供用户名和密码的,这三个配置的值只有两种:

cephx
none

注意:如果关闭了CephX,那么任何一个客户端只要拥有了MON的IP和集群的fsid,就可以连接到集群中,然后执行所有的Ceph的指令,这是相当危险的,所以对于一个非局域网的集群,是需要开启的。

之所以写这一节,是因为见过好几个在部署集群时就关闭了CephX而遇到了奇怪的现象的情形,他们一般的操作步骤是:

  1. ceph-deploy new node1 node2 node3
  2. 将生成的 ceph.conf 中的三个 cephx 改成了 none
  3. ceph-deploy mon create-initial  这一步报错如下:
[ceph_deploy.mon][INFO  ] mon.blog monitor has reached quorum!
[ceph_deploy.mon][INFO  ] all initial monitors are running and have formed quorum
[ceph_deploy.mon][INFO  ] Running gatherkeys...
.......
[blog][DEBUG ] fetch remote file
[ceph_deploy.gatherkeys][WARNIN] No mon key found in host: blog
[ceph_deploy.gatherkeys][ERROR ] Failed to connect to host:blog
[ceph_deploy.gatherkeys][INFO  ] Destroy temp directory /tmp/tmpyGDe4r
[ceph_deploy][ERROR ] RuntimeError: Failed to connect any mon

先介绍下这里报错的原因,在Ceph中,除了需要使用Ceph的普通用户之外,Ceph的基本组件:MON,OSD,MDS再到RGW等都可以看做一个用户,而在使用 ceph-deploy 部署的时候,会默认为这些用户生成秘钥文件,在 ceph-deploy new 的时候,除了生成了 ceph.conf ,还生成了 ceph.mon.keyring ,顾名思义这个就是为MON用户生成的秘钥文件。查看该文件的内容可以看到如下内容:

[mon.]
key = AQCUXIRYAAAAABAAOi6Cxnvm+zFzd5gi+hrt+A==
caps mon = allow *

一个秘钥文件一般由三部分组成:

  • [mon.]  : 也就是用户名,在方括号里面的就是用户名,这里为 mon. ,注意是有个**点号**的。
  • key = AQCUXIRYAAAAABAAOi6Cxnvm+zFzd5gi+hrt+A==  : 顾名思义,这就是 mon. 用户的密码。
  • caps  : 后面的就是权限,这里可以简单理解成,该用户可以对所有的MON进行所有操作。

也就是说,Ceph中的Monitor也会像一个用户一样,拥有自己的用户名和秘钥以及操作MON的权限。简单理解了CephX之后,我们再来看上面修改了 none 之后报的错。

ceph-deploy mon create-initial 执行的时候,它会去读取 ceph.conf 里面的 auth_cluster_required 配置,当被修改为 none 之后, 就不会在创建MON的时候,为其生成对应的 keyring ,但是有一点要注意的是,尽管没有为MON生成秘钥文件,但是,MON是正确生成的,这时候执行 ceph -s 是可以得到集群状态的,说明MON已经正确建立。但是在所有的MON建立成功之后, mon create-initial 指令内部会执行 gatherkeys 指令,这个指令会首先去MON的目录下面查找 /var/lib/ceph/mon/ceph-$HOSTNAME/keyring 文件,由于关闭了CephX,在创建MON的时候不会为其生成该文件,所以 gatherkeys 指令报错: No mon key found in host: blog 。这里只要清理下MON环境然后开启CephX重新部署MON就可以通过了。所以在我们 部署集群 的时候, 强烈建议开启CephX ,这样除了可以正确通过 mon create-initial ,还可以在后续的添加OSD时,为每个OSD生成对应的秘钥。在 集群部署完毕后 ,可以关闭CephX认证,具体方法如下:

  • 修改部署目录内 ceph.confcephx->none ,将配置推送到所有节点。
  • 重启所有的MON和OSD。如果只重启MON,过一段时间(几个小时),所有的OSD就会挂掉。。。

ceph-deploy mon create-initial 正确通过之后,我们可以在部署目录下面看到多出了几个文件,都是以 keyring 结尾:

  • ceph.client.admin.keyring : 这个是超级用户 client.admin 的秘钥文件,查看其对应的权限,可以发现全部都是 allow * ,所以有了这个秘钥之后,相当于有了 Linux 系统的 root 用户,可以为所欲为了。
  • ceph.bootstrap-osd.keyring : 类似的还有两个 mdsrgwbootstrap 的意思是引导,查看其权限 mon = "allow profile bootstrap-osd" ,简单解释就是,这个用户可以用于创建OSD(or MDS or RGW)用户。也就是说,后续的OSD的用户的生成是由该用户引导生成的。

最后再说一点,对于秘钥文件,其实我们只需要提供 key= xxxxxxxx 和用户名 [xxx] 就好了,不需要提供权限部分,因为权限已经在Ceph集群中保存了,秘钥文件说了不算的。具体权限可以通过 ceph auth list 来查看。

Q17. --overwrite-conf参数

这是个经常会遇到的问题,修改配置文件内的某些参数后,再执行 ceph-deploy 指令,会报如下的错误:

[blog][DEBUG ] write cluster configuration to /etc/ceph/{cluster}.conf
[ceph_deploy.mon][ERROR ] RuntimeError: config file /etc/ceph/ceph.conf exists with different content; use --overwrite-conf to overwrite
[ceph_deploy][ERROR ] GenericError: Failed to create 1 monitors

报错信息提示得很明确,部署目录内的 ceph.conf 和集群的配置文件 /etc/ceph/ceph.conf 内容不一致,使用 --overwrite-conf 参数来覆盖集群的配置文件,也就是用部署目录的 ceph.conf 覆盖之。使用 ceph-deploy --overwrite-conf xxxCMD 来达到这一效果,当然,你也可以直接 cp 覆盖之。但是这不是一个好习惯。

正确的修改集群配置文件的姿势应该是:

  • 修改**部署目录下的 ceph.conf **。
  • ceph-deploy --overwrite-conf config push NodeA NodeB ... NodeZ 将部署目录下的配置文件推送到各个节点。
  • 强烈建议使用上面的方法

有的朋友可能喜欢直接去某个节点下的 /etc/ceph/ceph.conf 去改配置文件,这样有很多坏处:

  • 过了一周你可能忘了你改过这个节点的配置文件。
  • 这个节点的配置和集群其他节点的配置不一样,会带来一些安全隐患。
  • 如果再来一个不知情的同事,他使用了正确的姿势推送配置文件,你改过的参数很容易被覆盖掉。

所以,从一开始,大家都使用同样的方式去修改集群的配置,是一个很好的习惯,对集群对同事有利无害。

如果你觉得可以接受这种推送配置的方式,但是又不喜欢每次都敲 --overwrite-conf 这么长的参数,你可以修改 ~/.cephdeploy.conf 这个文件,增加一行 overwrite_conf = true

# ceph-deploy configuration file
[ceph-deploy-global]
# Overrides for some of ceph-deploy's global flags, like verbosity or cluster
# name
overwrite_conf = true

打开文件你就会发现,这个是 ceph-deploy 的配置文件,里面的配置项是对 ceph-deploy 生效的,在加了那一行之后,我们再去执行 ceph-deploy 的任何指令,都会默认带上了 --overwrite-conf 参数,这样就可以不打这个参数还能覆盖节点的配置文件。好处是少打了一些参数,坏处是你可能会不知不觉就覆盖了配置文件,各中利弊自行取舍。

~/.cephdeploy.conf 这个文件的用处是很大的,可以为不同的 ceph-deploy xxxCMD 添加参数,刚刚添加在 [ceph-deploy-global] 下的参数对全局都会生效,如果你希望只对 xxxCMD 比如 newosdmon 指定对应的参数,可以添加 [ceph-deploy-xxxCMD] 域,同时在对应的域下添加对应的参数。

比如给 ceph-deploy osd 添加参数--zap-disk ,可以在 ~/.cephdeploy.conf 中添加:

[ceph-deploy-osd]
zap_disk = true

Q18. PG卡在creating状态

这时候,Monitor已经建好了,可以执行 ceph -s 的指令了,然而我们看到集群的健康状态却是: health HEALTH_ERR 。之所以是ERROR状态,是因为目前还没有建立OSD,PG处于creating状态,在建好了OSD之后,自然会解决这一问题。然而我要说的重点是 creating 这个状态的几个产生原因。

creating 字面意思很好理解,正在创建,那么怎么理解PG正在创建呢? 用最简单的方式解释PG就是: PG等于目录 。如果我们使用磁盘做OSD的话,那么这个OSD上的PG就相当于,在这个磁盘上建立的目录。那么现在的问题就可以简化成,我们尚未添加任何磁盘,那么需要落盘的目录无处可建,所以就会长时间处于 creating 状态。在添加了一些OSD后,PG就可以建立了。

还有一种可能的原因是,刚入门的同学在配置文件中加了 osd_crush_update_on_start = false 参数,这个参数的具体意义会有专门的小节介绍,这个参数的默认值是 true ,在使用这个参数后不论创建多少OSD,PG都依旧卡在 creating 状态。原因是所添加的OSD均不在默认的 root=default 根节点下。CRUSH在 default 下无法找到OSD,所以效果就和没有创建OSD一样,再解释就过于深入了,这里只简单介绍下解决方法:

  • 将部署目录里的 ceph.confosd_crush_update_on_start = false 去掉,或者将false改为true。
  • 将配置文件推送到各个节点。
  • 重启所有的OSD。

这样OSD在启动时,就会自动加到对应的主机名下的host下方,并将主机名加到 default 下方。这样CRUSH就可以找到OSD了。当然,对于新入门的同学,一点建议就是,不知道意义的参数都不用加上,Ceph有自己一套默认参数,而这些参数不用修改就可以正常运行集群。如果添加了某些参数,最好知道其作用再使用。

Q19. osd_crush_update_on_start 参数的使用和注意点

这是一个很有趣的参数,使用得当会省去很多事情,使用不当可能会造成灾难(亲身体验)。这个参数在 ceph --show-config 中并不能查询到,所以这并不是Ceph进程的一个配置项。实际上,这个配置相当于一个启动配置项。也就是说在OSD启动的时候会加载这个参数。由于Jewel将OSD的启动方式做了修改,所以针对Hammer及其之前和Jewel两种启动方式,分别在下面的两个文件使用到了这个参数,实际上,加载的方式还是一样的,只是启动文件有所变化:

0.94.9 -> /etc/init.d/ceph -> line 370 -> get_conf update_crush "" "osd crush update on start"
10.2.3 ->/usr/lib/ceph/ceph-osd-prestart.sh -> line 23 -> update="$(ceph-conf --cluster=${cluster:-ceph} --name=osd.$id --lookup osd_crush_update_on_start || :)"

在OSD启动的时候,都会去配置文件中读取 osd_crush_update_on_start 。然后启动脚本根据是否存在以及配置值来决定是否将该OSD按照一定的方式(CRUSH位置,OSD的ID,OSD的weight)将这个OSD添加到CRUSH中。

简单点说,如果这个值为false,那么OSD在启动的时候不会去修改你的CRUSH树,也就是说OSD不会自动填加到对应的主机名下再自己添加到 root=default 下。

如果这个值为true,或者不添加该配置项(也就是说,默认为true),OSD在启动时(任何一次启动)都会将自己添加到CRUSH树下。默认的位置为: /usr/bin/ceph-crush-location -> line 86 -> host=$(hostname -s) root=default


以上所述就是小编给大家介绍的《“网红架构师”解决你的Ceph 运维难题-Part2》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro JavaScript Design Patterns

Pro JavaScript Design Patterns

Dustin Diaz、Ross Harmes / Apress / 2007-12-16 / USD 44.99

As a web developer, you’ll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power......一起来看看 《Pro JavaScript Design Patterns》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码