使用源码编译docker组件,源码docker组件


一 下载docker开发镜像

  Docker hub提供了一个用于docker组件自动化编译的镜像docker-dev,这个镜像自带了docker源码和docker源码编译所依赖的各种环境资源。但是这个镜像目前不再随着docker源码更新,这个镜像自带docker最新的版本为1.9.1,如果需要编译更新的docker源码,需要进行一定的适配。

   镜像的pull命令:

docker pull docker-dev:tag
  这里以docker-1.8.2对应镜像为例: docker pull docker-dev:1.8.2。这个docker-dev镜像较大,从docker-hub pull时需要等待一段时间。

二 获取docker源码

  目前的Docker由多个组件组成,包括docker, containerd,runc。这些组件在github上都是独立的项目。可以从github上获取到这些组件源码,并在docker-dev镜像中进行编译。下面是几个组件的github地址。

  1 docker

    https://github.com/moby/moby/tags

  2 containerd

    https://github.com/containerd/containerd/tags

 3 runc

    https://github.com/opencontainers/runc/releases

三 搭建编译环境

  从docker hub(或者国内的加速器)下载了镜像docker-dev后,可以通过docker images命令查看到这个镜像。

warmbobo@tdd:~$ sudo docker images
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
docker-dev                              1.8.2               d1d2969c55fe        2 years ago         1.65GB
  由于docker-dev中自带的docker源码版本比较旧,而且镜像中集成的golang也不够新; 同时,镜像中集成docker源码的方式不够灵活,因而我们需要对其进行改造。

3.1 创建初始容器

  通过docker run命令在docker-dev镜像上创建并进入一个容器:

warmbobo@tdd:~$ sudo docker run --name autobuild --privileged -it docker-dev:1.8.2 /bin/bash
root@e654b914ba37:/go/src/github.com/docker/docker# pwd
/go/src/github.com/docker/docker
root@e654b914ba37:/go/src/github.com/docker/docker# ls
AUTHORS		 Dockerfile.simple  NOTICE	api	   contrib     docs	     image	      opts	runconfig  volume
CHANGELOG.md	 LICENSE	    README.md	builder    daemon      experimental  integration-cli  pkg	trust
CONTRIBUTING.md  MAINTAINERS	    ROADMAP.md	cli	   docker      graph	     links	      project	utils
Dockerfile	 Makefile	    VERSION	cliconfig  dockerinit  hack	     man	      registry	vendor
root@e654b914ba37:/go/src/github.com/docker/docker# cat VERSION 
1.8.2
  我们从docker-dev镜像创建了一个名为autobuild的容器,可以看到在容器中的/go/src/github.com/docker/docker目录已经集成了docker-1.8.2版本的源码。此时我们已经运行在容器中。

3.2 改造镜像

   为了让这个镜像能够编译各种版本的docker源码,我们可以利用docker volume将host机器上需要编译的docker源码映射到容器的/go/src/github.com/docker/docker目录就实现不同版本的docker源码灵活编译了。

  在上面创建运行着的容器中将docker-1.8.2版本的源码先删掉:

root@e654b914ba37:/go/src/github.com/docker/docker# cd ..
root@e654b914ba37:/go/src/github.com/docker# ls
docker
root@e654b914ba37:/go/src/github.com/docker# rm -rf docker/
  查看我们对docker-dev镜像所做的修改:
warmbobo@tdd:~$ sudo docker diff autobuild
[sudo] password for tdd: 
C /go/src/github.com/docker
D /go/src/github.com/docker/docker
  然后我们在host端提交我们的修改:
warmbobo@tdd:~$ sudo docker commit autobuild docker-dev:autobuild
sha256:e230725088b4558633a628ffb392a74ca7c2b8b37d09dfb5ebb48fbace08611a
warmbobo@tdd:~$ sudo docker images
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
docker-dev                              autobuild           e230725088b4        8 seconds ago       1.65GB
docker-dev                              1.8.2               d1d2969c55fe        2 years ago         1.65GB
  这样我们就有了一个新的镜像docker-dev:autobuild,镜像中没有固定的docker源码。

3.3 创建特定版本的docker编译容器

  假设我们下载了docker-1.12.6源码在/mnt/sda6/docker/moby-1.12.6目录,如下所示:

