项目场景:
mac m1系统
Docker Engine v20.10.20
k8s 管理
阿里云镜像仓库
springboot
问题描述
正常情况下,我们使用docker构建镜像,发布到镜像仓库,k8s拉取镜像正常启动
但是由于我的电脑是M1系统,就出现了一些小问题,首先进行构建命令:
docker打包镜像命令:
docker build -t imgaename:v1.0 .
注意最后有个点,默认使用 “上下文目录(Context)下的名为Dockerfile 的文件作为 Dockerfile”
然后push到阿里云,一切正常,这个时候使用k8s拉取镜像进行启动出现报错
exec /usr/bin/java: exec format error
原因分析:
这是因为系统架构的问题,mac M1系统是使用的arm架构,而我们服务器使用的是linux/amd架构,所以我们在打包时需要声明架构
在之前的版本中构建多种系统架构支持的 Docker 镜像,要想使用统一的名字必须使用 $ docker manifest 命令。
而在 Docker 19.03+ 版本中可以使用 $ docker buildx build
命令使用 BuildKit
构建镜像。
该命令支持 --platform
参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。
而我下载的是v20.10.20所以是自带buildx
提示:
1、docker镜像有多种架构版本,而当我们执行docker pull命令时会根据当前服务器的架构自动拉取对应架构版本所以我们可以直接生成多版本,pull时正常使用即可
2、linux下载的docker也是没有buildx的,需要安装buildx,这里我是mac下载的desktop所以是自带的
解决方案:
由于 Docker 默认的
builder
实例不支持同时指定多个--platform
,我们必须首先创建一个新的builder
实例。
使用 docker buildx ls 查看
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
default error
desktop-linux docker
desktop-linux desktop-linux running 20.10.20 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
创建新的builder实例并使用
docker buildx create --use --name=mybuilder-cn --driver docker-container --driver-opt image=dockerpracticesig/buildkit:master
在使用 docker buildx ls 查看
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder-cn * docker-container
mybuilder-cn0 desktop-linux running 1a7c480 linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default error
desktop-linux docker
desktop-linux desktop-linux running 20.10.20 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
当然步骤也可以分开,直接创建在使用,如下:
docker buildx create --name mybuilder --driver docker-container
#使用mybuilder
docker buildx use mybuilder
docker构建镜像
docker buildx build --platform linux/arm,linux/arm64,linux/amd64 -t myusername/imagename . --load
这时查看镜像生成成功
当然了,我这里不需要那么多端,只需要linux/amd64即可,所以不用设置多平台构建,那么也可以不用创建builder实例,直接使用默认的
docker buildx build --platform linux/amd64 -t imagename:v1.0 . --load
--load 表示生成镜像在本地加载
--push表示生成镜像并推送到仓库
将镜像推送到云端检查
//登陆docker,并输入密码
docker login --username=username registry.cn-hangzhou.aliyuncs.com
//将docker本地构建的镜像打上标记
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/repostry/imagename:[镜像版本号]
//进行推送
docker push registry.cn-hangzhou.aliyuncs.com/repostry/imagename:[镜像版本号]
到此查看k8s拉取最新项目,启动,ok
总结:
docker构建镜像也要区分当前服务平台与使用镜像的平台架构是否一致,如果一致则正常使用,如果不一致要考虑使用buildx构建不同平台版本问题