如何跨系统构建docker镜像?

Posted 西风未眠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何跨系统构建docker镜像?相关的知识,希望对你有一定的参考价值。

微信公众号“SRE成长记”可查看原文

1 前言

docker镜像有基于amd64系统的,也有基于arm64系统的。
前段时间用了一个在x86_64的centos7服务器上构建的image在一台国产aarch64服务器上运行,遇到了如下报错:
==standard_init_linux.go:219: exec user process caused: exec format error==
上述报错就是因为docker镜像的系统架构与部署容器的宿主机系统架构不一致。image文件的“Architecture”字段是amd64;运行镜像的服务器系统是aarch64架构。
想要构建在arm64/aarch64系统上能够运行的docker镜像,可以采取以下方法:
1)在arm64/aarch64系统服务器上构建镜像;
2)在x86_64/amd64服务器上使用buildx工具跨平台构建。

2 测试使用buildx构建image

==使用buildx有个非常重要的前提条件:docker版本为Docker 19.03+==

2.1 buildx实验规划

2.2 test103服务器安装buildx插件

1、在test103服务器上安装docker,版本为20.10.6(步骤略)
2、在test103服务器安装buildx
2.1、修改配置文件
1)修改/root/.docker/config.json,加入一行:=="experimental": "enabled"==。如果/root/.docker下面不存在该文件,则可以新创建。

[root@ops03 .docker]# cat /root/.docker/config.json 

 "experimental": "enabled"  #加入该行,这里文件是新的,所以只写了这一行内容

[root@ops03 .docker]#

2)修改/etc/docker/daemon.json文件,加入一行:=="experimental": true==

[root@ops03 docker]# cat /etc/docker/daemon.json

  "graph":"/docker",
  "experimental": true,   #加入该行
  "exec-opts":["native.cgroupdriver=systemd"],
  "insecure-registries": ["harbor.test.com:8081"],
  "registry-mirrors": ["https://1l3yp2sl.mirror.aliyuncs.com"],
  "default-address-pools": [
        
            "base": "192.168.0.0/16",
            "size": 24
        
    ]

[root@ops03 docker]# 

然后重启docker

systemctl daemon-reload
systemctl restart docker

2.2、安装buildx插件(==如果是yum安装的docker,则该插件包含在docker里了,可以略过该步骤。使用脚本安装的docker,则需要手动安装buildx==)
1)创建buildx插件目录(==注意路径,Linux下的安装路径为 $HOME/.docker/cli-plugins==),下载buildx文件

# mkdir /root/.docker/cli-plugins
# cd /root/.docker/cli-plugins/
# wget https://github.com/docker/buildx/releases/download/v0.8.2/buildx-v0.8.2.linux-amd64  #当前版本最新为v0.8.2
# mv buildx-v0.8.2.linux-amd64 docker-buildx
# chmod +x docker-buildx

2)install buildx插件

# docker buildx install         #install buildx
# docker buildx create --use --name multiarch-builder  #创建自己的构建容器
# docker buildx inspect multiarch-builder --bootstrap  #初始化构建容器,这个步骤会从外网拉取`moby/buildkit`镜像,即使本地存在该镜像,也会从外网去拉

执行过程如下图

2.3 使用buildx构建arm64系统镜像

1、下载arm64系统的minio可执行文件,并编写Dockerfile(==注意FROM的基础镜像也要用arm64的==)

FROM centos@sha256:43964203bf5d7fe38c6fca6166ac89e4c095e2b0c0a28f6c7c678a1348ddc7fa 
RUN set -ex \\
  && mkdir -p /data \\
  && mkdir -p /minio
COPY minio /minio/
RUN chmod 777 /minio/minio
EXPOSE 9000 9001
CMD ["/minio/minio","server","/data","--console-address",":9001"]

2、使用“--platform=linux/arm64”参数,指定构建镜像的系统平台

docker buildx build . --platform=linux/arm64 -t minio:test --load

==注意:命令末尾必须加上 --load或--push。--load可以将build的镜像加载到服务器本地;--push将build的镜像推送到默认仓库。==
如果不加,会报如下错误,且docker image看不到刚刚构建的镜像:

WARNING: No output specified for docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
警告:没有为 docker 容器驱动程序指定输出。生成结果将仅保留在生成缓存中。将结果映像推送到注册表使用 --push 或将映像加载到 docker 使用 --load

3 镜像部署验证

  1. 查看镜像的“Architecture”字段是否为arm64

    docker inspect minio:test

  2. 镜像架构如为arm64,则将x86_64服务器构建出来的镜像minio:test远程scp到aarch64服务器test104,测试部署

    docker save minio:test>minio.tar.gz
    scp minio.tar.gz root@10.0.0.4:/tmp/
  3. 在aarch64服务器test104上加载镜像并部署minio

    docker load</tmp/minio.tar.gz
  4. 在test104服务器启动容器

    docker run -d --privileged --restart=unless-stopped \\
    -p 9001:9000 \\
    -p 9002:9001 \\
    --name minio \\
    -v /tmp/data:/data \\
    -e "MINIO_ROOT_USER=admin" \\
    -e "MINIO_ROOT_PASSWORD=myadmin@123" \\
    minio:test
  5. 浏览器访问验证

::: hljs-center

:::

以上是关于如何跨系统构建docker镜像?的主要内容,如果未能解决你的问题,请参考以下文章

Docker compose v3版本构建跨主机容器编排构建wordpress集群

Docker compose v3版本构建跨主机容器编排构建wordpress集群

Docker 开启 buildx 多CPU架构镜像制作

转 dockerfile 介绍 及 编写

如何查看dockerhub的所有镜像

jenkins构建docker镜像