x86架构机器构建多CPU架构镜像

多CPU架构镜像

前提条件

目前使用的镜像都为x86架构的镜像,镜像架构与系统架构不匹配将无法进行正常部署。在进行本地构建镜像时,本地架构多为x86架构,无法正常构建其他架构的镜像,所以需要使用CPU虚拟化的方式来构建多CPU架构镜像。也可以直接通过其他CPU架构机器构建各自适配的镜像,这里使用x86架构机器构建其他架构(arm64)的镜像

使用虚拟化构建有2种方式:
  1. Mac、windows专业版可以通过开启CPU虚拟化、安装docker deskTop 进行构建
  2. x86架构的Linux系统可以通过启动binfmt_misc来开启CPU虚拟化从 而进行构建

本文档将以x86架构的Linux系统通过开启CPU虚拟化的方式来构建多CPU架构镜像,需要有如下前提:

  1. 开启buildx
    通过buildx构建多架构镜像,官方要求的docker版本为不低于19.03,没有测试低版本是否可行。
  2. 开启binfmt_misc
    为了运行非本地架构(本地架构多数为x86)的镜像,需要开启binfmt_misc(CPU虚拟化),需要linux内核为高版本,测试发现3.10.0-957内核版本无法满足,通过升级内核到5.8.12-1.el7.elrepo.x86_64开启成功,未测试最低版本是多少。
  3. 构建时需要连接到公共仓库
    在进行镜像构建时,buildx需要查询镜像的架构清单,该架构清单目前仅在公共仓库存在,buildx构建不同架构镜像时,会通过架构清单获取基础镜像的不同架构,再进行镜像构建,所以网络需要可连接到公共仓库。比如:dockerHub、quay.io、k8s.gcr.io、us.gcr.io等常用公共仓库。

一、Centos7.6升级内核

  • 当前系统
