从源码构建docker-ce的过程分析

目录
  • 准备环境
  • 获取源码
  • 编译前的准备工作
    • 添加dockerd的代理
  • 开始编译
  • 使用Delve调试
  • 参考

准备环境

准备一台Linux主机,并在上面安装好docker-ce,安装好make,git就可以开始编译工作了。对,就是如此简单,可能你会对此感到异或为啥要装docker,我不是准备编译这个玩意么,为啥不装go,docker不是用go开发的么? 这些疑问会在后面的步骤中解答。

# docker-ce 安装参考
# FROM: https://developer.aliyun.com/article/110806
# Ubuntu 14.04 16.04 (使用apt-get进行安装)
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

注意:其他注意事项在下面的注释中
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
#   docker-ce | 17.03.1~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
#   docker-ce | 17.03.0~ce-0~ubuntu-xenial | http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2、Step 3中的命令
# 经典网络:
# curl -fsSL http://mirrors.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyuncs.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# VPC网络:
# curl -fsSL http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# sudo add-apt-repository "deb [arch=amd64] http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# CentOS 7 (使用yum进行安装)
# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安装 Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start

注意:其他注意事项在下面的注释中
# 官方软件源默认启用了最新的软件,您可以通过编辑软件源的方式获取各个版本的软件包。例如官方并没有将测试版本的软件源置为可用,你可以通过以下方式开启。同理可以开启各种测试版本等。
# vim /etc/yum.repos.d/docker-ce.repo
#   将 [docker-ce-test] 下方的 enabled=0 修改为 enabled=1
#
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2 : 安装指定版本的Docker-CE: (VERSION 例如上面的 17.03.0.ce.1-1.el7.centos)
# sudo yum -y install docker-ce-[VERSION]
# 注意:在某些版本之后,docker-ce安装出现了其他依赖包,如果安装失败的话请关注错误信息。例如 docker-ce 17.03 之后,需要先安装 docker-ce-selinux。
# yum list docker-ce-selinux- --showduplicates | sort -r
# sudo yum -y install docker-ce-selinux-[VERSION]

# 通过经典网络、VPC网络内网安装时,用以下命令替换Step 2中的命令
# 经典网络:
# sudo yum-config-manager --add-repo http://mirrors.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
# VPC网络:
# sudo yum-config-manager --add-repo http://mirrors.could.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
# 安装其他工具, 以centos7为例子
yum install -y make git

获取源码

git clone https://github.com/moby/moby.git

其实如果你有对docker二次开发的需求了,我这边也不用再多费口舌在moby这个奇怪的项目名称上
其实就个人而言对docker改名这件事也是颇有微词的,docker公司愿意开源docker-ce固然是好事,但是直接换个名称明摆着是想把docker早期创造出来的名声都让公司的付费产品“docker”
上,而不是所谓的moby(docker-ce)。

编译前的准备工作

如果你工作网络环境足够优秀(可以稳定的访问到dockerhub和各种操作系统的源)可以跳过这一小节,肉身在国外的一般没有这种烦恼。而对于大部分国内的开发者则需要通过代理完成这个开发环境的构建,一下的步骤仅供参考。

添加dockerd的代理

docker的镜像拖取工作是由dockerd完成的(而不是你平常使用的docker命令行工具),而dockerd一般挂在systemd的进程下(如果有老哥头铁从命令行运行dockerd那么当我没说,这样也能读到代理的环境变量)。如果要为dockerd添加代理的话可以参考如下操作

# 修改为你自己的http代理地址
cat > /etc/systemd/system/docker.service.d/http-proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://192.168.144.1:10811"
Environment="HTTPS_PROXY=http://192.168.144.1:10811"
EOF
systemctl daemon-realod
systemctl restart docker

到这一步只是为镜像的拖取操作添加了代理,但是在开发环境中资源的拖取问题还是没有办法解决,这点我们稍微修改Makefile可以处理,参考如下操作

