Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,40 @@ In order to use the bootstrap tooling, `debootstrap` must be installed. This can
`$ sudo apt install debootstrap`

Additionally when building from a different platform architecture than the target image, i.e. the architecture used to run the debootstrap and docker engine vs the architecture inside the source chroot, the host will again need binfmt-support for the kernel. As the debootstrap process downloads and copies in the qemu static binaries for emulation into the chroot before any execution is done inside the chroot, installing the qemu static binaries onto the host is then not essential.

### Building minimal images using the upstream multiarch images as a base.

Docker's native multi-arch image support is available in 20.04 which includes support for using the host's qemu-user-static and binfmt-misc support to run arm-native images on amd64 transparently.
See https://github.com/docker/for-linux/issues/56 and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=868217
Until our infrastructure is configured to specify platform when building and running cross-platform images we still rely on the osrf/$OS_$ARCH:$CODENAME images.

However, instead of building and maintaining images from scratch we can leverage the default docker images for debian and ubuntu which are now provided for multiple platforms.
Since the native arch information is embedded in the image's metadata a normal docker-run will generate warnings when the platform doesn't match the host platform.
We work around this by exporting and modifying the image's metadata before re-importing it.
I haven't found a more ergonomic way of doing this yet.

The process is as follows

1. Fetch the appropriate base image from Docker Hub
```
docker pull --platform=linux/amd64 ubuntu:jammy
```
2. Using the image ID rather than tag (to prevent overriding the official tag and confusing your system later) export the image as a tar archive and extract it to a temporary workspace
```
docker save 0da0201282b7 > ubuntu-jammy-arm64.tar
mkdir -p tmp/ubuntu-jammy-arm64; tar -C tmp/ubuntu-jammy-arm64 -xf ubuntu-jammy-arm64.tar
```
3. Edit the image metadata to set the architecture to amd64. "variant" is not defined by default for amd64 images.
```
sed -e 's/"architecture":"arm64"/"architecture":"amd64"/' -e 's/,"variant":"v8"//' -i tmp/ubuntu-jammy-arm64/*.json
```
5. Re-tar the image contents and import them into docker.
```
tar -C tmp/ubuntu-jammy-arm64 -cf ubuntu-jammy-arm64.tar .
docker load < ubuntu-jammy-arm64.tar
```
6. Tag and push the image to Docker Hub
```
docker tag 184ec6725d6517ab94e8ee552f357f787eff4dc8ef1e41c8c2de8ab5d606b19c osrf/ubuntu_arm64:jammy
docker push osrf/ubuntu_arm64:jammy
```
Binary file modified qemu-aarch64-static
Binary file not shown.
Binary file modified qemu-arm-static
Binary file not shown.