centos7下docker1.10.3 rpm 源码编译小记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/redenval/article/details/83180646

下载rpm源码包

比如从https://cbs.centos.org/koji/buildinfo?buildID=16801上下载源码发布包:docker-1.10.3-59.el7.centos.src.rpm

提取源码

通过如下命令将打了所有的patch后的源码输出到/root/rpmbuild目录下

rpm -ivh docker-1.10.3-59.el7.centos.src.rpm

执行以上命令后rpmbuild文件夹下产生的目录结构如下:

[root@arch-docker-host2 rpmbuild]# tree
.
├── SOURCES
│   ├── 30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d.tar.gz
│   ├── docker-cleanup.sh
│   ├── docker-common.sh
│   ├── docker-logrotate.sh
│   ├── docker-lvm-plugin-bc03b53.tar.gz
│   ├── docker-network.sysconfig
│   ├── docker-novolume-plugin-c521254.tar.gz
│   ├── docker-selinux-98617f3.tar.gz
│   ├── docker.service
│   ├── docker-storage-setup-0d53efa.tar.gz
│   ├── docker-storage.sysconfig
│   ├── docker.sysconfig
│   ├── README-docker-common
│   ├── README.docker-logrotate
│   ├── v1.10-migrator-c417a6a.tar.gz
│   └── v1.10-migrator-helper
└── SPECS
    └── docker.spec

2 directories, 17 files

对原工程进行修改

主要是为了更快的编译源码,避免采坑,加快速度。整个编译流程从进入SPECS目录开始,执行如下命令即可

