Why
为什么要在windows上跑docker去编译ceph的代码?是松鼠哥吃太饱了吗?当然不是~
在实际生产问题处理中,很多时候会遇到棘手的情况,需要快速修改并编译得到可用的二进制程序,例如上篇中,松鼠哥处理多个osd连续的down时,就需要导出其中的一些pg,但是pg的数据导出会因为其中的一些对象有问题导致后续对象无法导出,这就要对导出的工具
ceph-objectstore-tool
做代码修改并重新编译,我们不应该在需要的时候才去搭建编译环境、修改和编译,提前准备环境就很有必要了。
那为什么不用vm来编译呢?恰好vmware workstation pro还免费了。主要的原因是:
- vm对于windows来说太重了,编译机怎么也要8GiB内存,4个core,为了编一下代码,整个os跑真的太重了。
- 依赖太蛋疼,不能够在一个vm中同时编译12、13、14、15、16等版本的ceph代码,莫非要每个版本一个vm?
而docker则能很好地解决上述问题:
- docker不重,你甚至可以在秒级得到一个可以立刻编译的环境。
- docker可以构筑编译镜像,这就意味着可以每个版本建立自己的镜像,镜像并不是很大。
- 可以导入导出镜像实现迁移和备份,想在哪里编译就在哪里编译。
windows下的docker
em…windows是可以跑docker的,但是对windows系统的小版本有要求,例如松鼠哥一开始用的windows10 1909,安装的时候会提示这个小版本不支持,需要升级才行:
Installation failed:one pre-requisite is not full filled
升级也简单,就是在系统更新那里点一下更新它就自己升级了,时间还挺久,现在松鼠哥的版本是:
C:\Users\twj>ver
Microsoft Windows [版本 10.0.19045.4651]
顺便提一下,现在docker的网站访问不行了,要从docker网站下载windows的安装包会失败,得上科技。
How
首先是下载windows版的docker,在科技的加持下直接去docker官网下载就行,松鼠哥用的
v4.32.0
版本,然后检查系统的小版本是不是符合要求,最简单的做法就是直接安装,看它给不给安装。
安装完成后,开始准备镜像。
首先,ceph12、13、14版本的代码可以在centos7下编译,所以首先要制作centos7的基础镜像,具体就是安装centos7.6.1810的minimal版本,啥包也不要装,就是要个基础系统,然后打包一下:
cd /
tar-cvpf system.tar --directory=/ --exclude=proc --exclude=sys --exclude=dev --exclude=run --exclude=boot .
其实就是除了那几个系统自动生成的目录,其他目录都使用tar打包,打包好之后,弄出来,导入docker中作为基础镜像
dockerimport ./system.tar centos7.6.1810:1.0
为了编译15、16、17等版本的ceph,也要搞一个debian的基础系统,这里推荐使用
debian 10.13.0 netins
,也就是debian的最小安装系统,也叫网络安装镜像,因为我们只需要最小的基础系统,打包也是一样的,就不赘述了。
接下来,使用松鼠哥打包好的包继续制作镜像,这个包是这么制作的:
首先使用git拉取ceph的代码,并下载更新所有子模块,例如16.2.15的代码:
git clone --branch v16.2.15 https://github.com/ceph/ceph.git
cd ceph
git submodule update --init--recursive
接下来在minimal系统中收集这个版本的ceph编译所需要的所有依赖包:
在centos中可以使用yum的--downloadonly选项来下载所使用的rpm包和相关依赖
在debian中可以使用apt的-d参数来下载所指定的deb包和相关依赖
将包下载完整后,最好手动安装一下,然后编一下代码看看能不能编过,确保所有的包都收集齐全
做所有包收集和配置的主要目的是,我们希望能够让项目在完全没有网络的环境中依然能够进行编译。
最后将它们打包在一起
tar-zcvf ceph.16.2.15.all.tar.gz ceph.16.2.15
为了保持docker镜像build的一致性,建议每个打的包保持几乎一致的结构。
接下来就是Dockerfile,这个文件告诉docker如何去构建一个镜像,例如16.2.15编译镜像的构建:
# 使用基础镜像
FROM debian10.13.0:1.0
# 把包拷进来
RUN mkdir /app
COPY ceph.16.2.15.all.tar.gz /app/ceph.16.2.15.all.tar.gz
# 解压
RUN tar-zxvf /app/ceph.16.2.15.all.tar.gz -C /app/
# 安装依赖
RUN aptinstall-y /app/ceph.16.2.15.all/packages/*
RUN pip3 install /app/ceph.16.2.15.all/Cython-0.29.37-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl
# 删除包
RUN rm-rf /app/ceph.16.2.15.all/packages/
RUN rm-rf /app/ceph.16.2.15.all.tar.gz
RUN rm-f /app/ceph.16.2.15.all/Cython-*
# cmake
RUN cd /app/ceph.16.2.15.all/ceph/;./do_cmake.sh -DWITH_MANPAGE=OFF -DWITH_BABELTRACE=OFF -DWITH_MGR_DASHBOARD_FRONTEND=OFF -DCMAKE_BUILD_TYPE=Release -DWITH_CCACHE=OFF -DSPAWN_TEST_ADDRESS_SANITIZER=OFF -DWITH_DMCLOCK_TESTS=OFF -DWITH_GTEST_PARALLEL=OFF -DWITH_SYSTEM_GTEST=OFF -DWITH_TESTS=OFF -Ddmclock_TEST=OFF -DWITH_LTTNG=OFF
RUN mv /app/ceph.16.2.15.all/boost_1_73_0.tar.bz2 /app/ceph.16.2.15.all/ceph/build/boost/src/boost_1_73_0.tar.bz2
RUN cd /app/ceph.16.2.15.all/liburing;git checkout liburing-0.7
RUN mv /app/ceph.16.2.15.all/liburing /app/ceph.16.2.15.all/ceph/build/src/liburing
# 设置工作目录
WORKDIR /app
就是按步骤一步一步来,在os怎么操作怎么编的,在容器就怎么搞,有时候依赖的问题比较难搞,要花点时间。
接下来就是build,在当前目录下,使用docker命令来完成构建,这里松鼠哥已经做好了所以它都是从
CACHE
获取到内容:
D:\code>docker build -t ceph.16.2.15 .[+] Building 0.2s (19/19) FINISHED docker:desktop-linux
=>[internal] load build definition from Dockerfile 0.0s
=>=> transferring dockerfile: 1.33kB 0.0s
=>[internal] load metadata for docker.io/library/debian10.13.0:1.0 0.0s
=>[internal] load .dockerignore 0.0s
=>=> transferring context: 2B 0.0s
=>[1/14] FROM docker.io/library/debian10.13.0:1.0 0.0s
=>[internal] load build context 0.0s
=>=> transferring context: 48B 0.0s
=> CACHED [2/14] RUN mkdir /app 0.0s
......=>=> naming to docker.io/library/ceph.16.2.15 0.0s
View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/zp5bl79pddjpw00obfnbc2jl1
What's next:
View a summary of image vulnerabilities and recommendations → docker scout quickview
遇到一个坑,Dockerfile内如果使用了本地路径的操作,例如上述的Dockerfile中将文件拷进去:
COPY ceph.16.2.15.all.tar.gz /app/ceph.16.2.15.all.tar.gz
这个源路径是本地windows路径,这里没有用绝对路径而是使用了本目录,因为使用绝对路径是有问题的,我们知道,windows的路径与linux的路径最大的区别就是用
\
还是用
/
,经过测试发现,docker并没有处理这个情况,在使用windows的绝对路径时,会直接加上
/
开头,哪怕你用
\\
去转义也不行,这就导致它无法正常读到本地文件,解决办法就是去需要读文件的目录中build,使用不带任何前缀的相对路径方式,Dockerfile在哪个目录,哪个目录就是它的当前路径,或者,到Linux上build,就不存在这个问题,这个小问题困扰了半天,松鼠哥认为这是个bug=.=
最终的效果是这样的,松鼠哥搞定了12、13、14、16版本的编译,其他版本有空再弄:
D:\code>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ceph.16.2.15 latest 5e0c5c05e41f 16 hours ago 6GB
debian10.13.0 1.0 0c505598ca83 18 hours ago 590MB
ceph.13.2.10 latest 6740d88dd244 23 hours ago 6.6GB
ceph.12.2.13 latest cb5d5463376d 24 hours ago 6.31GB
ceph.14.2.22 latest ca913b4da1e5 24 hours ago 7.21GB
centos7.6.1810 1.0 016d1053dc58 24 hours ago 951MB
起一个容器来编译看看:
D:\code>docker ps-a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0163c241f58c ceph.16.2.15 "/bin/bash"16 hours ago Up 5 seconds angry_bell
D:\code>docker exec-it 0163c241f58c /bin/bash
root@0163c241f58c:/app# cd ceph.16.2.15.all/ceph/build/
root@0163c241f58c:/app/ceph.16.2.15.all/ceph/build# make -j4 ceph-objectstore-tool[0%] Built target Boost
[3%] Built target rocksdb_ext
......[93%] Built target os
[100%] Built target osd
[100%] Built target ceph-objectstore-tool
root@0163c241f58c:/app/ceph.16.2.15.all/ceph/build#
No problem~
编过一次之后,后续再编速度就快了。
So
windows上跑容器总体来说比跑vm好很多,管理也方便,资源吃得少,之前只能起一个vm编一个项目,现在可以起3个容器跑,而且镜像做好之后导出还能放别的地方用,实在方便,大家可以尝试用用。
喜欢ceph的话欢迎关注奋斗的cepher微信公众号阅读更多好文!
版权归原作者 奋斗的松鼠 所有, 如有侵权,请联系我们删除。