I happened to find that my macos(x86) can run a docker container for an arm image arm64v8/alpine, but with the following warning:
docker run -it arm64v8/alpine uname -a
WARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64) and no specific platform was requested
Linux d5509c57dd24 4.19.121-linuxkit #1 SMP Tue Dec 1 17:50:32 UTC 2020 aarch64 Linux
And I'm pretty sure the image is not a multi-arch image (docker manifest inspect --verbose arm64v8/alpine
). Why can x86 run an arm container?
You are correct, the image is not multi architecture, yet, docker can run it. Reason behind this is a kernel subsystem called binfmt_misc
which allows to set the magic
numbers of a binary file to specific actions for their execution. You can read more in this nice wikipedia post about it.
Docker for Mac is arriving prepared for the binfmt
magic, so there is nothing to be done to enable it. It will be enabled out-of-box with the installation, all you need to do is to fetch the image and run. The details of the mechanism can be found in repository of docker-for-mac project on this link.
To explain it simply, the binary images have the magic
number that allows the kernel to decide how to handle the execution. When binfmt_misc
intercepts a file for which it recognizes the magic
numbers it will invoke the handler that is associated with the magic
numbers.
This alone is not enough to run the container. The next part of the magic is QEMU
which is the emulator for various CPU architectures. The kernel (binfmt_misc
) will invoke the quemy for each of the binaries that are ARM64 and will emulate the ARM64v8.
This is not limited to docker
nor to the virtual machine that is running the docker
on macOS
. Any linux system can be configured to do this.
You can use following to install it setup Ubuntu to run the emulation.
sudo apt-get install qemu binfmt-support qemu-user-static # Install the qemu packages
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes # This step will execute the registering scripts
docker run --rm -t arm64v8/ubuntu uname -m # Testing the emulation environment
More details about the whole process of the set-up can be found in the qemu-user-static repository
OP: If you are wondering what is the usefulness of this, from my personal experiance, I am using this functionality heavily when porting applications from X86 to other architectures (mainly ARM64). This allows me to run build systems for various architectures without having a physical machine on which I can run the build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With