Docker 多平台镜像操作指南
拉取指定平台镜像
manifest是个实验功能,所以需要在docker中进行打开。
开启方法
# 修改配置
vi /etc/docker/daemon.json
# 新增
"experimental": true
# 重新加载服务的配置文件
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 测试manifest是否开启
docker info | grep -i 'experimental'
修改完如下图
拉取指定平台镜像
拉去指定镜像需要查看镜像仓库是否存在需要的平台版本,存在才能正常拉取,如下图:
测试拉取镜像
# 拉取 arm 架构镜像:
docker pull --platform=arm64 nacos/nacos-server:v2.2.3-slim
# 拉取 amd 架构镜像:
docker pull --platform=amd64 nginx:latest
--platform
参数用于拉取指定平台的镜像,是实验性功能,在开启 manifest 功能后出现,可手动指定需要的 CPU 平台镜像。参考:
https://docs.docker.com/engine/reference/commandline/manifest/
利用 qemu-user-static 实现 不同平台 docker 镜像的运行
配置qemu-user-static依赖
方法一:注册可支持的架构解释器
# 运行
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# 执行成功后,会返回类似如下的结果来表明支持的架构解析器
Setting /usr/bin/qemu-alpha-static as binfmt interpreter for alpha
Setting /usr/bin/qemu-arm-static as binfmt interpreter for arm
Setting /usr/bin/qemu-armeb-static as binfmt interpreter for armeb
# 测试
docker run --rm --platform=arm64 docker.guoliangjun.com/library/alpine uname -m
# 返回结果
Unable to find image 'docker.guoliangjun.com/library/alpine:latest' locally
latest: Pulling from library/alpine
6e771e15690e: Pull complete
Digest: sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
Status: Downloaded newer image for docker.guoliangjun.com/library/alpine:latest
aarch64
如果失败,出现错误,请查看内核版本与系统版本,centos7.9的默认内核(3.10.0-1160.71)是不支持的!请使用rocky8+
方法二:下载 qemu-user-static
如果可支持的架构解释器不支持,可使用此方法。
qemu-user-static
下载地址:https://github.com/multiarch/qemu-user-static/releases
比如需要适配arm64
# 下载对应适配器
wget https://github.com/multiarch/qemu-user-static/releases/download/v7.2.0-1/qemu-aarch64-static
chmod +x qemu-aarch64-static
mv qemu-aarch64-static /usr/local/sbin/qemu-aarch64-static
# 检查是否已挂载 binfmt_misc
mount | grep binfmt_misc
# 如果未挂载,手动挂载
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
# 加载 binfmt_misc 模块
sudo modprobe binfmt_misc
测试
docker run --rm --platform=arm64 \
-v /usr/local/sbin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static \
docker.guoliangjun.com/library/alpine uname -m
# 返回结果
aarch64
同理,参试其他cpu架构平台也是一样下载
qemu-xxxx-static
构建不同平台的容器镜像
方法一:基于本地存在qemu-user-static
文件进行构建
- 准备一个
Dockerfile
- 需要将
qemu-aarch64-static
带入到容器内的/usr/bin
目录下才可以实现构建 - 不然会返回
standard_init_linux.go:211: exec user process caused "no such file or directory"
这样的报错
[root@localhost tmp]# ls -l
总用量 10164
-rw-r--r-- 1 root root 582 4月 17 17:37 Dockerfile
-rwxr-xr-x 1 root root 10402960 4月 17 17:37 qemu-aarch64-static
Dockerfile
# docker build --platform arm64 -t reg-hub.gzeport.com/gzeport/jdk/debian-jdk11-arm:20240529 .
FROM debian:stable-slim
MAINTAINER guoliangjun<post@199604.com>
# 设置aarch64环境
COPY ./qemu-aarch64-static /usr/bin/qemu-aarch64-static
# Support Chinese
ENV TIME_ZONE="Asia/Shanghai" \
LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN.UTF-8
# 切换apt源为清华源,并安装vim ping telnet命令
RUN addgroup --gid 2888 gzapps \
&& adduser --uid 2888 --gid 2888 --home /AppHome --disabled-password --gecos --no-create-home gzapps
WORKDIR /AppHome
USER gzapps
构建
# 构建
docker build --platform arm64 -t reg-hub.gzeport.com/gzeport/jdk/debian-jdk11-arm:20240529 .
# 构建完成后
[root@localhost arm-x64]# docker inspect reg-hub.gzeport.com/gzeport/jdk/debian-jdk11-arm:20240529 | grep -i 'architecture'
"Architecture": "arm64",
测试
[root@localhost tmp]# docker run --rm --platform=arm64 \
> -v /usr/local/sbin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static \
> reg-hub.gzeport.com/gzeport/jdk/debian-jdk11-arm:20240529 uname -m
aarch64
过程的图:
方式二:使用buildx编译arm64架构的Docker镜像
因为 Centos 7 的内核太老,使用buildx暂时不支持的
过程自行验证:https://199604.com/3227
使用 docker manifest 对多平台镜像进行合并
Docker manifest
为不同平台构建镜像合并成一个tag的镜像,类似hub那样子,如果使用buildx
编译可忽略。
如果是从hub仓库分批拉回去镜像版本就可以参考合并。
过程自行验证:https://199604.com/3169
合并的shell
#!/bin/bash
# 读取 image.txt 文件中的每一行
for image in $(cat image.txt); do
# 拉取 ARM64 镜像
docker pull --platform="arm64" "docker.guoliangjun.com/$image"
docker tag "docker.guoliangjun.com/$image" "docker.guoliangjun.com/$image-arm64"
docker push "docker.guoliangjun.com/$image-arm64"
docker rmi "docker.guoliangjun.com/$image"
# 拉取 AMD64 镜像
docker pull --platform="amd64" "docker.guoliangjun.com/$image"
docker tag "docker.guoliangjun.com/$image" "docker.guoliangjun.com/$image-amd64"
docker push "docker.guoliangjun.com/$image-amd64"
docker rmi "docker.guoliangjun.com/$image"
# 创建并推送 Docker Manifest
docker manifest create "docker.guoliangjun.com/$image" \
--amend "docker.guoliangjun.com/$image-arm64" \
--amend "docker.guoliangjun.com/$image-amd64"
docker manifest push --purge "docker.guoliangjun.com/$image"
done
提个建议:文章正文看起来还好,代码块儿里的字看起来很虚,几乎走样了,有点影响阅读感
应该是主题模板导致的吧,我有空看看~