1. 在Makefile文件头部增加"include .env"
2. Makefile同目录创建.env文件并写入你的环境变量,参考如下
BUILD_PROXY := --build-arg "http_proxy=http://192.168.144.1:10811" --build-arg "https_proxy=http://192.168.144.1:10811"
3. 追加参数到指定的构建参数变量,修改Makefile, 在BUILD_OPTS := *后面的一行增加
BUILD_OPTS += $(BUILD_PROXY)

开始编译

ntpdate ntp1.aliyun.com # 同步时间,如果时间误差过大会导致部分源依赖获取失效,非必须
make BIND_DIR=. shell

构建过程由于或需要拖取镜像和资源耗时一般比较长(即使在网络条件较好的情况下),一般要10分钟左右。
如果构建成功你回进入如下的一个容器内终端

root@3cede98051a6:/go/src/github.com/docker/docker#

这个便是makefile通过dockerfile为你构建的docker-ce的编译环境,这个环境中你开发和调试的工具应有尽有,如你还有特殊的需求可以通过修改dockerfile重新构建(别担心,由于之前构建的缓存文件,你第二次构建只会构建新增部分,不会花太多的时间),项目的根目录挂载到主机目录,所以你在此路径下构建出的二进制文件也会写入到宿主机。
接下来我们开始编译

hack/make.sh binary

编译完成

root@3cede98051a6:/go/src/github.com/docker/docker# hack/make.sh binary

Removing bundles/

---> Making bundle: binary (in bundles/binary)
Building: bundles/binary-daemon/dockerd
GOOS="" GOARCH="" GOARM=""
Created binary: bundles/binary-daemon/dockerd
Copying nested executables into bundles/binary-daemon
Building: bundles/binary-daemon/docker-proxy
GOOS="" GOARCH="" GOARM=""
Created binary: bundles/binary-daemon/docker-proxy

root@3cede98051a6:/go/src/github.com/docker/docker#

安装测试

# 还是在容器内
make install

启动测试

/usr/local/bin/dockerd -D

你也可以在容器内下载镜像,启动容器

# 在宿主机另开一个终端,并进入容器
[root@localhost moby]# docker ps
CONTAINER ID   IMAGE                      COMMAND            CREATED         STATUS         PORTS                                                                                            NAMES
3cede98051a6   docker-dev                 "hack/dind bash"   8 minutes ago   Up 8 minutes                                                                                                    condescending_swanson
dae301c0f728   yandex/clickhouse-server   "/entrypoint.sh"   33 hours ago    Up 33 hours    0.0.0.0:8123->8123/tcp, :::8123->8123/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 9009/tcp   ch-server
[root@localhost moby]# docker exec -it 3ced /bin/bash
root@3cede98051a6:/go/src/github.com/docker/docker#
# 下载镜像,启动容器
root@3cede98051a6:/go/src/github.com/docker/docker# docker pull centos:7
7: Pulling from library/centos
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Image is up to date for centos:7
root@3cede98051a6:/go/src/github.com/docker/docker# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              7                   eeb6ee3f44bd        15 months ago       204MB
root@3cede98051a6:/go/src/github.com/docker/docker# docker run --rm -it eeb /bin/bash
[root@26c12cba6431 /]# exit
exit

使用Delve调试

都从源码构建了,总不可能单纯奔着纯安装去的吧,多少是想对docker做点简单的定制化,这里就可以使用Delve来调试我们编译出来的dockerd二进制程序了。

dlv /usr/local/bin/dockerd -- -D

哎,咋报错了

2022-12-14T09:10:43Z error layer=debugger error loading binary "/usr/local/bin/dockerd": could not parse .eh_frame section: pointer encoding not supported 0x9b at 0x3150
could not launch process: could not parse .eh_frame section: pointer encoding not supported 0x9b at 0x3150

这个报错是由于默认的hack/make.sh中的这一段(我所编译的版本在105)

IAMSTATIC='true'
if [ -z "$DOCKER_DEBUG" ]; then
	LDFLAGS='-w'
fi

在编译时加了-w参数删除了调试信息,所以在编译时添加参数或者写到环境变量里就行啦

