当前位置: 首页 > news >正文

Docker 构建 ARM64 镜像并导出二进制文件 — 完整操作指南

Docker 构建 ARM64 镜像并导出二进制文件 — 完整操作指南

基于hello.c源码,使用 Docker 交叉编译生成 ARM64 平台可执行文件


目录

  1. 环境信息
  2. 源码分析
  3. 创建 Dockerfile
  4. 构建 ARM64 镜像
  5. 验证镜像
  6. 导出镜像
  7. 从镜像中提取二进制文件
  8. 验证提取的二进制文件
  9. 完整流程图
  10. 常见问题

1. 环境信息

项目
宿主机系统CentOS Stream 10 (x86_64)
Docker 版本已安装
QEMU 版本7.2.0 (已注册 binfmt)
工作目录/home/jp/下载/prj_test

当前文件

prj_test/ ├── hello.c # 源码 (109 bytes) ├── hello # x86_64 编译产物 (16KB) ├── Dockerfile # 已有 Dockerfile └── ...

2. 源码分析

// hello.c#include<stdio.h>#include<stdlib.h>intmain(){printf("hello world by centOS-10\n");return0;}
  • 简单的 C 程序,输出一行字符串
  • 使用标准库stdio.hstdlib.h
  • 编译需要gcc和 C 标准库

已有二进制对比

文件架构链接方式大小
hellox86_64动态链接16KB
hello-arm64-binARM aarch64静态链接136KB

3. 创建 Dockerfile

3.1 查看现有 Dockerfile

catDockerfile

3.2 创建新的 ARM64 构建 Dockerfile

# Dockerfile.arm64 # ============================================================ # 阶段 1:使用 ARM64 基础镜像进行交叉编译 # ============================================================ FROM arm64v8/gcc:12 AS builder # 安装依赖(如有需要) RUN apt-get update && \ apt-get install -y --no-install-recommends \ libc6-dev \ && rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /build # 复制源码 COPY hello.c . # 编译(静态链接,方便在任何 ARM64 设备运行) RUN gcc -static -O2 -o hello hello.c && \ strip hello && \ echo "编译完成" && \ file hello # ============================================================ # 阶段 2:最小化运行镜像 # ============================================================ FROM arm64v8/debian:bookworm-slim # 安装运行时依赖 RUN apt-get update && \ apt-get install -y --no-install-recommends \ libc6 \ && rm -rf /var/lib/apt/lists/* # 设置元数据 LABEL maintainer="jp" LABEL version="1.0" LABEL description="hello.c ARM64 构建镜像" LABEL platform="linux/arm64" # 设置工作目录 WORKDIR /app # 从构建阶段复制二进制文件 COPY --from=builder /build/hello . # 设置可执行权限 RUN chmod +x hello # 默认运行 CMD ["./hello"]

4. 构建 ARM64 镜像

4.1 方式一:使用 docker buildx(推荐)

# 注册 QEMU 多架构支持(如果还没有)dockerrun--rm--privilegedmultiarch/qemu-user-static--reset-pyes# 构建 ARM64 镜像dockerbuildx build\--platformlinux/arm64\-thello-arm64:v1.0\-fDockerfile.arm64\--load\.

4.2 方式二:使用 docker build(传统方式)

# 直接构建(QEMU binfmt 已注册,会自动使用 QEMU 编译)dockerbuild\-thello-arm64:v1.0\-fDockerfile.arm64\.

4.3 构建过程详解

构建流程: ┌─────────────────────────────────────────────────────────────┐ │ 1. docker buildx build --platform linux/arm64 │ │ │ │ 2. 拉取 arm64v8/gcc:12 基础镜像 │ │ └── 自动通过 QEMU 模拟 ARM64 环境 │ │ │ │ 3. 在 QEMU 模拟的 ARM64 环境中执行: │ │ ├── apt-get update && apt-get install │ │ ├── gcc -static -o hello hello.c ← ARM64 交叉编译 │ │ └── strip hello │ │ │ │ 4. 拉取 arm64v8/debian:bookworm-slim │ │ │ │ 5. 复制编译产物到运行镜像 │ │ │ │ 6. 标记镜像:hello-arm64:v1.0 │ └─────────────────────────────────────────────────────────────┘

