内容简介:作者介绍哈喽大家好,“网红架构师”又来给大家分享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.keyring
和 ceph.conf
拷贝到xxNode的 /etc/ceph
目录下,并覆盖掉原先的秘钥文件,虽然实际上也就是scp了这两个文件,但是管理Ceph遵循一定的规则是一个很好的习惯。所以,想要得到 ceph -s
的正确输出,你需要确认在 /etc/ceph
目录下有 ceph.conf
和 ceph.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而遇到了奇怪的现象的情形,他们一般的操作步骤是:
-
ceph-deploy new node1 node2 node3
-
将生成的
ceph.conf
中的三个cephx
改成了none
-
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.conf
的cephx->none
,将配置推送到所有节点。 - 重启所有的MON和OSD。如果只重启MON,过一段时间(几个小时),所有的OSD就会挂掉。。。
在 ceph-deploy mon create-initial
正确通过之后,我们可以在部署目录下面看到多出了几个文件,都是以 keyring
结尾:
-
ceph.client.admin.keyring
: 这个是超级用户client.admin
的秘钥文件,查看其对应的权限,可以发现全部都是allow *
,所以有了这个秘钥之后,相当于有了 Linux 系统的root
用户,可以为所欲为了。 -
ceph.bootstrap-osd.keyring
: 类似的还有两个mds
和rgw
,bootstrap
的意思是引导,查看其权限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
比如 new
, osd
, mon
指定对应的参数,可以添加 [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.conf
的osd_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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 消息架构的设计难题以及应对之道
- “网红架构师”解决你的Ceph 运维难题
- “网红架构师”解决你的Ceph 运维难题-Part1
- 自动驾驶如何解决道路安全难题?
- mysql同步延迟,世界级难题
- 虚拟电厂:解决能源转型的实际难题
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数据结构 Python语言描述
[美] Kenneth A. Lambert 兰伯特 / 李军 / 人民邮电出版社 / 2017-12-1 / CNY 69.00
在计算机科学中,数据结构是一门进阶性课程,概念抽象,难度较大。Python语言的语法简单,交互性强。用Python来讲解数据结构等主题,比C语言等实现起来更为容易,更为清晰。 《数据结构 Python语言描述》第1章简单介绍了Python语言的基础知识和特性。第2章到第4章对抽象数据类型、数据结构、复杂度分析、数组和线性链表结构进行了详细介绍,第5章和第6章重点介绍了面向对象设计的相关知识、......一起来看看 《数据结构 Python语言描述》 这本书的介绍吧!