# 在容器创建时添加debug参数
DOCKER_DEBUG=1 make BIND_DIR=. shell
# 在编译时添加参数
DOCKER_DEBUG=1 hack/make.sh binary

以上两种方法都可以,之后就可以使用dlv来调试docekrd了

root@f42403397fa5:/go/src/github.com/docker/docker# dlv exec --check-go-version=false /usr/local/bin/dockerd -- -D
WARNING: undefined behavior - version of Delve is too old for Go version 1.19.4 (maximum supported version 1.18)
Type 'help' for list of commands.
(dlv)

至于为什么加上 --check-go-version=false 这个参数,如果你是使用开发中的分支,docker的开发者可能忽略了更新dlv的版本,导致dlv的版本有那么一丝落后于go的版本。如果你要解决这个问题可以通过修改Dockerfile中的 Delve镜像拖取的版本,像是如下这样,把AELVE_VERSION修改为1.9.1即可。

ARG DELVE_VERSION=v1.8.1
# Delve on Linux is currently only supported on amd64 and arm64;
# https://github.com/go-delve/delve/blob/v1.8.1/pkg/proc/native/support_sentinel.go#L1-L6
RUN --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=cache,target=/go/pkg/mod \
        case $(dpkg --print-architecture) in \
            amd64|arm64) \
                GOBIN=/build/ GO111MODULE=on go install "github.com/go-delve/delve/cmd/dlv@${DELVE_VERSION}" \
                && /build/dlv --help \
                ;; \
            *) \
                mkdir -p /build/ \
                ;; \
        esac

至于delve调试工具如何使用就不在本文里细述,可通过help的方式知道如何使用,类似于gdb,上手十分的简单。

参考

https://github.com/moby/moby/tree/master/docs/contributing
https://github.com/moby/moby/blob/master/docs/contributing/debug.md
https://github.com/moby/moby/blob/master/docs/contributing/set-up-dev-env.md