5. 验证镜像

5.1 查看镜像

# 列出镜像dockerimages|grephello# 预期输出:# hello-arm64 v1.0 abc123456789 10 seconds ago 120MB

5.2 查看镜像架构

# 检查镜像架构dockerinspect hello-arm64:v1.0|grepArchitecture# 预期输出:# "Architecture": "arm64"

5.3 运行测试

# 直接运行(QEMU binfmt 会自动处理 ARM64 二进制)dockerrun--rmhello-arm64:v1.0# 预期输出:# hello world by centOS-10

5.4 进入容器查看

# 交互式进入容器dockerrun--rm-ithello-arm64:v1.0bash# 在容器内查看二进制信息filehello# 输出:hello: ELF 64-bit LSB executable, ARM aarch64...# 退出容器exit

6. 导出镜像

6.1 导出为 tar 文件

# 导出镜像为 tar 文件dockersave-ohello-arm64.tar hello-arm64:v1.0# 查看导出文件ls-lhhello-arm64.tar# 预期输出:# -rw------- 1 jp jp 120M 7月 10 14:30 hello-arm64.tar

6.2 压缩导出(可选,减小体积)

# 导出并压缩dockersave hello-arm64:v1.0|gzip>hello-arm64.tar.gz# 查看压缩后大小ls-lhhello-arm64.tar.gz# 预期输出:# -rw-r--r-- 1 jp jp 50M 7月 10 14:32 hello-arm64.tar.gz

6.3 验证导出内容

# 查看 tar 包结构tartf hello-arm64.tar|head-20# 预期输出(OCI 格式):# blobs/# blobs/sha256/# blobs/sha256/xxxxx...# index.json# manifest.json# oci-layout

7. 从镜像中提取二进制文件

7.1 方式一:使用 docker cp(推荐)

# 创建临时容器(不启动)dockercreate--namehello-tmp hello-arm64:v1.0# 从容器中拷贝二进制文件dockercphello-tmp:/app/hello ./hello-arm64# 清理临时容器dockerrmhello-tmp# 验证文件ls-lhhello-arm64

7.2 方式二:从 tar 包手动提取

# 步骤 1:解压 OCI 镜像mkdir-p/tmp/hello-ocitarxf hello-arm64.tar-C/tmp/hello-oci# 步骤 2:查看 manifest 获取层信息cat/tmp/hello-oci/manifest.json|python3-mjson.tool# 步骤 3:找到层文件(通常是 blobs/sha256/ 下的 .gz 文件)ls-la/tmp/hello-oci/blobs/sha256/# 步骤 4:解压层文件(层是 gzip 压缩的 tar)mkdir-p/tmp/hello-rootfstarxzf /tmp/hello-oci/blobs/sha256/*.gz-C/tmp/hello-rootfs# 步骤 5:查找并复制二进制文件find/tmp/hello-rootfs-name"hello"-typef-execcp{}./hello-arm64\;chmod+x ./hello-arm64# 步骤 6:清理临时文件rm-rf/tmp/hello-oci /tmp/hello-rootfs

7.3 方式三:一行命令提取

# 一行命令完成提取tarxf hello-arm64.tar-C/tmp&&\tarxzf /tmp/blobs/sha256/*.gz-C/tmp&&\cp/tmp/app/hello ./hello-arm64&&\chmod+x ./hello-arm64&&\rm-rf/tmp/blobs /tmp/index.json /tmp/manifest.json /tmp/oci-layout

8. 验证提取的二进制文件

8.1 检查文件架构

# 检查二进制架构filehello-arm64# 预期输出:# hello-arm64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV),# statically linked, BuildID[sha1]=xxx, for GNU/Linux 3.2.0, stripped

8.2 检查文件大小

# 查看文件信息ls-lhhello-arm64# 预期输出:# -rwxr-xr-x 1 jp jp 136K 7月 10 14:35 hello-arm64

8.3 在 ARM64 设备上运行

# 直接在 ARM64 设备上运行./hello-arm64# 预期输出:# hello world by centOS-10