rpmbuild -ba dokcker.spec
  1. 每次编译时候都会去https://github.com/projectatomic/docker.git下载这个docker Git仓库,而国内下载出奇的慢,可以提前下载好(下载的是rhel7-1.10.3分支代码),然后修改SPEC目录下的docker.spec文件,让它每次做copy即可,具体改动如下:

    %check
    [ ! -w /run/%{name}.sock ] || {
     	mkdir test_dir
     	pushd test_dir
    	cp /root/docker.tar.gz ./
    	tar zxvf docker.tar.gz
    	#git clone https://github.com/projectatomic/docker.git -b %{docker_branch}
    	pushd %{name}
     	make test
    	popd
    	popd
    }
    
  2. 编译过程中会创建/root/rpmbuild/BUILD目录,并且解压SOURCES/30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d.tar.gz文件到/root/rpmbuild/BUILD下,产生docker-30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d文件夹。然后根据 docker-30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d文件夹下的DockerFile的配置不断根据centos7作为基础镜像去不断的添加新的层构建新的镜像。整个过程一共有50多步,由于国内防火墙的原因经常容易下载超时,或者下载网址失效导致构建镜像失败。经验之谈是在失败的Step处修改DockerFile,这样每次重新构建时候不会从头开始构建(会using cache),否则又要重头开始漫长的下载。

    2.1 从DockerFile中删除 OSX_SDK MacOSX10.11.sdk步骤,该步骤是跨平台编译Mac OS版本docker,由于 https://s3.dockerproject.org/darwin/网址失效,导致该构建步骤失败

    2.2 在构建过程中会提示pip command not found及jq command not found, 其实DockerFile中一开始就会批量安装很多的依赖包,其中就包含了pip 和 jq,但是还是在后面构建过程中失败,我的解决方式是在失败的step前分别在添加RUN yum install jq -y和RUN yum install python-pi -y

    2.3 整个50多层的镜像构建成功后,生成centos-dev镜像,开始利用该镜像起容器,在容器内部build docker-1.10.3 二进制文件。然后会编译各种平台的docker bin 文件。在编译docker-1.10.3.exe 出错。主要是缺少mingw64-gcc安装包,该安装包是linux跨平台编译Windows程序的编译器,在DockerFile 加入RUN yum install mingw64-gcc -y,重新构建镜像即可。

  3. 构建完镜像,通过镜像起容器,在容器内编译bin文件,容器内的bin文件目录会映射到宿主机/root/rpmbuildbak/BUILD/docker-30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d/bundles下。生成完bin文件后开始单元测试。在进行单元测试时又会出错,最快的办法是跳过出错的单元测试

    3.1 比如在做test-integration-cli 单元测试时候,就会包如下错误:

    ---> Making bundle: .integration-daemon-setup (in bundles/1.10.3/test-integration-cli)
    ---> Making bundle: .detect-daemon-osarch (in bundles/1.10.3/test-integration-cli)
    ---> Making bundle: .ensure-emptyfs (in bundles/1.10.3/test-integration-cli)
    ++++ tar -cC bundles/1.10.3/test-integration-cli/emptyfs .
    ++++ docker load
    ---> Making bundle: .ensure-frozen-images (in bundles/1.10.3/test-integration-cli)
    ++++ tar -cC /docker-frozen-images .
    ++++ docker load
    Error response from daemon: ApplyLayer exit status 1 stdout:  stderr: archive/tar: invalid tar header
    +++ bundle .integration-daemon-stop
    +++ local bundle=.integration-daemon-stop
    

    网上查了半天各种方法尝试了后都不好解决,然后直接进入docker-30bf0b874ebdda9b8d2a7adf36ce1dcbf5a67f1d文件,将所有包含test-integration-cli关键字的spec,MakeFile文件及shell文件找出来,将test-integration-cli删除,这样就会跳过test-integration-cli单元测试。

    3.2 test-docker-py单元测试也会出错,同样也是查找关键字跳过该单元测试。

  4. 通过单元测试后,就会开始打rpm包,打包成功后会在/root/rpmbuild/ 目录下多出一下几个目录,整个文件夹如下:

    BUILD  BUILDROOT  RPMS  SOURCES  SPECS  SRPMS
    

    其中RPMS目录下会生成多个rpm包:

    [root@arch-docker-host2 RPMS]# tree
    .
    └── x86_64
    	├── container-selinux-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-common-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-logrotate-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-lvm-plugin-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-novolume-plugin-1.10.3-59.1.el7.centos.x86_64.rpm
    	├── docker-unit-test-1.10.3-59.1.el7.centos.x86_64.rpm
    	└── docker-v1.10-migrator-1.10.3-59.1.el7.centos.x86_64.rpm
    

    SRPMS目录下会生成当前编译docker的源码包

安装RPM包

线上安装docker rpm包:复制docker-common-1.10.3-59.1.el7.centos.x86_64.rpm及docker-1.10.3-59.1.el7.centos.x86_64.rpm到需要安装的机器上,执行如下命令,待安装成功后重启docker即可

rmp -Uvh *.rpm 

更加快捷的编译方式

无意中将编译机docker daemon给停了后发现docker 编译过程中不再去构建镜像起容器,直接在宿主机上编译,太神奇了,感觉前面倒腾半天,在物理机上很快就编译完成了,没有繁琐的步骤。

高版本go编译的坑

通过这种方式去编译rpm包后,安装到物理机上执行 docker version 就出错。
提示如下:

faild to get docer version: An error occurred trying to connect : Get Http://%2Fvar%2Frun%2Fdocker.sock/version:EOF

网上查询解决方法,都试过了还是不行。然后开始看docker log,log中有一段go panic的堆栈信息,具体是getFdFromWriter方法触发panic,然后在网上搜到该bug是由于go 版本过高触发的panic(docker1.10.3默认采用go1.5.3版本编译,而编译机我安装的是最新版本的go1.11),同时github上对于该bug也有相关提交,具体链接在此将该提交的代码copy到编译机,重新编译,打包 安装,该问题得到修复。
后面编译机go也调整到1.5.3,去掉刚才添加代码也没有出问题。

猜你喜欢

转载自blog.csdn.net/redenval/article/details/83180646