Ceph-Deploy 源码分析部署过程
一. 前言
ceph-deploy 是官方提供的部署集群的工具,在自动化部署过程中灵活性稍微欠缺了些,想重新写一份自动化部署项目,所以阅读了ceph-deploy的源代码,这里做一个记录和分析ceph-deploy部署过程中做了什么操作。
二. ceph-deploy 部署分析
环境:
- centos 7.3
- ceph-deploy 2.0
- ceph luminous 12.2.10
- 测试服务器ip和主机名
主机名 | ip |
---|---|
df-vm-01 | 192.168.106.11⁄24 |
1. ceph 源码整体结构
ceph-deploy 将部署的所有步骤封装成一个个的模块,在使用的时候,通过识别命令去调用不同的模块
通过 setuptools 注册包,setuptools是python的包管理工具,感兴趣的可以自行google用法,源码 ==setup.py==
. . . entry_points={ 'console_scripts': [ 'ceph-deploy = ceph_deploy.cli:main', ], 'ceph_deploy.cli': [ 'new = ceph_deploy.new:make', 'install = ceph_deploy.install:make', 'uninstall = ceph_deploy.install:make_uninstall', 'purge = ceph_deploy.install:make_purge', 'purgedata = ceph_deploy.install:make_purge_data', 'mon = ceph_deploy.mon:make', 'gatherkeys = ceph_deploy.gatherkeys:make', 'osd = ceph_deploy.osd:make', 'disk = ceph_deploy.osd:make_disk', 'mds = ceph_deploy.mds:make', 'mgr = ceph_deploy.mgr:make', 'forgetkeys = ceph_deploy.forgetkeys:make', 'config = ceph_deploy.config:make', 'admin = ceph_deploy.admin:make', 'pkg = ceph_deploy.pkg:make', 'rgw = ceph_deploy.rgw:make', 'repo = ceph_deploy.repo:make', ], }, )
console_scripts 是ceph-deploy命令的总入口,调用的是 ceph_deploy.cli:main
ceph_deploy.cli 是子命令入口
这里就很明了了,每一个子命令都有对应的处理程序入口
代码整体结构简单介绍
ceph_deploy ├── conf ├── host // 不同操作系统下载ceph的源的安装卸载等 ├── lib ├── tests ├── util // 一些辅助操作封装 ├── __init__.py ├── admin.py // 以下就是所有命令对应的处理模块,可以从文件名看出来是什么命令了 ├── cli.py ├── cliutil.py ├── config.py ├── connection.py ├── exc.py ├── forgetkeys.py ├── gatherkeys.py ├── hosts ├── install.py ├── mds.py ├── mgr.py ├── misc.py ├── mon.py ├── new.py ├── osd.py ├── pkg.py ├── repo.py ├── rgw.py └── validate.py
2. 部署过程分析
这里以官网ceph-deploy 部署的过程为步骤,分析过程
1. ceph-deploy new {initial-monitor-node(s)}
2. ceph-deploy install {ceph-node} [...]
3. ceph-deploy mon create-initial
4. ceph-deploy admin {ceph-node(s)}
5. ceph-deploy mgr create node1
6. ceph-deploy osd create {ceph-node}:{device}
1. ceph-deploy new {initial-monitor-node(s)} –public-network xxxxx 阶段
==源码地址 ceph_deploy/new.py== , new 主要做了两件的事情
1.初始化配置文件 ceph.conf , 包括对配置项的检测,主机和子网是否可通,默认cephx是开启的
fsid = 7656185e-b585-4f67-96b3-3e4d855d4286 public_network = 192.168.106.0/24 mon_initial_members = df-vm-01 mon_host = 192.168.106.11 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx
2.生成 ceph.mon.keyring
[mon.] key = AQATseJbAAAAABAAT7Bw/8ijA1aIs8LKS+677w== caps mon = allow *
这一阶段只是做了初始化的配置文件的一些操作,完全可以使用ansible 模板做为替代。
生成mon key 使用的函数是
def generate_auth_key(): key = os.urandom(16) header = struct.pack( '<hiih', 1, # le16 type: CEPH_CRYPTO_AES int(time.time()), # le32 created: seconds 0, # le32 created: nanoseconds, len(key), # le16: len(key) ) return base64.b64encode(header + key).decode('utf-8')
2.ceph-deploy install {ceph-node} […] 阶段
这一阶段主要做的事情是判断目标服务器的操作系统,并将对应的源发到服务器,然后下载ceph 相关的安装包, 这里并不建议使用ceph-deploy去安装ceph的相关软件,因为官方的yum源是国外的,下载速度慢,不一定能下载成功,建议自己下载国内的yum源,并在每台集群服务器上执行安装ceph的操作
# yum install ceph ceph-radowgw -y
这一步就可以跳过了,因为做的事情也很简单
3. ceph-deploy mon create-initial 阶段
1.拷贝ceph.conf 到目标服务器,根据目标服务hostname 创建文件夹 /var/lib/ceph/mon/{hostname}} ,将第一阶段生成的mon.key 拷贝到 /var/lib/ceph/tmp/{hostname}}.mon.keyring 文件, 并将相关目录文件设置的用户和组 设置为 ceph
2.在mon服务器执行初始化mon 的命令,命令如下
# ceph-mon --cluster ceph --mkfs -i {hostname} --keyring /var/lib/ceph/tmp/ceph-df-vm-01.mon.keyring --setuser 167 --setgroup 167
在mon工作目录生成如下文件,就是初始化rocksdb
[root@df-vm-01 ceph-df-vm-01]# ls keyring kv_backend store.db [root@df-vm-01 ceph-df-vm-01]# cat keyring [mon.] key = AQArnpBcAAAAABAAdxvumtv+SYhJXZL9TtAD9Q== caps mon = "allow *"
3.生成标志已经初始化完成的文件, 这个 systemd 是有作用的,表示目标服务器用的是 systemd管理服务的
/var/lib/ceph/mon/ceph-df-vm-01/systemd /var/lib/ceph/mon/ceph-df-vm-01/done
现在工作目录下的文件是这样的
[root@df-vm-01 ceph-df-vm-01]# ls keyring kv_backend store.db systemd done
4.启动mon 服务
# systemctl enable ceph.target # systemctl enable ceph-mon@ceph-df-vm-01 # systemctl start ceph-mon@ceph-df-vm-01
5.检查mon的状态
# ceph --cluster=ceph --admin-daemon /var/run/ceph/ceph-mon.df-vm-01.asok mon_status
当所有的mon都创建完成之后,会检查所有的mon的状态 是否为 peon 或者 leader,如果所有的mon都已经是就绪状态了,那就开始生成各种用户秘钥
if mon_in_quorum == mon_members: LOG.info('all initial monitors are running and have formed quorum') LOG.info('Running gatherkeys...') gatherkeys.gatherkeys(args) # 如果所有的mon都达到了仲裁状态,那就开始生成秘钥
在这里先介绍下ceph 中各用户的作用
# 第一级分类: 管理用户 admin # 管理整个集群的用户,权限最大 mon # mon 自身的key # 第二级分类: 创建mgr osd rgw等的管理用户 client.bootstrap-* # 这一类用户是专门用来创建对应的角色使用的 # 第三级分类: osd mgr 本身 osd.* : 这个是osd本身跟mon或者其他osd 通讯的用户 mgr.*
6.通过获取目标mon上的keyring到临时文件 ceph.mon.keyring
[root@df-vm-01 ceph-deploy]# ls /tmp/tmp4kuuMn/ ceph.mon.keyring
当确认mon没有问题,并且ceph.mon.keyring 都存在的时候那就开始生成各种keyring
for keytype in ["admin", "mds", "mgr", "osd", "rgw"]: # 当确认ceph.mon.keyring 存在并且mon健康的时候,那就开始用mon的key去连接mon然后生成各种权限的keyring if not gatherkeys_missing(args, distro, rlogger, path_keytype_mon, keytype, dest_dir): # We will return failure if we fail to gather any key rlogger.error("Failed to return '%s' key from host %s", keytype, host) return False
- path_keytype_mon: mon key的路径
7.ceph.client.admin.keyring 等秘钥的创建过程
首先会在mon总检查检查一下 client.admin 用户存不存在
/usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get client.admin
如果不存在,那就重新创建
/usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get-or-create client.admin osd allow * mds allow * mon allow * mgr allow *
client.* 相关用户的用户名字和对应的权限如下:
cap_dict = { 'admin' : [ 'osd', 'allow *', 'mds', 'allow *', 'mon', 'allow *', 'mgr', 'allow *' ], 'mds' : [ 'mon', 'allow profile bootstrap-mds' ], 'mgr' : [ 'mon', 'allow profile bootstrap-mgr' ], 'osd' : [ 'mon', 'allow profile bootstrap-osd' ], 'rgw': [ 'mon', 'allow profile bootstrap-rgw' ] } ident_dict = { 'admin' : 'client.admin', 'mds' : 'client.bootstrap-mds', 'mgr' : 'client.bootstrap-mgr', 'osd' : 'client.bootstrap-osd', 'rgw' : 'client.bootstrap-rgw', 'mon' : 'mon.' }
下面列出创建client.* 用户的的命令
mgr
# /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get-or-create client.bootstrap-mgr mon allow profile bootstrap-mgr
mds
# /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get-or-create client.bootstrap-mds mon allow profile bootstrap-mds
osd
# /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get-or-create client.bootstrap-osd mon allow profile bootstrap-osd
rgw
# /usr/bin/ceph --connect-timeout=25 --cluster=ceph --name mon. --keyring=/var/lib/ceph/mon/ceph-df-vm-01/keyring auth get-or-create client.bootstrap-rgw mon allow profile bootstrap-rgw
创建完就将临时文件的这些key移动到当前工作目录 结果如下
# ls ceph.bootstrap-mds.keyring ceph.bootstrap-mgr.keyring ceph.bootstrap-osd.keyring ceph.bootstrap-rgw.keyring ceph.client.admin.keyring ceph.conf ceph-deploy-ceph.log ceph.mon.keyring
到此 mon的创建和各个角色的key的创建就完成了
4. ceph-deploy admin {ceph-node(s)} 阶段
这一阶段的工作很简单就是将ceph-deploy工作目录下的 ceph.client.admin.keyring 分发到对应的管理节点服务器上。
注意这里不会吧 client.bootstrap-* 的key分发出去,所以在部署的时候可能会出现 bootstrap 找不到的情况,使用 ceph-deploy push 就可以了
5. ceph-deploy mgr create阶段
1.将ceph-deploy 工作目录的 bootstrap-mgr keyring 分发到ngr服务器: /var/lib/ceph/bootstrap-mgr/{cluster}.keyring
2.创建mgr 工作目录 /var/lib/ceph/mgr/{cluster}-{name}
- cluster: 集群名字
- name: 主机名字
3.使用 client.bootstrap-mgr 这个用户的keyring 去创建 mgr 用户, 并将keyring信息保存在 /var/lib/ceph/mgr/{cluster}-{name}/keyring
ceph --cluster ceph --name client.bootstrap-mgr --keyring /var/lib/ceph/bootstrap-mgr/ceph.keyring auth get-or-create mgr.{hostname} mon allow profile mgr osd allow * mds allow * -o /var/lib/ceph/mgr/ceph-{hostname}/keyring
4.生成标志创建完成和系统服务管理的文件
/var/lib/ceph/mgr/ceph-df-vm-01/done /var/lib/ceph/mgr/ceph-df-vm-01/systemd
5.然后启动mgr
systemctl enable ceph-mgr@df-vm-01 systemctl start ceph-mgr@df-vm-01 systemctl enable ceph.target
6.最后查看下看集群的状态
[root@df-vm-01 test]# ceph -s cluster: id: ee0eae0b-b1b2-4041-8587-b461b905e469 health: HEALTH_OK services: mon: 1 daemons, quorum df-vm-01 mgr: df-vm-01(active) osd: 0 osds: 0 up, 0 in data: pools: 0 pools, 0 pgs objects: 0 objects, 0B usage: 0B used, 0B / 0B avail pgs:
6. ceph-deploy osd create {ceph-node}:{device} 阶段
这里只针对bluestore的存储引擎下的osd创建过程
1.首先copy ceph.conf 配置文件到osd服务器
2.将 ceph.bootstrap-osd.keyring 拷贝到目标服务器的 /var/lib/ceph/bootstrap-osd/{cluster}.keyring
3.然后通过输入的各种参数通过ceph-volume 去创建osd
/usr/sbin/ceph-volume --cluster ceph lvm create --bluestore --data /dev/vdc
如果有指定wal 和db就是下面这样
/usr/sbin/ceph-volume --cluster ceph lvm create --bluestore --data /dev/vdc ----block.wal /dev/xxxx --block.db /dev/xxxx
默认情况下是osd的创建是使用 ceph-volume 去创建osd,在创建的时候会基于lvm,L版早期的小版本使用的是 ceph-disk 来创建osd,这个工具官方已经废弃了,基于lvm的创建有很多好处,比如不用担心重启盘符飘逸的问题,这里先不展开讲解,对于osd的创建有很多的细节问题,后面会专门一篇分析ceph-volume 创建osd的过程到底做了什么
三.总结
掌握 ceph-deploy 的创建集群的过程,对了解集群有很大的帮助,特别是日常中将ceph-deploy作为部署工具的,阅读ceph-deploy 的源码和掌握整个流程就显得很关键,同时用ansible 做自动化部署也是必须要了解这个过程的。