8.4 在 x86 主机上使用 QEMU 测试

# 使用 QEMU 运行(如果 binfmt 未注册)qemu-aarch64-static ./hello-arm64# 预期输出:# hello world by centOS-10

9. 完整流程图

┌─────────────────────────────────────────────────────────────────┐ │ Docker 构建 ARM64 镜像流程 │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ hello.c │───>│ Dockerfile │───>│ Docker Image │ │ │ │ (源码) │ │ (构建配置) │ │ (ARM64) │ │ │ └──────────┘ └──────────────┘ └──────┬───────┘ │ │ │ │ │ ┌────────────────────┼────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │ │ │ docker save │ │ docker cp │ │ docker │ │ │ │ 导出为 tar │ │ 提取二进制 │ │ run │ │ │ └──────┬───────┘ └──────┬───────┘ └────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ hello-arm64 │ │ hello-arm64 │ │ │ │ .tar │ │ (二进制文件) │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ tar 解压 │ │ │ │ 提取二进制 │ │ │ └──────┬───────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ hello-arm64 │ │ │ │ (可执行文件) │ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘

10. 常见问题

Q1: 构建时提示 “exec format error”

# 原因:QEMU binfmt 未注册# 解决:注册 QEMU 多架构支持dockerrun--rm--privilegedmultiarch/qemu-user-static--reset-pyes

Q2: 构建速度慢

# 原因:QEMU 模拟 ARM64 效率较低# 解决:使用 BuildKit 缓存DOCKER_BUILDKIT=1dockerbuildx build\--platformlinux/arm64\-thello-arm64:v1.0\-fDockerfile.arm64\--load\.# 或使用远程 builder(需要配置)dockerbuildx create--namemybuilder--driverdocker-container--usedockerbuildx build--platformlinux/arm64-thello-arm64:v1.0--load.

Q3: 导出的 tar 包太大

# 方式 1:压缩导出dockersave hello-arm64:v1.0|gzip>hello-arm64.tar.gz# 方式 2:优化 Dockerfile,使用更小的基础镜像# 将 arm64v8/debian:bookworm-slim 改为 arm64v8/alpine:3.18

Q4: 提取的二进制无法运行

# 检查架构是否正确filehello-arm64# 如果是动态链接,需要目标设备有对应库# 解决:使用静态编译(Dockerfile 中已使用 -static)

Q5: 如何推送到私有仓库

# 打标签dockertag hello-arm64:v1.0 your-registry.com/hello-arm64:v1.0# 推送dockerpush your-registry.com/hello-arm64:v1.0# 其他设备拉取dockerpull your-registry.com/hello-arm64:v1.0

11. 实际执行记录

以下为在 CentOS Stream 10 (x86_64) 上的实际操作记录

11.1 构建镜像

$dockerbuildx build--platformlinux/arm64-thello-arm64:v1.0-fDockerfile.arm64--load.

构建结果

  • 编译阶段:gcc -static -O2 -o hello hello.c成功
  • 二进制验证:hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, stripped
  • 镜像大小:28.4MB

11.2 验证镜像

$dockerimages|grephello-arm64 hello-arm64:latest 8dafc3dcbf5e 170kB hello-arm64:v1.0 783e36dfc2f428.4MB $dockerinspect hello-arm64:v1.0|grepArchitecture"Architecture":"arm64"$dockerrun--rmhello-arm64:v1.0 hello world by centOS-10

11.3 导出镜像

$dockersave-ohello-arm64-v1.0.tar hello-arm64:v1.0 $ls-lhhello-arm64-v1.0.tar -rw-------1jp jp 28M71011:42 hello-arm64-v1.0.tar

11.4 提取二进制文件

$dockercreate--namehello-tmp hello-arm64:v1.0 $dockercphello-tmp:/app/hello ./hello-arm64-v1.0 $dockerrmhello-tmp $file./hello-arm64-v1.0 ./hello-arm64-v1.0: ELF64-bit LSB executable, ARM aarch64, version1(GNU/Linux), statically linked,forGNU/Linux3.7.0, stripped $ls-lh./hello-arm64-v1.0 -rwxr-xr-x1jp jp 586K71011:41 ./hello-arm64-v1.0

