目前使用的镜像都为x86架构的镜像,镜像架构与系统架构不匹配将无法进行正常部署。在进行本地构建镜像时,本地架构多为x86架构,无法正常构建其他架构的镜像,所以需要使用CPU虚拟化的方式来构建多CPU架构镜像。也可以直接通过其他CPU架构机器构建各自适配的镜像,这里使用x86架构机器构建其他架构(arm64)的镜像
本文档将以x86架构的Linux系统通过开启CPU虚拟化的方式来构建多CPU架构镜像,需要有如下前提:
[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
1. 导入公钥
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org (external link)
2. 安装ELRepo
yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
3. 检查内核包
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
4. 安装新内核版本
yum --enablerepo=elrepo-kernel install kernel-ml
5. 设置默认内核版本
vim /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=0
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
6. 重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg
7. 重启虚拟机
8. 选择高内核版本登录
9. 检查系统
[root@localhost ~]# uname -a
Linux localhost.localdomain 5.8.12-1.el7.elrepo.x86_64 #1 SMP Fri Sep 25 17:49:38 EDT 2020 x86_64 x86_64 x86_64 GNU/Linux
可自行或使用其他国内镜像源拉取镜像
虚拟机发生重启后,binfmt_misc将会自动关闭,同时,创建的builder将会处于停止状态。需要执行两步重新打开:开启binfmt_misc、加载CPU架构。
在构建之前,请一定仔细查看Dockerfile的基础镜像是否支持多个CPU架构,大部分常用镜像的低版本是不支持的,版本过低时就需要提高版本,否则在构建时,虽然指定镜像为其他架构(非x86),但是如果该镜像仅支持x86架构,那么构建出来的镜像仍然为x86架构。比如常用的java镜像,低版本可能就仅支持x86架构
下载buildx二进制文件:https://github.com/docker/buildx/releases
mkdir ~/.docker/cli-plugins
mv buildx-v0.4.2.linux-amd64 .docker/cli-plugins/docker-buildx
chmod a+x ~/.docker/cli-plugins/docker-buildx
mkdir ~/.docker
vim ~/.docker/config.json
{
"experimental": "enabled"
}
开启binfmt_misc
docker run --rm --privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d
执行docker run没有报错,同时目录下有如下内容,则表明开启成功
构建
#docker buildx create --use --name mybuilder
可有限的提高镜像拉取速度
docker buildx create --use --name=mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master
docker buildx inspect --bootstrap
[root@localhost ~]# cat Dockerfile
FROM alpine:latest
RUN uname -a > /os.txt \
&& uname -m >> /os.txt
CMD cat /os.txt
docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le -t anyy/alpine:v1 --push .
--platform 指定架构名称,多个架构中间用逗号隔开
--push 生成多架构清单,同时推送至镜像仓库
-t 指定镜像名称
Ⅱ 第二种:构建指定架构的镜像并保存至本地
docker buildx build --platform=linux/arm64 -t alpine-arm64:test -o type=docker .
--platform 指定架构名称
-o type=docker 将镜像保存至本地
-t 指定镜像名称
四、构建示例
1、简单构建alpine
本示例以alpine为例构建arm64架构的镜像。
[root@localhost ~]# cat Dockerfile
FROM alpine:latest
RUN uname -a > /os.txt \
&& uname -m >> /os.txt
CMD cat /os.txt
docker buildx build --platform=linux/arm64 -t anyy/alpine:demo -o type=docker .
docker run -it --rm anyy/alpine:demo
Ⅱ x86架构节点测试
通过docker save、docker load的方式拷贝镜像,或将构建的镜像上传至公共仓库(即构建镜像的第一种方式)
非当前架构的镜像在运行时将会出现明显报错,同时启动的该容器无法通过docker stop停止,当执行docker stop之后,终端可能会断开连接(本地测试是这样的,原因未查明),再次连接终端后查看该容器依然存在。需要重启docker,让该容器自动退出后在进行删除。
2、重新编译构建coredns
本实例以构建coredns为例,需要获取源码编译coredns二进制文件,再通过Dockerfile进行构建。
git clone https://github.com/coredns/coredns.git
#切换tag至v1.6.5
git checkout v1.6.5
docker pull --platform linux/arm64 go:1.15.3
#启动arm64架构的golang镜像
docker run --rm -i -t -v $PWD:/v -w /v golang:1.15.3
#查看是否为arm64架构
uname -m
#设置go变量,否则可能在编译时拉取第三方扩展包失败
go env -w GOSUMDB=off
go env -w GOPROXY=https://goproxy.cn,direct
#开始编译
make
docker buildx build --platform=linux/arm64 -t anyy/coredns:arm64-1.6.5 --push .
Ⅱ x86架构节点测试
镜像架构与系统架构不匹配,所以无法正常启动
五、支持拉取不同架构镜像
Docker默认会拉取与节点自身架构相匹配的镜像,若需要在当前架构节点拉取其他架构镜像,需要指定架构名称。当镜像所支持的架构不包含节点本身架构时,那么将会拉取其他镜像,未发现有什么优先级。
比如test:v1镜像支持arm64架构,当我在x86架构拉取该镜像时,会首先在架构清单寻找是否存在x86架构的镜像,如果不存在就会将arm架构镜像拉取下来。
Docker开启experimental
cat /etc/docker/daemon.json
{
"experimental": true
}
拉取(推荐第一种)
方式1——通过版本
通过指定架构和镜像版本拉取
docker pull --platform OS/ARCH NAME:TAG
#比如docker pull --platform linux/ppc64le coredns/coredns:1.6.7
方式2——通过DIGEST
通过不同架构下镜像的不同sha256值进行拉取,拉取下来的镜像版本为,需要重新打tag
docker pull NAME@DIGEST
docker pull coredns/coredns@sha256:cf6908fdfa864f4243f4df8117da2b83355588e3c990d056110fc618b990980b