1 编译目标
由于 openEuler 所有版本适配的 docker 版本为 18.09,版本比较低不能满足大部分使用场景。因此本文以基于openEuler 22.03 LTS SP4 操作系统编译 docker-ce-20.10.13 为例,演示在 openEuler 操作系统上编译高版本 docker 的操作流程
2 环境准备
2.1 网络环境
由于编译 docker 所需的源代码资源都在外网,因此需要提前配置代理
# 配置代理
PROXY_IP=192.168.230.1
PROXY_PORT=1080
export http_proxy=http://${PROXY_IP}:${PROXY_PORT}
export https_proxy=http://${PROXY_IP}:${PROXY_PORT}
export ALL_PROXY=http://${PROXY_IP}:${PROXY_PORT}
export all_proxy=socks://${PROXY_IP}:${PROXY_PORT}
# 测试代理
$ curl www.google.com
2.2 编译工具
安装必要的编译工具
$ yum install -y rpm-build rpmdevtools gcc gcc-c++ make golang
2.3 编译资源
软件包名 | 下载地址 |
---|---|
docker-ce-20.10.10-3.el8.src.rpm | https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-20.10.10-3.el8.src.rpm |
docker-ce-cli-20.10.13-3.el8.src.rpm | https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-cli-20.10.13-3.el8.src.rpm |
docker-ce-rootless-extras-20.10.13-3.el8.src.rpm | https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm |
containerd.io-1.4.3-3.2.src.rpm | https://repo.openeuler.openatom.cn/openEuler-preview/sw_arch/openEuler-22.03-LTS/sources/Packages/containerd.io-1.4.3-3.2.src.rpm |
docker-scan-plugin-0.12.0-3.el8.src.rpm | https://download.docker.com/linux/centos/8/source/stable/Packages/docker-scan-plugin-0.12.0-3.el8.src.rpm |
3 编译流程
3.1 编译 docker-ce
3.1.1 编译
# 定义 GOPATH 路径
$ export GOPATH=/go
# 设置不使用 Go Modules 功能
$ export GO111MODULE=off
# 从 docker 官方仓库下载 docker-ce-20.10.10-3.el8.src.rpm 源码包
$ wget https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-20.10.10-3.el8.src.rpm -P /root
-2024-11-09 12:39:03-- https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-20.10.10-3.el8.src.rpm
Connecting to 192.168.230.1:1080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 11328477 (11M) [binary/octet-stream]
Saving to: ‘/root/docker-ce-20.10.10-3.el8.src.rpm’
docker-ce-20.10.10-3.el8. 100%[==================>] 10.80M 1.67MB/s in 7.5s
2024-11-09 12:39:12 (1.44 MB/s) - ‘/root/docker-ce-20.10.10-3.el8.src.rpm’ saved [11328477/11328477]
# 安装 docker-ce-20.10.10-3.el8.src.rpm源码包
$ rpm -ivh /root/docker-ce-20.10.10-3.el8.src.rpm
warning: /root/docker-ce-20.10.10-3.el8.src.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Updating / installing...
1:docker-ce-3:20.10.10-3.el8 ################################# [100%]
# 进入 spec 文件目录
$ cd /root/rpmbuild/SPECS
# 修改 spec 文件
$ sed -i \
-e '1i %define _version 20.10.13' \
-e '1i %define _release 3' \
-e '1i %define _origversion %{_version}' \
-e '1i \ ' \
docker-ce.spec
# 安装编译包依赖
$ yum builddep -y docker-ce.spec
# 开始编译
$ rpmbuild -ba docker-ce.spec
3.1.2 FAQ
(1)no required module provides package github.com/docker/libnetwork/cmd/proxy: go.mod file not found in current directory or any parent directory; see 'go help modules'
报错信息:
报错原因:
参考文献:报错no required module provides package github.comxx的解决方案-CSDN博客
Go Modules 是在 Go 1.11 版本中引入的。此时从 git 上下载的依赖库不再保存在 GOPATH
中,而是存到当前项目中,并使用 go.mod 文件跟踪依赖库和其版本。GO111MODULE
这个环境变量也是此时引入的,作为控制是否开启 Go Modules 的开关,Go Modules 和 GOPATH 是两个对立的依赖存储和搜索方式
解决方案:
从 Go 1.16 开始,默认行为是 GO111MODULE=on
,这意味着如果您想继续使用旧 GOPATH 方式,则必须强制 Go 不使用 Go Modules 功能:
$ export GO111MODULE=off
(2)error: missing GOPATH; please see https://golang.org/doc/code.html#GOPATH alternatively, set AUTO_GOPATH=1
报错信息:
报错原因:
GOPATH
变量未定义
$ echo $GOPATH
解决方案:
指定 GOPATH
变量
$ export GOPATH=/go
3.2 编译 docker-ce-cli
3.2.1 编译
# 定义 GOPATH 路径
$ export GOPATH=/go
# 添加 PATH 变量
$ export PATH=${PATH}:${GOPATH}/bin
# 设置不使用 Go Modules 功能
$ export GO111MODULE=off
# 从 docker 官方仓库下载 docker-ce-cli-20.10.13-3.el8.src.rpm 源码包
$ wget https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-cli-20.10.13-3.el8.src.rpm -P /root
--2024-11-09 17:26:50-- https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-cli-20.10.13-3.el8.src.rpm
Connecting to 192.168.230.1:1080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 7688788 (7.3M) [binary/octet-stream]
Saving to: ‘/root/docker-ce-cli-20.10.13-3.el8.src.rpm’
docker-ce-cli-20.10.13-3. 100%[==================>] 7.33M 1.64MB/s in 4.5s
2024-11-09 17:26:56 (1.64 MB/s) - ‘/root/docker-ce-cli-20.10.13-3.el8.src.rpm’ saved [7688788/7688788]
# 安装 docker-ce-cli-20.10.13-3.el8.src.rpm 源码包
$ rpm -ivh /root/docker-ce-cli-20.10.13-3.el8.src.rpm
warning: /root/docker-ce-cli-20.10.13-3.el8.src.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Updating / installing...
1:docker-ce-cli-1:20.10.13-3.el8 ################################# [100%]
# 进入 spec 文件目录
$ cd /root/rpmbuild/SPECS
# 修改 spec 文件
$ sed -i \
-e '1i %define _version 20.10.13' \
-e '1i %define _release 3' \
-e '1i %define _origversion %{_version}' \
-e '1i \ ' \
docker-ce-cli.spec
# 安装编译包依赖
$ yum builddep -y docker-ce-cli.spec
# 开始编译
$ rpmbuild -ba docker-ce-cli.spec
3.2.2 FAQ
(1)cannot find package "github.com/docker/cli/cmd/docker" in any of
报错信息:
报错原因:
GOPATH
变量未定义
$ echo $GOPATH
解决方案:
指定 GOPATH
变量
$ export GOPATH=/go
(2)go: cannot find main module, but found vendor.conf in /go/src/github.com/docker/cli
报错信息:
报错原因:
参考文献:报错no required module provides package github.comxx的解决方案-CSDN博客
Go Modules 是在 Go 1.11 版本中引入的。此时从 git 上下载的依赖库不再保存在 GOPATH
中,而是存到当前项目中,并使用 go.mod 文件跟踪依赖库和其版本。GO111MODULE
这个环境变量也是此时引入的,作为控制是否开启 Go Modules 的开关,Go Modules 和 GOPATH 是两个对立的依赖存储和搜索方式
解决方案:
从 Go 1.16 开始,默认行为是 GO111MODULE=on
,这意味着如果您想继续使用旧 GOPATH 方式,则必须强制 Go 不使用 Go Modules 功能:
$ export GO111MODULE=off
(3)./man/md2man-all.sh: line 21: go-md2man: command not found
报错信息:
报错原因:
未找到 go-md2man
命令,实际此时该命令已经编译成功,位于 /go/bin 目录中
$ ls -l /go/bin/
total 2604
-rwxr-xr-x 1 root root 2666053 Nov 9 17:39 go-md2man
解决方案:
将 /go/bin 添加 PATH
变量
# 将 /go/bin 添加 PATH 变量
$ export PATH=${PATH}:${GOPATH}/bin
# 查询是否能找到 go-md2man 命令
$ which go-md2man
/go/bin/go-md2man
3.3 编译 docker-ce-rootless-extras
# 从 docker 官方仓库下载 docker-ce-rootless-extras-20.10.13-3.el8.src.rpm 源码包
$ wget https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm -P /root
--2024-11-09 17:52:50-- https://download.docker.com/linux/centos/8/source/stable/Packages/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm
Connecting to 192.168.230.1:1080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 11211542 (11M) [binary/octet-stream]
Saving to: ‘/root/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm’
docker-ce-rootless-extras 100%[==================>] 10.69M 2.57MB/s in 4.2s
2024-11-09 17:52:55 (2.57 MB/s) - ‘/root/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm’ saved [11211542/11211542]
# 安装 docker-ce-rootless-extras-20.10.13-3.el8.src.rpm 源码包
$ rpm -ivh /root/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm
warning: /root/docker-ce-rootless-extras-20.10.13-3.el8.src.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Updating / installing...
1:docker-ce-rootless-extras-0:20.10################################# [100%]
# 进入 spec 文件目录
$ cd /root/rpmbuild/SPECS
# 修改 spec 文件
$ sed -i \
-e '1i %define _version 20.10.13' \
-e '1i %define _release 3' \
-e '1i \ ' \
docker-ce-rootless-extras.spec
# 安装编译包依赖
$ yum builddep -y docker-ce-rootless-extras.spec
# 开始编译
$ rpmbuild -ba docker-ce-rootless-extras.spec
3.4 编译 containerd.io
3.4.1 编译
(1)环境准备
# 定义 GOPATH 路径
$ export GOPATH=/root/go
(2)部署 containerd 源码
# 创建存放 containerd 的源码目录
$ mkdir -p $GOPATH/src/github.com/containerd
# 进入存放 containerd 的源码目录
$ cd $GOPATH/src/github.com/containerd
# 克隆 containerd 源码
$ git clone https://github.com/containerd/containerd.git
Cloning into 'containerd'...
remote: Enumerating objects: 148247, done.
remote: Counting objects: 100% (19157/19157), done.
remote: Compressing objects: 100% (1209/1209), done.
remote: Total 148247 (delta 18390), reused 18188 (delta 17926), pack-reused 129090 (from 1)
Receiving objects: 100% (148247/148247), 113.09 MiB | 2.27 MiB/s, done.
Resolving deltas: 100% (96229/96229), done.
# 进入克隆的 containerd 源码目录
$ cd $GOPATH/src/github.com/containerd/containerd
# 切换分支,因为高版本分支需要较高的 go 版本支持
$ git checkout v1.5.18
# 确认分支是否正确
$ git branch
* (HEAD detached at v1.5.18)
main
(3)部署 runc 源码
# 创建存放 runc 的源码目录
$ mkdir -p $GOPATH/src/github.com/opencontainers
# 进入存放 runc 的源码目录
$ cd $GOPATH/src/github.com/opencontainers
# 克隆 runc 源码
$ git clone https://github.com/opencontainers/runc.git
Cloning into 'runc'...
remote: Enumerating objects: 44540, done.
remote: Counting objects: 100% (194/194), done.
remote: Compressing objects: 100% (138/138), done.
remote: Total 44540 (delta 80), reused 126 (delta 49), pack-reused 44346 (from 1)
Receiving objects: 100% (44540/44540), 22.01 MiB | 1.52 MiB/s, done.
Resolving deltas: 100% (29266/29266), done.
# 进入克隆的 runc 源码目录
$ cd $GOPATH/src/github.com/opencontainers/runc
# 切换分支,因为高版本分支需要较高的 go 版本支持
$ git checkout v1.1.12
# 确认分支是否正确
$ git branch
* (HEAD detached at v1.1.12)
main
(4)部署 go-md2man
工具命令
# 安装 go-md2man 工具命令
$ go install github.com/cpuguy83/go-md2man/v2@latest
# 查看命令是否安装成功
$ ls -l ${GOPATH}/bin
total 2624
-rwxr-xr-x 1 root root 2685640 Nov 9 19:59 go-md2man
# 将命令路径添加到 PATH
$ export PATH=${PATH}:${GOPATH}/bin
# 查询是否能找到 go-md2man 命令
$ which go-md2man
/root/go/bin/go-md2man
(5)编译 containerd.io
# 从 OEPKGS 仓库下载 containerd.io-1.4.3-3.2.src.rpm 源码包
$ wget https://repo.openeuler.openatom.cn/openEuler-preview/sw_arch/openEuler-22.03-LTS/sources/Packages/containerd.io-1.4.3-3.2.src.rpm -P /root
--2024-11-09 19:32:48-- https://repo.openeuler.openatom.cn/openEuler-preview/sw_arch/openEuler-22.03-LTS/sources/Packages/containerd.io-1.4.3-3.2.src.rpm
Resolving repo.openeuler.openatom.cn (repo.openeuler.openatom.cn)... 124.70.105.51
Connecting to repo.openeuler.openatom.cn (repo.openeuler.openatom.cn)|124.70.105.51|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 15017 (15K) [application/x-redhat-package-manager]
Saving to: ‘/root/containerd.io-1.4.3-3.2.src.rpm’
containerd.io-1.4.3-3.2.s 100%[==================>] 14.67K 45.6KB/s in 0.3s
2024-11-09 19:32:48 (45.6 KB/s) - ‘/root/containerd.io-1.4.3-3.2.src.rpm’ saved [15017/15017]
# 安装 containerd.io-1.4.3-3.2.src.rpm 源码包
$ rpm -ivh /root/containerd.io-1.4.3-3.2.src.rpm
Updating / installing...
1:containerd.io-1.4.3-3.2 ################################# [100%]
# 进入 spec 文件目录
$ cd /root/rpmbuild/SPECS
# 修改 spec 文件
$ sed -i '/^rm -rf %{_topdir}\/BUILD\// s/\/$//' containerd.spec
# 定义 spec 文件中需要的环境变量
$ export RPM_VERSION=1.4.3
$ export RPM_RELEASE_VERSION=3.2
# 安装编译包依赖
$ yum builddep -y containerd.spec
# 开始编译
$ rpmbuild -ba containerd.spec
3.4.2 FAQ
(1)RPM: error: line 46: Empty tag: Version
报错信息:
报错原因:
containerd.spec 文件中第 46 行和第 47 行为定义 rpm 包的版本信息,其变量的值来自于环境变量 RPM_VERSION
和 RPM_RELEASE_VERSION
,但是这两个环境变量未定义
Version: %{getenv:RPM_VERSION}
Release: %{getenv:RPM_RELEASE_VERSION}
解决方案:
在命令行中定义环境变量:RPM_VERSION
和 RPM_RELEASE_VERSION
$ export RPM_VERSION=1.4.3
$ export RPM_RELEASE_VERSION=3.2
(2)is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt
报错信息:
报错原因:
go.mod
文件和 vendor/modules.txt
文件之间存在不一致
解决方案:
重新拉取源代码,确认go.mod
文件和 vendor/modules.txt
文件是否一致
3.5 编译 docker-scan-plugin
# 从 docker 官方仓库下载 docker-scan-plugin-0.12.0-3.el8.src.rpm 源码包
$ wget https://download.docker.com/linux/centos/8/source/stable/Packages/docker-scan-plugin-0.12.0-3.el8.src.rpm -P /root
--2024-11-09 20:38:29-- https://download.docker.com/linux/centos/8/source/stable/Packages/docker-scan-plugin-0.12.0-3.el8.src.rpm
Connecting to 192.168.230.1:1080... connected.
Proxy request sent, awaiting response... 200 OK
Length: 104035 (102K) [binary/octet-stream]
Saving to: ‘/root/docker-scan-plugin-0.12.0-3.el8.src.rpm’
docker-scan-plugin-0.12.0 100%[==================>] 101.60K 278KB/s in 0.4s
2024-11-09 20:38:33 (278 KB/s) - ‘/root/docker-scan-plugin-0.12.0-3.el8.src.rpm’ saved [104035/104035]
# 安装 docker-scan-plugin-0.12.0-3.el8.src.rpm 源码包
$ rpm -ivh /root/docker-scan-plugin-0.12.0-3.el8.src.rpm
warning: /root/docker-scan-plugin-0.12.0-3.el8.src.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Updating / installing...
1:docker-scan-plugin-0:0.12.0-3.el8################################# [100%]
# 进入 spec 文件目录
$ cd /root/rpmbuild/SPECS
# 修改 spec 文件
$ sed -i \
-e '1i %define _scan_rpm_version 0.12.0' \
-e '1i %define _release 3' \
-e '1i %define _scan_version v%{_scan_rpm_version}' \
-e '1i \ ' \
docker-scan-plugin.spec
# 安装编译包依赖
$ yum builddep -y docker-scan-plugin.spec
# 开始编译
$ rpmbuild -ba docker-scan-plugin.spec
4 安装测试
(1)安装
# 进入存放构建完成的 rpm 包目录
$ cd /root/rpmbuild/RPMS/x86_64/
# 查看编译完成的 rpm 包
$ ls -l
total 91636
-rw-r--r-- 1 root root 31520637 Nov 9 20:32 containerd.io-1.4.3-3.2.x86_64.rpm
-rw-r--r-- 1 root root 22738649 Nov 9 17:10 docker-ce-20.10.13-3.x86_64.rpm
-rw-r--r-- 1 root root 30831385 Nov 9 17:46 docker-ce-cli-20.10.13-3.x86_64.rpm
-rw-r--r-- 1 root root 4890517 Nov 9 19:20 docker-ce-rootless-extras-20.10.13-3.x86_64.rpm
-rw-r--r-- 1 root root 3842797 Nov 9 20:44 docker-scan-plugin-0.12.0-3.x86_64.rpm
# 执行本地安装
$ yum localinstall *.rpm
(2)测试
# 配置加速地址
$ cat >> /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [ "https://367e3d3a84aa407eb200df7aab688eaf.mirror.swr.myhuaweicloud.com" ]
}
EOF
# 启动 docker 并设置开机自启
$ systemctl start docker && systemctl enable docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
# 查看 docker 基本信息
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.8.0-docker)
scan: Docker Scan (Docker Inc., v0.12.0)
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 20.10.13
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version:
runc version: v1.1.12-0-g51d5e946
init version: de40ad0
Kernel Version: 5.10.0-216.0.0.115.oe2203sp4.x86_64
Operating System: openEuler 22.03 (LTS-SP4)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 7.228GiB
Name: localhost.localdomain
ID: S6QG:FGLU:ZJC2:2N2Q:6SZS:HDTN:MDBY:CACI:DQ7Q:SX3B:XJ34:MFNO
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
# 拉取镜像
$ docker pull openeuler/openeuler:22.03-lts-sp4
22.03-lts-sp4: Pulling from openeuler/openeuler
6550e36f5825: Pull complete
12f045674288: Pull complete
Digest: sha256:7b3947d10e1f9459ffae6303349f9f7dba79a1eb992adaa10172df6cbdac2b4e
Status: Downloaded newer image for openeuler/openeuler:22.03-lts-sp4
docker.io/openeuler/openeuler:22.03-lts-sp4
# 创建容器
$ docker run -d --name test01 openeuler/openeuler:22.03-lts-sp4 /bin/bash -c "sleep 3600"
cca749590ba66bdd6812bba5e83c17d5be217772933cb3c725aa831883c93b9a
评论