
mkaczanowski/packer-builder-arm
该插件用于构建或扩展ARM系统镜像,支持以下三种模式:
插件模拟标准镜像创建流程,包括:
虚拟化通过binfmt_misc内核功能和qemu实现。
由于不同硬件类型的设置差异较大,每个"开发板"都提供了示例配置。目前支持以下开发板(欢迎添加更多):
适用于需要为ARM设备构建定制系统镜像的开发者,尤其适合:
bashgit clone [***] cd packer-builder-arm go mod download go build sudo packer build boards/odroid-u3/archlinuxarm.json
此方法主要面向macOS用户(无法原生使用qemu-user-static、loop挂载Linux文件系统或安装Linux工具)或不想在本地配置packer及相关工具的Linux用户。
容器为多架构容器(linux/amd64或linux/arm64),可在Intel x86_64、Apple M1及Linux x86_64/aarch64系统上使用。
注意:在Mac上,不要先运行
go build .(会生成darwin二进制文件),然后执行下面的docker run命令,这会导致错误error initializing builder 'arm': fork/exec /build/packer-builder-arm: exec format error(Docker内的linux packer进程无法加载darwin二进制文件)。通过rm -r packer-*删除本地二进制文件,仅使用容器内置的二进制文件。
拉取最新版本容器以确保不使用旧缓存版本:
bashdocker pull mkaczanowski/packer-builder-arm:latest
构建开发板镜像:
bashdocker run --rm --privileged -v /dev:/dev -v ${PWD}:/build mkaczanowski/packer-builder-arm:latest build boards/raspberry-pi/raspbian.json
构建时添加额外系统包(如bmap-tools、zstd):
bashdocker run --rm --privileged -v /dev:/dev -v ${PWD}:/build mkaczanowski/packer-builder-arm:latest build boards/raspberry-pi/raspbian.json -extra-system-packages=bmap-tools,zstd
注意:上述命令中的
latest可替换为特定版本(如1.0.3)以使用指定版本容器。
本地构建容器:
bashdocker build -t packer-builder-arm -f docker/Dockerfile .
通过本地构建的容器运行packer:
bashdocker run --rm --privileged -v /dev:/dev -v ${PWD}:/build packer-builder-arm build boards/raspberry-pi/raspbian.json
本地构建需安装以下工具:
sfdisk / sgdisk(分区工具)e2fsprogs(文件系统工具)parted(调整分区大小时需要)resize2fs(调整分区大小时需要)qemu-img(调整分区大小时需要)配置分为三部分:远程文件配置、镜像配置和QEMU配置。
描述用作基础镜像或根文件系统归档的远程文件(取决于image_build_method):
json"file_urls": ["[***]"], "file_checksum_url": "[***]", "file_checksum_type": "md5", "file_unarchive_cmd": ["bsdtar", "-xpf", "$ARCHIVE_PATH", "-C", "$MOUNTPOINT"], "file_target_extension": "tar.gz"
file_urls的下载通过github.com/hashicorp/go-getter实现,支持本地文件、http(s)等多种协议(详见支持的协议)。如需使用其他协议,可在运行packer前通过curl、wget等工具下载文件,然后在file_urls中引用本地文件。
file_unarchive_cmd为可选配置,当标准golang归档器无法处理归档格式时使用。
可通过定义file_target_extension使用原始镜像格式(.img或.iso)。
基础镜像描述(大小、分区、挂载点等):
json"image_build_method": "new", "image_path": "odroid-xu4.img", "image_size": "2G", "image_type": "dos", "image_partitions": [ { "name": "root", "type": "8300", "start_sector": "4096", "filesystem": "ext4", "size": "0", "mountpoint": "/" } ]
插件不会尝试检测镜像分区(因差异较大),完全依赖image_partitions配置,即使使用reuse模式也需设置此项。
QEMU相关配置:
json"qemu_binary_source_path": "/usr/bin/qemu-arm-static", "qemu_binary_destination_path": "/usr/bin/qemu-arm-static"
可通过QEMU_CPU变量定义要模拟的ARM指令集(默认为qemu-arm-static的armv7l)。要切换到armv6l(可通过uname -m验证),可通过以下方式运行packer:
QEMU_CPU=arm1176 packer build ...docker run -e QEMU_CPU=arm1176 ...要在chroot环境中执行命令,需使用chroot通信器:
json"provisioners": [ { "type": "shell", "inline": [ "pacman-key --init", "pacman-key --populate archlinuxarm" ] } ]
插件不会调整基础镜像的分区大小,但可通过systemd服务在启动时扩展分区。此处提供了树莓派根文件系统扩展至SD卡全部空间的实际示例。
可使用自定义后处理器(dd的封装,包含一些安全检查)将镜像写入设备:
json"post-processors": [ { "type": "flasher", "device": "/dev/sdX", "block_size": "4096", "interactive": true } ]
虽然.img格式适用于大多数情况,但有时可能需要rootfs用于其他目的(如导出到Docker)。通过以下方式生成rootfs归档而非镜像:
json"image_path": "odroid-xu4.img" // 生成镜像 "image_path": "odroid-xu4.img.tar.gz" // 生成rootfs归档
目前仅支持使用resize2fs扩展单个ext{2,3,4}分区。这是一个常见需求:使用现有镜像并扩展主分区以容纳 provisioner 步骤中安装的软件包。
要调整分区大小,需将image_build_method设置为resize模式,并将目标分区大小设为0:
json"builders": [ { "type": "arm", "image_build_method": "resize", "image_partitions": [ { "name": "boot", ... }, { "name": "root", "size": "0", ... } ], ... } ]
完整示例:
boards/raspberry-pi/raspbian-resize.jsonboards/beaglebone-black/ubuntu.pkr.hcl通过artifice插件可将rootfs归档传递给Docker插件:
json"post-processors": [ [ { "type": "artifice", "files": ["rootfs.tar.gz"] }, { "type": "docker-import", "repository": "mkaczanowski/archlinuxarm", "tag": "latest" } ], ... ]
以下是使用GitHub Actions将镜像推送到Docker镜像仓库的示例:
bashcat .github/workflows/archlinuxarm-armv7-docker.yml
更多示例请查看:
bashtree boards/
仓库还包含一些ARM常用脚本,如首次启动时调整分区大小或更复杂的provision脚本:
bashtree scripts/
Packer provision脚本的丰富资源可参考GitHub Actions runner images仓库。
许多报告的问题是平台/OS特定的。如遇到问题,首先应确认:
是我的设置有问题?还是确实存在问题?
建议在VM中重现错误以排查:
bashcd packer-builder-arm vagrant up vagrant provision
注意:需要安装disksize插件(如未安装)
vagrant plugin install vagrant-disksize

manifest unknown 错误
TLS 证书验证失败
DNS 解析超时
410 错误:版本过低
402 错误:流量耗尽
身份认证失败错误
429 限流错误
凭证保存错误
来自真实用户的反馈,见证轩辕镜像的优质服务