gotoz / runq

run regular Docker images in KVM/Qemu
Apache License 2.0
802 stars 45 forks source link

Multiarch support #16

Open Niels-Be opened 3 years ago

Niels-Be commented 3 years ago

I would like to be able to run multi arch images. With normal runc backend this is possible by enabling qmeu-binfmt and then simply running

$ docker run -it arm64v8/debian

Trying this with runq will result in exec error

$ docker run -it --runtime runq arm64v8/debian
[entrypoint(1) 09048dc] exec format error
Exec() failed
main.runEntrypoint
    /runq/cmd/init/entrypoint.go:129
main.mainEntrypoint
    /runq/cmd/init/entrypoint.go:22
main.main
    /runq/cmd/init/main.go:40
runtime.main
    /usr/local/go/src/runtime/proc.go:204
runtime.goexit
    /usr/local/go/src/runtime/asm_amd64.s:1374

Are there plans to support other architectures? Maybe add a flag that maps to the requested qemu variant? e.g. -e RUNQ_ARCH=aarch64

pmorjan commented 3 years ago

There are no plans for this. But I found this an interesting idea and did some experiments that can be found in the new branch:

https://github.com/gotoz/runq/tree/binfmt_misc

This (experimental) branch allows running unmodified AArch64 Docker images on an x86 host.E.g.:

$ docker run --platform=linux/aarch64 --runtime runq --rm alpine  uname -m
aarch64

Please give it a try.

Niels-Be commented 3 years ago

Thanks for the fast reply. This works and might be a nice feature on its own, but unfortunately this is not what I had in mind.

My hole idea was not to use qemu-user-static but full system emulation, because it does not support all syscalls. e.g. ptrace. (Also ldconfig crashes in recent debian:bullseye images under qemu-user.)

So instead of always using the nativ architecture to select the qmeu executable make this configurable in order to have a qemu-system-aarch64 runner on an amd64 platform.

pmorjan commented 3 years ago

For this you would also need an target architecture specific guest kernel and initrd.

hmh commented 2 years ago

The usual way people run multiarch in docker, with bin-fmt inside the container, can result in an insane slowdown because it spawns qemu for every command that has to be run. If you're just running one long-lived application, it works just fine. For a build that calls a large number of commands (e.g. C, C++), it can easily be on the grounds of 10x slower than what it could be.

For runq, it would make a lot more sense to not have binfmt anywhere. You run a different CPU and arch inside the QEMU vm, and everything is there would be in "native" mode for that cpu/arch. There is no launch-qemu-for-every-command cost anymore.

For multiarch runq, you'd have runq change the qemu parameters to the required cpu/arch based on what you specified in the docker command line, I suppose...