Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why macos(x86) can run docker arm container arm64v8/alpine?

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?

like image 597
Feng Xi Avatar asked Feb 24 '21 12:02

Feng Xi


1 Answers

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.

like image 93
jordanvrtanoski Avatar answered Oct 16 '22 22:10

jordanvrtanoski