到此这篇关于从源码构建docker-ce的文章就介绍到这了,更多相关从源码构建docker-ce内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ubuntu17.10安装docker-ce的方法

    本文介绍了ubuntu17.10安装docker-ce的方法,分享给大家,具体如下: 系统要求:centos 7 64位,centos-extras存储库必须启用. 卸载旧版Docker 查询当前的Docker版本 $ docker -v 如果存在已安装的Docker,卸载 $ sudo yum remove docker \ docker-common \ docker-selinux \ docker-engine 注意:卸载后,/ var / lib / docker / 下内容(imag

  • 树莓派4b ubuntu19 server 安装docker-ce的安装步骤

    树莓派型号是4b,1G RAM. 系统是ubuntu19.10 server. 下载命令如下: wget "https://download.docker.com/linux/ubuntu/dists/disco/pool/stable/arm64/containerd.io_1.2.10-3_arm64.deb" wget "https://download.docker.com/linux/ubuntu/dists/disco/pool/stable/arm64/dock

  • 从源码构建docker-ce的过程分析

    目录 准备环境 获取源码 编译前的准备工作 添加dockerd的代理 开始编译 使用Delve调试 参考 准备环境 准备一台Linux主机,并在上面安装好docker-ce,安装好make,git就可以开始编译工作了.对,就是如此简单,可能你会对此感到异或为啥要装docker,我不是准备编译这个玩意么,为啥不装go,docker不是用go开发的么? 这些疑问会在后面的步骤中解答. # docker-ce 安装参考 # FROM: https://developer.aliyun.com/arti

  • springboot-2.3.x最新版源码阅读环境搭建(基于gradle构建)

    一.前言 跟很多小伙伴聊天,发现一个严重的问题,很多小伙伴横向发展的貌似很不错,很多技术都能说出一二,但是如果在某个技术上深挖一下就不行了,问啥啥不会.就拿springboot来说,很多同学止步于springboot的应用,再往深处就一问三不知了,那么如何破局呢?smart哥认为最好的办法就是直捣黄龙,要把一个技术理解透了,听别人讲一万遍原理,不如自己撕一遍源码. 要阅读源码那就首先得先搭建源码阅读环境,那么本篇文章就来介绍下Spring Boot的源码环境搭建. 鉴于spring团队已经全面抛

  • 深入解析Vue源码实例挂载与编译流程实现思路详解

    在正文开始之前,先了解vue基于源码构建的两个版本,一个是 runtime only ,另一个是 runtime加compiler 的版本,两个版本的主要区别在于后者的源码包括了一个编译器. 什么是编译器,百度百科上面的解释是 简单讲,编译器就是将"一种语言(通常为高级语言)"翻译为"另一种语言(通常为低级语言)"的程序.一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) →

  • 使用idea和gradle编译spring5源码的方法步骤

    写在前面:spring 应该对于每个从事java开发的大兄弟们来说应该都不陌生的,作为一个从业两年多的小开发仔,个人觉得,每天都在面对spring,确从来没有编译过spring源码,有点不太合适.最近在研究spring源码的时候,突然想起编译一下spring源码,网上应该也有很多大神编译过spring源码,在这里我把我再编译过程的遇到的坑,来跟大家分享下. 版本工具:spring5.0.x,gradle4,9,jdk1.8_131,kotlin1.2.51,groovy2.4.15,Intell

  • 基于Gradle搭建Spring 5.3.13-release源码阅读环境的详细流程

    目录 # 1.安装JDK # 2.安装Gradle # 3.Spring版本命名规则 # 4.下载Spring 5.3.13-release源码 # 5.修改Spring源码中Gradle配置 # 6.构建Spring源码 # 7.导入IDEA 点击File --> New --> Project from Existing Sources... # 8.创建Spring源码debug调试模块 # 基于Gradle搭建Spring 5.5.13-release源码阅读环境 Spring版本:5

  • 深入解析vue 源码目录及构建过程分析

    ​" 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整体有一个认知,有助于后续对源码的阅读." 一.目录结构 上图是对vue的代码的所有目录进行的梳理,其中源码位于src目录下,下面对src下的目录进行介绍. compiler 该目录是编译相关的代码,即将 template 模板转化成 render 函数的代码. vue 提供了 render 函数,render 函数作用是用来创建 VNode,但在平时开发中,绝大多数情况下使用 template 来创建 H

  • docker容器源码部署httpd用存储卷部署网站(推荐)

    目录 docker容器源码部署httpd,用存储卷部署网站 创建一个httpd镜像 部署nfs 挂载 创建容器并映射 访问测试 docker容器源码部署httpd,用存储卷部署网站 创建一个httpd镜像 // 创建一个httpd容器 [root@localhost ~]# docker run -tid --name httpd centos 2d693e16f4f3734b127cbae90d189c1b4e78619a54ceec912a82d96cf4f1c345 [root@local

  • Ubuntu Docker 源码编译(1.9.1 )详解

    Ubuntu Docker 源码编译: 网上对Ubuntu Docker 源码编译的资料有很多,但是对于具体如何操作,和命令的实现不是多细致,经过我一番折腾,终于把源码编译搞定,这里记录下,以便以后使用参考, 一.系统环境 Ubuntu14.04 desktop 64位 二.安装Docker(Docker内编译Docker) $ sudo apt-get update $ sudo apt-get install wget $ wget -qO- https://get.docker.com/

  • 详解Docker源码编译安装

    最近在尝试阅读Docker源码,一直想弄明白docker关于namespace等的代码的在哪,以及怎么触发.然而在阅读时发现根本找不到代码...想着还是先源码安装下docker,然后边运行边打印些调试信息看看再说 安装之前 Docker源码需在docker容器编译环境中编译,所以先安装docker,安装环境依旧是ubuntu14.04 echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee

  • git拉源码maven构建后部署脚本详解

    部署某个中间件到测试机器脚本 从git取源码,再maven构建,将jar拷贝到服务器,备份旧版本,重启. #!/bin/bash server_ips=(132.121.100.44 132.121.100.45 132.121.100.46 132.121.100.47) git_url=http://seaboat:123456@132.122.1.21:8888/splan/dbpool-src.git port=22 user=seaboat dbproxy_base=/data/sea

随机推荐