11.5 测试运行

$ qemu-aarch64-static ./hello-arm64-v1.0 hello world by centOS-10

11.6 产出文件清单

文件类型架构大小说明
hello-arm64-v1.0.tarDocker 镜像arm6428MB可通过docker load导入
hello-arm64-v1.0ELF 可执行文件ARM aarch64586KB静态链接,可直接在 ARM64 设备运行

附录:快速命令参考

# ===== 构建 =====dockerbuildx build--platformlinux/arm64-thello-arm64:v1.0-fDockerfile.arm64--load.# ===== 运行 =====dockerrun--rmhello-arm64:v1.0# ===== 导出 =====dockersave-ohello-arm64.tar hello-arm64:v1.0# ===== 提取二进制(方式一) =====dockercreate--nametmp hello-arm64:v1.0dockercptmp:/app/hello ./hello-arm64dockerrmtmp# ===== 提取二进制(方式二) =====tarxf hello-arm64.tar-C/tmptarxzf /tmp/blobs/sha256/*.gz-C/tmpcp/tmp/app/hello ./hello-arm64# ===== 验证 =====filehello-arm64 ./hello-arm64
http://www.jsqmd.com/news/1167228/

相关文章:

  • Flutter Android 无线调试No supported devices connected
  • ChatGPT-Image2图像生成实战:从免费使用到工作流搭建
  • 终极游戏库管理指南:5分钟掌握Playnite开源游戏管理器
  • MidiEditor:开源MIDI编辑器的完整功能架构解析
  • 性能对比分析:NV-Raw2insights-MRI在CMRxRecon挑战赛中的优异表现
  • 无锡2026全屋定制爱格可丽芙双授权品牌选购宝典 - 设计本
  • Llama-3.1-8B-Instruct-FP8-KV-Quark-test性能优化:KV缓存量化实战指南
  • 【ChatGPT JSON工程化实战】:从Prompt设计→Schema约束→反序列化熔断,构建零崩溃JSON流水线(含GitHub Star 4.2k的开源工具链)
  • SSM框架+MySQL 8.0 网上书店系统:3层架构设计与5大核心模块实现
  • Copilot Chat从入门到精通:3天掌握企业级AI协作工作流,附实测效率提升数据
  • 2026年7月泉州惠普售后专业维修服务中心综合指南|地址电话服务项目维保流程全攻略.txt - 品牌引荐
  • 2026年7月泉州华硕售后本地化服务全景|交通指引气候养护到店全攻略.txt - 品牌引荐
  • 如何在Windows上免费获得苹果级别中文排版体验:PingFangSC字体包完整指南
  • 终极指南:Nintendo Switch Cleaner and Builder 一站式游戏文件管理解决方案
  • LLM 幻觉检测:用输出一致性检查降低业务风险,别让模型在关键场景胡编
  • CANN Runtime日志配置查看
  • DC-DC升压转换器与PIC微控制器的智能电源方案设计
  • Angular SVG圆形进度条自定义主题:5步实现品牌色彩统一
  • 五款热门中央软水机深度测评 - GrowUME
  • 2026年安徽哪所卫校男生可以上-合肥医药卫生学校(原安徽红十字会卫校) - cc江江
  • Gmail接入Gemini API的终极清单,含OAuth2.0动态刷新、速率限制绕行与错误码速查表
  • WeChatMsg:微信聊天记录永久保存与智能分析完全指南
  • 农业机器人市场2034年达374亿美元:3大驱动力与5个商业化挑战
  • 3步搞定黑苹果配置:OpCore-Simplify自动化EFI生成终极指南
  • 2026年北京GEO服务商——最新动态与选型风向标 - 资讯报道
  • 如何为Blender添加3MF格式支持:3D打印工作流的终极解决方案
  • Grouper输出解读:如何识别GPO中的高风险配置(含实战案例)
  • Kiro实战指南:用Opus 4.6实现低成本高精度代码理解与自动化
  • Vue 3 + Three.js r164 项目实战:5步封装可复用3D场景组件(含响应式)
  • 我的硕士期间课题研究:光学相位调控系统