[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

二、安装/配置VPN

可自行或使用其他国内镜像源拉取镜像

三、使用buildx构建多架构镜像

虚拟机发生重启后,binfmt_misc将会自动关闭,同时,创建的builder将会处于停止状态。需要执行两步重新打开:开启binfmt_misc、加载CPU架构。

在构建之前,请一定仔细查看Dockerfile的基础镜像是否支持多个CPU架构,大部分常用镜像的低版本是不支持的,版本过低时就需要提高版本,否则在构建时,虽然指定镜像为其他架构(非x86),但是如果该镜像仅支持x86架构,那么构建出来的镜像仍然为x86架构。比如常用的java镜像,低版本可能就仅支持x86架构
x86架构机器构建多CPU架构镜像_第1张图片

  • 开启buildx
  1. Docker二进制
下载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
  1. docker-ce
mkdir ~/.docker
vim ~/.docker/config.json
{
"experimental": "enabled"
}
  • 开启binfmt_misc
    docker run --rm --privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d
    执行docker run没有报错,同时目录下有如下内容,则表明开启成功
    x86架构机器构建多CPU架构镜像_第2张图片

  • 构建

  1. 创建builder
#docker buildx create --use --name mybuilder
可有限的提高镜像拉取速度
docker buildx create --use --name=mybuilder --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master

在这里插入图片描述

  1. 加载CPU架构
docker buildx inspect --bootstrap

x86架构机器构建多CPU架构镜像_第3张图片

  1. 创建Dockerfile
    首先,需要保证FROM的基础镜像指定版本包含了多架构清单。
[root@localhost ~]# cat Dockerfile 
FROM alpine:latest
RUN uname -a > /os.txt \
    && uname -m >> /os.txt
CMD cat /os.txt
  1. 构建镜像
    构建的镜像默认是保存在构建缓存中,需要将镜像上传至镜像仓库或保存至本地才可使用
    Ⅰ 第一种:构建存在多架构清单的镜像并上传至镜像仓库
docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le -t anyy/alpine:v1 --push .
--platform 指定架构名称,多个架构中间用逗号隔开
--push 生成多架构清单,同时推送至镜像仓库
-t 指定镜像名称

x86架构机器构建多CPU架构镜像_第4张图片

Ⅱ 第二种:构建指定架构的镜像并保存至本地

docker buildx build --platform=linux/arm64 -t alpine-arm64:test -o type=docker .
--platform 指定架构名称
-o type=docker 将镜像保存至本地
-t 指定镜像名称

四、构建示例
1、简单构建alpine
本示例以alpine为例构建arm64架构的镜像。

  1. Dockerfile
    本示例仅为了表示不同架构镜像构建成功,所以Dockerfile将会简化
[root@localhost ~]# cat Dockerfile 
FROM alpine:latest
RUN uname -a > /os.txt \
    && uname -m >> /os.txt
CMD cat /os.txt
  1. 构建镜像
docker buildx build --platform=linux/arm64 -t anyy/alpine:demo -o type=docker .

x86架构机器构建多CPU架构镜像_第5张图片

  1. 测试镜像
    Ⅰ 构建镜像的节点测试
    该节点开启了binfmt_misc,所以可以正常运行不同架构的镜像。
docker run -it --rm anyy/alpine:demo

在这里插入图片描述

Ⅱ x86架构节点测试
通过docker save、docker load的方式拷贝镜像,或将构建的镜像上传至公共仓库(即构建镜像的第一种方式)
非当前架构的镜像在运行时将会出现明显报错,同时启动的该容器无法通过docker stop停止,当执行docker stop之后,终端可能会断开连接(本地测试是这样的,原因未查明),再次连接终端后查看该容器依然存在。需要重启docker,让该容器自动退出后在进行删除。
x86架构机器构建多CPU架构镜像_第6张图片
x86架构机器构建多CPU架构镜像_第7张图片

2、重新编译构建coredns
本实例以构建coredns为例,需要获取源码编译coredns二进制文件,再通过Dockerfile进行构建。

  1. 获取源码
git clone https://github.com/coredns/coredns.git
#切换tag至v1.6.5
git checkout v1.6.5

x86架构机器构建多CPU架构镜像_第8张图片
x86架构机器构建多CPU架构镜像_第9张图片

  1. 拉取arm64架构的go镜像
docker pull --platform linux/arm64 go:1.15.3

x86架构机器构建多CPU架构镜像_第10张图片

  1. 使用arm64架构的go镜像编译coredns
#启动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

x86架构机器构建多CPU架构镜像_第11张图片
x86架构机器构建多CPU架构镜像_第12张图片

  1. 构建coredns镜像
docker buildx build --platform=linux/arm64 -t anyy/coredns:arm64-1.6.5 --push .

x86架构机器构建多CPU架构镜像_第13张图片

  1. 测试coredns镜像
    Ⅰ 构建镜像的节点测试
    该节点开启了binfmt_misc,所以可以正常运行不同架构的镜像。
    x86架构机器构建多CPU架构镜像_第14张图片

Ⅱ x86架构节点测试
镜像架构与系统架构不匹配,所以无法正常启动

x86架构机器构建多CPU架构镜像_第15张图片

五、支持拉取不同架构镜像
Docker默认会拉取与节点自身架构相匹配的镜像,若需要在当前架构节点拉取其他架构镜像,需要指定架构名称。当镜像所支持的架构不包含节点本身架构时,那么将会拉取其他镜像,未发现有什么优先级。
比如test:v1镜像支持arm64架构,当我在x86架构拉取该镜像时,会首先在架构清单寻找是否存在x86架构的镜像,如果不存在就会将arm架构镜像拉取下来。
Docker开启experimental

cat /etc/docker/daemon.json 
{
"experimental": true
}

六、拉取多架构镜像
查看某镜像是否支持特定架构
x86架构机器构建多CPU架构镜像_第16张图片

拉取(推荐第一种)
方式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

x86架构机器构建多CPU架构镜像_第17张图片

你可能感兴趣的:(Linux个人学习笔记,docker,多CPU架构镜像)