warmbobo@tdd:/mnt/sda6/docker/moby-1.12.6$ pwd
/mnt/sda6/docker/moby-1.12.6
warmbobo@tdd:/mnt/sda6/docker/moby-1.12.6$ ls
api           cmd              Dockerfile          Dockerfile.simple   hack             MAINTAINERS  opts       reference       vendor
AUTHORS       container        Dockerfile.aarch64  Dockerfile.windows  image            Makefile     pkg        registry        VENDORING.md
builder       contrib          Dockerfile.armhf    dockerversion       integration-cli  man          plugin     restartmanager  VERSION
CHANGELOG.md  CONTRIBUTING.md  Dockerfile.gccgo    docs                layer            migrate      profiles   ROADMAP.md      volume
cli           daemon           Dockerfile.ppc64le  errors              libcontainerd    NOTICE       project    runconfig
cliconfig     distribution     Dockerfile.s390x    experimental        LICENSE          oci          README.md  utils
warmbobo@tdd:/mnt/sda6/docker/moby-1.12.6$ cat VERSION 
1.12.6
  另外,docker-dev中的golang版本也比较低,在编译较高版本的docker组件时很可能会失败,因而还需要将编译容器的golang环境也替换。

  因此,我们通过docker-dev:autobuild创建的一个专门用于编译docker-1.12.6源码的容器需要映射host端的/mnt/sda6/docker/moby-1.12.6和/usr/local/go两个目录,如下所示:

warmbobo@tdd:~$ sudo docker run --name moby-1.12.6 -v /mnt/sda6/docker/moby-1.12.6:/go/src/github.com/docker/docker -v /usr/local/go/:/usr/local/go/ --privileged -it docker-dev:autobuild /bin/bash
root@1fb7707e3b24:/go/src/github.com/docker/docker# go version
go version go1.9.2 linux/amd64
root@1fb7707e3b24:/go/src/github.com/docker/docker#
   这样我们就创建了用于编译host机器上/mnt/sda6/docker/moby-1.12.6处源码的容器moby-1.12.6,而且容器中golang的环境也是host主机上的较高的go1.9.2版本。

3.4 编译docker源码

  按照3.3小节的步骤搭建好docker-1.12.6源码编译环境的容器后,就可以开始进行编译了,有动态和静态编译两种方式,如果编译的容器在本机上运行可以选择动态编译; 否则考虑静态编译(使用静态编译时出现一些warning,不过可暂时忽略)。下面动态编译的详细过程:

root@1fb7707e3b24:/go/src/github.com/docker/docker# hack/make.sh dynbinary


---> Making bundle: dynbinary (in bundles/1.12.6/dynbinary)
Building: bundles/1.12.6/dynbinary-client/docker-1.12.6
Created binary: bundles/1.12.6/dynbinary-client/docker-1.12.6
Building: bundles/1.12.6/dynbinary-daemon/dockerd-1.12.6
Created binary: bundles/1.12.6/dynbinary-daemon/dockerd-1.12.6
Building: bundles/1.12.6/dynbinary-daemon/docker-proxy-1.12.6
Created binary: bundles/1.12.6/dynbinary-daemon/docker-proxy-1.12.6
   编译完成后,会在容器源码目录生成一个bundles目录,docker的组件都在这个目录下生成。
root@1fb7707e3b24:/go/src/github.com/docker/docker# ls -l bundles/1.12.6/dynbinary-client/
total 11530
lrwxrwxrwx 1 root root       34 Jan 21 04:26 docker -> docker-1.12.6
-rwxrwxrwx 1 root root 11801014 Jan 21 04:26 docker-1.12.6
-rwxrwxrwx 1 root root       48 Jan 21 04:26 docker-1.12.6.md5
-rwxrwxrwx 1 root root       80 Jan 21 04:26 docker-1.12.6.sha256
root@1fb7707e3b24:/go/src/github.com/docker/docker# ls -l bundles/1.12.6/dynbinary-daemon/
total 35875
lrwxrwxrwx 1 root root       46 Jan 21 04:29 docker-proxy -> docker-proxy-1.12.6
-rwxrwxrwx 1 root root  2014707 Jan 21 04:29 docker-proxy-1.12.6
-rwxrwxrwx 1 root root       54 Jan 21 04:29 docker-proxy-1.12.6.md5
-rwxrwxrwx 1 root root       86 Jan 21 04:29 docker-proxy-1.12.6.sha256
lrwxrwxrwx 1 root root       36 Jan 21 04:28 dockerd -> dockerd-1.12.6
-rwxrwxrwx 1 root root 34713852 Jan 21 04:28 dockerd-1.12.6
-rwxrwxrwx 1 root root       49 Jan 21 04:28 dockerd-1.12.6.md5
-rwxrwxrwx 1 root root       81 Jan 21 04:28 dockerd-1.12.6.sha256

四 其他组件

  上面演示了docker源码的编译过程,其他相关组件containerd和runc的编译过程很类似,参考摸索即可完成。

查看评论

相关内容

    暂无相关文章