我的docker随笔12:docker源码编译

526 阅读4分钟

因工作需要从源码编译docker,本文对此进行介绍。

一、环境搭建

docker的编译,需要在宿主机预先安装docker软件。因为编译docker的源码时,会构建一个docker镜像并运行,在这个容器里面进行build操作。由于这个容器已经包含了go语言环境,故宿主机无须额外安装golang。 宿主机系统:ubuntu 16.04 64bit 宿主机docker版本:

docker -v
Docker version 17.10.0-ce, build f4ffd25

二、下载源码

docker的github官方网站为:github.com/docker/dock…。 docker以每月发布一个版本的节奏进行开发。命名规则为:年份-月份-ce,其中ce表示社区版本。截至本文撰写时,最新版本为v17.12.0-ce,但下一版本v18.01.0-ce-dev已经处于开发阶段(带dev表示开发阶段),本文编译得到的版本即为v18.01.0-ce-dev。 发行版本下载地址:github.com/docker/dock…。 本文在/home/latelee/docker/dev目录进行,请根据实际情况修改目录。 下载源码:

git clone https://github.com/docker/docker-ce

进入docker-ce目录:

cd docker-ce

切换到最新的tag:

git checkout -b v18.01.0-ce

三、编译过程

本节工作目录为/home/latelee/docker/dev/docker-ce目录。

修改Dockerfile

执行下面小节编译命令时会发生一个错误,因此需要预先修改Dockerfile文件。 编译时会构建一个docker镜像来编译,实际执行的命令是(来自components/packaging/deb的makefile,并经过解析生成的): docker build -t debbuild-ubuntu-xenial/x86_64 -f /home/latelee/docker/dev/docker-ce/components/packaging/deb/ubuntu-xenial/Dockerfile.x86_64 .。 分析components/packaging/deb/ubuntu-xenial/Dockerfile.x86_64文件,知道其在构建过程会下载golang编译器,因golang.org访问不了,最后会构建失败。因此需要更新下载源。解决方法:找一个国内可下载的网站。如dl.gocn.io/。 修改components/packaging/deb/ubuntu-xenial/Dockerfile.x86_64文件。 将RUN curl -fSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz"; | tar xzC /usr/local修改为:RUN curl -fSL "https://dl.gocn.io/golang/${GO_VERSION}/go${GO_VERSION}.linux-amd64.tar.gz"; | tar xzC /usr/local 最终会构建出镜像:debbuild-ubuntu-xenial/x86_64。 注意,这个镜像在后面的编译中会继续使用,因此不需要删除。

编译

进入目录:

cd components/packaging/deb

deb目录下的Makefile指定了编译得到的是deb包。 执行编译命令:

make  VERSION=18.01.0-ce-dev ENGINE_DIR=/home/latelee/docker/dev/docker-ce/components/engine CLI_DIR=/home/latelee/docker/dev/docker-ce/components/cli ubuntu-xenial

命令解释: 该命令指定了版本号和docker组件的目录(VERSION、ENGINE、CLI分别指版本号、docker引擎、docker命令行),同时指定了要编译的系统版本(ubuntu16.04代号为xenial),这是因为,本文只针对一个系统版本进行编译,而不是编译所有的版本。

生成文件

大约经过半小时,编译成功。最终生成的deb包位于:components\packaging\deb\debbuild\ubuntu-xenial。 deb文件为:docker-ce_18.01.0~ce~dev~git20171228.105814.0.486a48d-0~ubuntu_amd64.deb

安装

将得到的deb包存放到本机或其它ubuntu系统上,执行以下命令进行安装:

# dpkg -i docker-ce_18.01.0~ce~dev~git20171228.105814.0.486a48d-0~ubuntu_amd64.deb

验证其版本号:

# docker -v
Docker version 18.01.0-ce-dev, build 486a48d

到此,docker的编译结束。

四、docker源码目录剖析

docker-ce源码目录如下:

.├── CHANGELOG.md├── components  # 组件目录│   ├── cli│   ├── engine│   └── packaging├── components.conf├── CONTRIBUTING.md├── Makefile # 编译所需├── README.md # 说明文件└── VERSION # 版本文件4 directories, 6 files

其中组件目录包含三个子目录:cli、engine、packaging。前2个为go代码所在目录,packaging是构建最终二进制文件的目录。内容如下:

.├── deb│   ├── build-deb│   ├── common│   ├── debbuild│   ├── debian-buster│   ├── debian-jessie│   ├── debian-stretch│   ├── debian-wheezy│   ├── Makefile│   ├── raspbian-jessie│   ├── raspbian-stretch│   ├── README.md│   ├── systemd│   ├── ubuntu-artful│   ├── ubuntu-trusty│   └── ubuntu-xenial├── Jenkinsfile├── Makefile├── README.md├── rpm│   ├── centos-7│   ├── fedora-26│   ├── fedora-27│   ├── gen-rpm-ver│   ├── Makefile│   ├── README.md│   └── systemd└── static    ├── hash_files    └── Makefile

其中deb目录是编译生成deb文件的,区别不同的系统版本(如ubuntu和debian,而ubuntu又以代号区别不同版本,其中trusty表示14.04,xenial表示16.04,等等)。比如ubuntu-xenial目录包括了基于16.04的不同平台的Dockerfile。build-deb是运行于前面提到的容器的编译脚本。 详细分析将在后续文档给出。

附录

如果下载release版本进行编译,将得到如此错误:

# WARNING! I don't seem to be running in a Docker container.# The result of this command might be an incorrect build, and will not be# officially supported.## Try this instead: make all#error: .git directory missing and DOCKER_GITCOMMIT not specified  Please either build with the .git directory accessible, or specify the  exact (--short) commit hash you are building using DOCKER_GITCOMMIT for  future accountability in diagnosing build issues.  Thanks!make[1]: *** [override_dh_auto_buil

解决方法: 使用git下载代码仓库,然后切换到发布版本分支,再进行编译。

由于docker版本更新非常快,本文所述,仅供参考。