-
Notifications
You must be signed in to change notification settings - Fork 14
Build ARM64 on AMD64
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install -y docker-ce
sudo usermod -aG docker $USER
Add experimental features:
echo '{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
mkdir -p ~/.docker && echo '{\n "experimental": enabled\n}' | tee ~/.docker/config.json
Restart the Docker daemon
sudo systemctl daemon-reload
sudo systemctl restart docker
Login to your Docker Hub account
sudo docker login
Objective
-----------------------------
| Linux | Windows |
-----------------------------
| ARM | AMD64 | ARM | AMD64 |
-----------------------------
| Dockerfile | Dockerfile |
-----------------------------
| Host |
-----------------------------
The following allows us to run and build ARM64 on AMD64 however, it is restricted to work only with Docker images from the multiarch repository.
docker run --rm --privileged multiarch/qemu-user-static:register --reset
docker run --rm -it multiarch/alpine:arm64-edge /bin/sh
This is similar of running Linux containers on OSX with default xhyve virtualization.
Requirements
sudo apt-get install -y qemu-user-static qemu-user binfmt-support
ls -ltr /proc/sys/fs/binfmt_misc
# I.e copy /usr/bin/qemu-aarch64-static to Docker project folder.
Or
for target_arch in aarch64; do # Extend
wget -N https://github.com/multiarch/qemu-user-static/releases/download/v3.1.0-3/x86_64_qemu-${target_arch}-static.tar.gz
tar -xvf x86_64_qemu-${target_arch}-static.tar.gz
done
rm *.tar.gz
It is now already possible to run ARM64 images by mounting the qemu binary into the container.
docker run --rm -it -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static …
But there is no way for the Docker CLI to pull a specific arch, hence we can only specify to pull "ubuntu:latest" which would result in pulling the AMD64 image instead of an ARM64 image. In any way for building an ARM64 image we would need to move the binary to the Docker image during the build process and the "build" flag does not support the volume mount parameter.
docker manifest inspect ubuntu:latest
Use the digest to pull the corresponding arch image.
# Dockerfile.arm64
FROM ubuntu@sha256:92d9e5deed4c994a64f04cb023370e79ce273fabde51f8cfc7cf66b594147eb2
COPY qemu-aarch64-static /usr/bin/
# Dockerfile.amd64
FROM ubuntu@sha256:f2557f94cac1cc4509d0483cb6e302da841ecd6f82eb2e91dc7ba6cfd0c580ab
#!/usr/bin/env bash
USER=posidron
NAME=core
for arch in amd64 arm64; do
docker build --no-cache -f Dockerfile.${arch} -t $USER/$NAME:${arch}-latest .
docker push $USER/$NAME:${arch}-latest
done
$ docker image inspect posidron/core:arm64-latest --format '{{.Os}} {{.Architecture}}'
linux arm64
$ docker image inspect posidron/core:amd64-latest --format '{{.Os}} {{.Architecture}}'
linux amd64
#!/usr/bin/env bash
USER=posidron
NAME=core
docker manifest create \
$USER/$NAME:latest \
$USER/$NAME:amd64-latest \
$USER/$NAME:arm64-latest
docker manifest annotate $USER/$NAME:latest $USER/$NAME:arm64-latest --os linux --arch arm64 --variant v8
docker manifest push $USER/$NAME:latest
docker manifest inspect posidron/core
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1150,
"digest": "sha256:f2557f94cac1cc4509d0483cb6e302da841ecd6f82eb2e91dc7ba6cfd0c580ab",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 1361,
"digest": "sha256:7f7c38c7cc5f4d4ba657ec1d0041ff6a5a633f1d9864ddc3e5ba2b0b49a49ace",
"platform": {
"architecture": "arm64",
"os": "linux",
"variant": "armv8"
}
}
]
}
docker run mplatform/mquery posidron/core
Image: posidron/core
* Manifest List: Yes
* Supported platforms:
- linux/amd64
- linux/arm64
This would resemble FuzzOS multi-arch.
# Dockerfile
ARG IMAGE=posidron/core
FROM $IMAGE
# Build for both Architectures
docker build --no-cache --build-arg IMAGE=posidron/core:arm64-latest -t fuzzos .
docker build --no-cache --build-arg IMAGE=posidron/core:amd64-latest -t fuzzos .
Proceed with creating a manifest for the new child image similar to posidron/core
but for posidron/fuzzos
in this case.
• https://github.com/linuxkit/linuxkit/tree/master/pkg/binfmt/etc/binfmt.d