下载源代码,手动编译ceph
写在前面
松鼠哥的ceph专业课程上线啦!
面向新手同学,从0实战,全面入门ceph安装部署与运维,有需要的同学赶紧扫码订购吧:
亲手编译一个开源项目实际上不会太难,对理解项目的知识会很有好处,借此机会把ceph的源代码基础知识学习一下,为后续剖析整个代码、修改代码做优化铺一下路
开始
下载代码
使用git下载指定版本的ceph代码
1 | [tanweijie@cs-2-41 ~]$ git clone --branch v12.2.8 https://github.com/ceph/ceph.git |
解决依赖
ceph这种大项目非常的规范,自带傻瓜式依赖解决脚本
1 | [tanweijie@cs-2-41 ceph]$ ./install-deps.sh |
这样就搞定了
开始编译
官方建议是,直接编译安装适用于开发和测试目的,出于生产使用目的的推荐将ceph编译成rpm包的方式,这种编译成rpm包的方式最大的好处是可以很灵活地决定自己环境中使用的ceph选项,在编译前可以做很多调整,并且编译完成之后可以方便地分发到不同的节点上,保证所有节点安装的包都是一样的
这里先介绍直接编译安装的方式
1 | [tanweijie@cs-2-41 ceph]$ ./do_cmake.sh |
do_cmake首先创建并初始化编译前的环境,创建编译所需的条件,这个过程比较长,官方也说默认情况下会创建一个debug环境,导致这个时间非常久,想要快点则可以指定参数,不让其创建debug环境
1 | [tanweijie@cs-2-41 ceph]$ ARGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo" ./do_cmake.sh |
实测会快很多,与官方说的5x速度差不多,快了5倍左右
接下来是make,因为我的编译环境是cpu是48 core的,所以编译的时候可以加参数充分发挥cpu的能力
1 | [tanweijie@cs-2-41 ceph]$ cd build/ |
make -j96
一出,所有处理器跑满,j参数表示开启多少个线程进行make,一般取cpu核数的2倍
使用time
命令统计的时间开销为
1 | [tanweijie@cs-2-41 build]$ time make -j96 |
时间还可以,大约11分钟就执行完了
编译打包为rpm
对于编译成rpm包的方式,因为本人也是小白,所以从头开始学习,首先是安装制作rpm包的工具
1 | [tanweijie@cs-2-41 build]$ sudo yum install rpm-build rpmdevtools |
然后使用rpmbuild工具创建编译目录,创建后会看到为编译准备的目录
1 | [tanweijie@cs-2-41 ~]$ rpmdev-setuptree |
接下来,获取到ceph的源代码包,rpmbuild制作rpm包需要tar.gz或者bz2之类的压缩形式的源代码包,也可以将上面git拉下来的代码打包成tar.gz或者z2格式,这里直接将tar.gz包下载下来放在目录的SOURCES子目录下
1 | [tanweijie@cs-2-41 ~]$ wget -P ~/rpmbuild/SOURCES/ https://download.ceph.com/tarballs/ceph-12.2.8.tar.gz |
然后,取出源代码包内的spec文件,这个文件指导rpmbuild进行源代码/文件的编译连接和组装
1 | [tanweijie@cs-2-41 ~]$ tar --strip-components=1 -C ~/rpmbuild/SPECS/ --no-anchored -zxvf ~/rpmbuild/SOURCES/ceph-12.2.8.tar.gz "ceph.spec" |
此时,在/home/tanweijie/rpmbuild/SPECS
下有取出来的ceph.spec
文件,可以进行编译了
1 | [tanweijie@cs-2-41 ~]$ rpmbuild -ba ~/rpmbuild/SPECS/ceph.spec |
这样就编译完成了,在~/rpmbuild/RPMS/x86_64
下可以看到全部编译得到的包
1 | [tanweijie@cs-2-41 x86_64]$ ll |
学习spec
从上面的编译过程发现,spec文件是打包编译成rpm的核心文件,下面跟着ceph.spec
简单学习这个文件的使用和优化方法,这种spec文件打包很通用,不仅适用于ceph
首先映入眼帘的是下面的内容
1 | %bcond_without ocf |
这些bcond_with
是一些条件依赖,它主要是检查环境的配置,从而可以根据不同的环境配置来选择不同的编译选项,例如selinux,以及一些第三方的包,例如tcmalloc,在检查完这些依赖后,后续会对这部分配置进行进一步的使用,条件依赖有非常多的好处,它可以根据环境设定来调整运行时的配置,避免硬编码带来的不便,这里不做深究,openSUSE:RPM conditional builds这篇文章说得特别好
接下来是main package definition部分
1 | Name: ceph |
这部分主要是一些信息的定义,版本号啊许可啊,这些信息就是我们使用rpm -qpi xxx.rpm
查询到的信息
接下来是dependencies that apply across all distro families部分
1 | Requires: ceph-osd = %{_epoch_prefix}%{version}-%{release} |
这部分主要是一些编译环境的依赖,指出了制作过程中用到的软件包,其中对应最开头的条件依赖,可以发现对这些依赖都会做特殊判断处理,例如selinux,另外,编译时对其他的第三方依赖,有特殊情况的则会提出版本要求等,这里编译所需要的包都在install-deps.sh
中进行了指定安装,只要运行了那个脚本,这些包自动会满足,继续往下看
1 | %description |
描述信息,想改可以改
接下来是subpackages部分
1 | %package base |
这部分开始描述一部分附属依赖包及其描述信息,这些包为主包提供依赖,最开始的几个Requires表示要打出来的包,后面的则表示安装时所需要的包
对于ceph编译打包,我们可以修改或者优化的地方还是比较少的,ceph源代码中用到的第三方包和依赖我们没有太多手段进行更改
接下来是common部分
1 | %prep |
这部分进入准备阶段,设定基本信息,导入环境变量,关于lowmem_builder,从名字上看就知道表示编译机器是否为低内存设备,如果是,则会降低编译的内存使用和并行任务数,在众多的资料中,也只发现有这样的解释:limit _smp_mflags when lowmem_builder is set in SUSE’s OBS
,看起来大概率跟SUSE有关
另外还有一个参数,_smp_mflags,这里定义了一个变量,在lowmem_builder且任务数大于8的情况下,使用j为8,这里的-j8
就是make命令的j参数,它对编译速度影响非常大,事实上在~/.rpmmacros
文件中也有关于_smp_mflags参数的检测,从实际编译效果来看,此文件的配置优先级比较低,即如果满足上面两个if条件,就会降低编译速度
这里可以直接优化,在设备条件允许的情况下,将上述两个if注释掉,直接修改定义为%define _smp_mflags -j96
,则可以极大加快编译速度(此环境中cpu有48个核),可以直接跑满所有处理器
往下,继续看看
1 | mkdir build |
创建了build目录并进入操作,执行了带很多参数的cmake,并根据条件依赖开启/关闭对应配置,这里还有make命令的执行,可以看到j参数就是在这里被使用了,继续往下
1 | %install |
这部分关于rpm包安装的配置,这里进行的配置将在安装这个rpm的时候执行,其中buildroot这个字段很重要,它将作为make install时候安装的根路径,它决定了rpm安装时候file的具体位置
下面是files and systemd scriptlets部分
1 | %files |
这个部分的篇幅非常大,此部分列出了需要被打包的文件和目录,此前所有的文件都被安装到以buildroot为基准的虚拟目录中,这里将从指定的虚拟路径提取所需要的文件进行打包
遇到的问题
python问题导致编译失败
请注意,编译ceph需要python 2.x,如果环境中默认python版本不是此版本的话,会编译失败
打包rpm包失败
将ceph 12.2.8源码打包成rpm的时候发现如下错误:
1 | rpmbuild/SOURCES/ceph-12.2.8.tar.bz2: No such file or directory |
原因是spec文件中写定的压缩包名称为ceph-12.2.8.tar.bz2
,可参见spec第80行Source字段
1 | ... |
而对应站点上,ceph已经不再打包成bz2格式了,下载下来的源代码包文件名称为ceph-12.2.8.tar.gz
,所以修改spec文件中的名称为ceph-12.2.8.tar.gz
即可
参考资料
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2019/01/03/手动编译ceph/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!