docker多架构镜像
内核升级
wget --no-check-certificate https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-5.4.278-1.el7.elrepo.x86_64.rpm
wget --no-check-certificate https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-devel-5.4.278-1.el7.elrepo.x86_64.rpm
wget --no-check-certificate https://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-headers-5.4.278-1.el7.elrepo.x86_64.rpm
yum localinstall -y /tmp/kernel-upgrade/*.rpm
rpm -qa | grep kernel
awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot

docker 安装插件
yum install -y docker-buildx-plugin
docker buildx version
安装qemu模拟器
在amd64主机上构建arm64镜像,必须先安装QEMU模拟器来支持跨架构指令翻译,否则BuildKit无法交叉编译arm64版本镜像
docker run --privileged --rm tonistiigi/binfmt --install all


安装构建器
docker buildx rm multicharch-builder
创建构建器的配置文件
cat > /home/admin/buildkitd.toml << 'EOF'
[registry."192.168.30.113:80"]
http = true
insecure = true
EOF
启动并初始化构建器,自动加载QEMU跨架构仿真器
docker buildx create \
--name multicharch-builder \
--driver docker-container \
--driver-opt "network=host" \
--config /home/admin/buildkitd.toml \
--platform linux/amd64,linux/arm64 \
--bootstrap
查看构建器
docker buildx ls

构建arm架构镜像
通过构建器和QEMU模拟器来构建对应架构的镜像
docker buildx build --builder multicharch-builder --platform linux/amd64 -o type=image,oci-mediatypes=false,push=true --provenance=false --sbom=false -t 192.168.30.113/soc-base-test/main_x86:latest .
后续如果需要构建多架构镜像
如果后续需要同时支持amd64和arm64两种架构,只需要把构建命令里的--platform linux/arm64改成--platform linux/amd64,linux/arm64即可,Buildx会自动构建两个架构的镜像并生成兼容的manifest列表,不同架构的机器拉取时会自动匹配对应版本

镜像迁移验证操作
docker pull 192.168.30.113/soc-base-test/main_arch:latest 把镜像拉取到本地
docker save -o main_arch.tar 192.168.30.113/soc-base-test/main_arch
gzip -9 main_arch.tar
验证镜像架构
# 删除本地旧镜像
docker rmi -f 192.168.30.113/soc-base-test/main_arch:latest
# 重新拉取新镜像
docker pull 192.168.30.113/soc-base-test/main_arch:latest
# 验证镜像架构
docker inspect 192.168.30.113/soc-base-test/main_arch:latest | grep Architecture
在指定的容器中查看服务
docker run -ti 8e9557139197 /bin/sh
docker run --rm -it --entrypoint=/bin/sh 8e9557139197
构建器迁移主机
# 编辑daemon.json
cat > /etc/docker/daemon.json <<'EOF'
{
"insecure-registries": ["192.168.30.113","192.168.30.113:80"]
}
EOF
# 重启Docker
systemctl daemon-reload
systemctl restart docker
# 先停掉并删除旧的builder
docker buildx rm multicharch-builder
# 确认已经删除
docker buildx ls
cat > /home/admin/buildkitd.toml <<'EOF'
[registry."192.168.30.113"]
http = true
insecure = true
tls = false
[registry."192.168.30.113:80"]
http = true
insecure = true
tls = false
EOF
重新创建buildx builder,确保配置被加载
docker buildx create \
--name multicharch-builder \
--driver docker-container \
--driver-opt "network=host" \
--config /home/admin/buildkitd.toml \
--platform linux/amd64,linux/arm64 \
--bootstrap
验证builder是否能正常访问私有仓库
docker buildx build \
--builder multicharch-builder \
--platform linux/arm64 \
-t test-pull:test \
--load \
- <<EOF
FROM 192.168.30.113/library/jdk_arch:1.8
RUN echo "success"
EOF

集成到流水线pipeline

CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )
cd $CURDIR
if [ $# -eq 1 ]; then
arch="arm64"
tag="_arm64"
else
arch="amd64"
tag=""
fi
docker buildx build \
--builder multicharch-builder \
--platform linux/$arch \
-o type=image,oci-mediatypes=false,push=true --provenance=false --sbom=false \
-t 192.168.30.113/soc-base-test/main$tag \
--push \
.
ARG TARGETARCH FROM 192.168.30.113/library/java:latest AS amd64-base # x86 专属操作可以提前写在这里 FROM 192.168.30.113/library/jdk_arch:1.8 AS arm64-base # ARM 专属操作可以提前写在这里 FROM ${TARGETARCH}-base AS final ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone WORKDIR / VOLUME /tmp ADD main-prod.jar main-prod.jar ADD license.json license.json ADD msyhbd.ttc /usr/share/fonts/win/msyhbd.ttc ADD msyhl.ttc /usr/share/fonts/win/msyhl.ttc ADD msyh.ttc /usr/share/fonts/win/msyh.ttc ADD ca.crt ca.crt RUN bash -c 'touch /main-prod.jar' ENTRYPOINT ["java","-Dspring.config.location=/application-prod.yml","-Djava.security.egd=file:/dev/./urandom","-jar","/main-prod.jar","/license.json"]
ARG TARGETARCH # 定义两个架构的基础镜像阶段 FROM 192.168.30.113/library/java-23 AS amd64-base # x86 专属操作可以提前写在这里 RUN rm -fr /usr/bin/java && ln -s /usr/jdk-23.0.1/bin/java /usr/bin/java FROM 192.168.30.113/library/jdk_arch:23 AS arm64-base # ARM 专属操作可以提前写在这里 RUN echo "ARM 架构专属操作" # 必须加这一行:根据当前构建架构自动选择对应基础镜像 FROM ${TARGETARCH}-base AS final # 两个架构通用的配置 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone VOLUME /tmp WORKDIR / ADD mcp-server-0.0.1-SNAPSHOT.jar mcp-server-0.0.1-SNAPSHOT.jar ADD license.json license.json ADD ca.crt ca.crt RUN bash -c 'touch /mcp-server-0.0.1-SNAPSHOT.jar' # 这里不用再写if判断java路径了,因为两个基础镜像里我们已经提前配置好软链接 ENTRYPOINT ["java","-Dspring.config.location=/application-prod.yml","-Djava.security.egd=file:/dev/./urandom","-jar","/mcp-server-0.0.1-SNAPSHOT.jar","--license.path=/license.json"]
构建x86的镜像并验证 sh build.sh docker pull 192.168.30.113/soc-base-test/main
构建arm的镜像并验证 sh build.sh arm64 docker pull 192.168.30.113/soc-base-test/main_arm64

双架构镜像构建结束
定制flink arm64架构镜像
wget /https://github.com/tianon/gosu/releases/download/1.17/gosu-arm64
wget https://mirrors.aliyun.com/centos-altarch/7/os/aarch64/Packages/gettext-0.19.8.1-3.el7.aarch64.rpm

ARG TARGETARCH FROM 192.168.30.113/library/flink:1.17.1-java8-base AS amd64-base # x86 专属操作可以提前写在这里 FROM 192.168.30.113/library/jdk_arch:1.8 AS arm64-base # ARM 专属操作可以提前写在这里 RUN rm -fr /opt/java/openjdk/ COPY openjdk /opt/java/openjdk/ ADD flink17.tar /opt/ ENV FLINK_HOME=/opt/flink RUN rm -fr /opt/flink/upload-jar COPY gosu /usr/local/bin/ COPY gettext-0.19.8.1-3.el7.aarch64.rpm /opt/flink/ # 从rpm包中精准提取envsubst二进制,无需安装任何依赖 RUN rpm2cpio /opt/flink/gettext-0.19.8.1-3.el7.aarch64.rpm | cpio -idmv ./usr/bin/envsubst && \ mv ./usr/bin/envsubst /usr/local/bin/ && \ chmod +x /usr/local/bin/envsubst && \ rm -rf ./usr /opt/flink/gettext-*.rpm # 清理临时文件缩小镜像体积 FROM ${TARGETARCH}-base AS final WORKDIR / ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone # Configure container RUN set -ex; \ CONF_FILE="$FLINK_HOME/conf/flink-conf.yaml"; \ mkdir $FLINK_HOME/upload-jar; mkdir -p /opt/sa-conf; \ sed -i '$a web.upload.dir: $FLINK_HOME/upload-jar' "$CONF_FILE"; ADD analysis-*.jar /opt/flink/lib/ ADD sa-conf/* /opt/sa-conf/ COPY upload-jar /opt/flink/upload-jar/ COPY docker-entrypoint.sh / COPY yq /usr/bin/ ENTRYPOINT ["/docker-entrypoint.sh"] EXPOSE 6123 8081 CMD ["help"]
CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )
cd $CURDIR
if [ $# -eq 1 ]; then
arch="arm64"
tag="_arm64"
else
arch="amd64"
tag=""
fi
docker buildx build \
--builder multicharch-builder \
--platform linux/$arch \
-o type=image,oci-mediatypes=false,push=true --provenance=false --sbom=false \
-t 192.168.30.113/soc-base-test/flink:1.17.1-java8$tag \
--push \
.
docker run -ti 192.168.30.113/soc-base-test/flink:1.17.1-java8_arm64 /bin/sh
定制kibana arm64架构镜像

# 基于ARM64版CentOS7作为基础镜像 FROM arm64v8/centos:7 ADD ca.crt / ADD kibana-7.8.0-linux-x86_64.tar.gz /usr/share/ # 配置Kibana基础参数 WORKDIR /usr/share/kibana-7.8.0-linux-x86_64 ADD node-v10.21.0-linux-arm64.tar.xz /usr/share/kibana-7.8.0-linux-x86_64/ RUN rm -fr node && mv node-v10.21.0-linux-arm64 node RUN chmod +x ./bin/* # 暴露默认端口 EXPOSE 5601 # 启动命令 CMD ["./bin/kibana","--allow-root"]
docker build -t 192.168.30.113/library/kibana:7.8.1_arm64 .
/usr/share/kibana-7.8.0-linux-x86_64/config/kibana.yml 通过configmap 的挂载方式覆盖掉容器里原来的配置文件
docker run -it 192.168.30.113/library/kibana:7.8.1_arm64

构建并测试启动容器
定制Python3 jdk镜像
ARG TARGETARCH FROM 192.168.30.113/library/java:latest AS amd64-base # x86 专属操作可以提前写在这里 ADD python3.9.tar_x86 /usr/local/ FROM 192.168.30.113/library/jdk8-python3_arm64 AS arm64-base # ARM 专属操作可以提前写在这里 FROM ${TARGETARCH}-base AS final WORKDIR / ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone VOLUME /tmp ADD pluginRunner-1.0.0.jar pluginRunner-1.0.0.jar ADD main.py main.py ADD license.json license.json ADD ca.crt ca.crt RUN bash -c 'touch /pluginRunner-1.0.0.jar' ENTRYPOINT ["java","-Dspring.config.location=/application-prod.yml","-Djava.security.egd=file:/dev/./urandom","-jar","/pluginRunner-1.0.0.jar","/license.json"]

定制结束启动成功
本文来自博客园,作者:不懂123,转载请注明原文链接:https://www.cnblogs.com/yxh168/p/22578849
浙公网安备 33010602011771号