How to run Erlang in arm64 Docker image on x86_64 host - docker

How can my docker containers run Erlang commands with the linux/arm64/v8 platform on my x86_64/amd64 host?
I am trying to build a multi-platform Docker image following the official documentation. My build is failing when running build steps with erlang. Following this build failure to the underlying cause: Erlang commands return segmentation fault when emulating arm64 on the x86_64 hosts, even though arm/v7 works.
I have tested this across two machines: Windows 10, WSL 2 Ubuntu 20.04, Docker Desktop, x84_64; Ubuntu 20.04, x86_64. I have tested qemu versions 6.2.0 and 7.0.0-28 using their respective tags on tonistiigi/binfmt to install emulators.
Steps to reproduce on either x86_64 host, assuming Docker is already installed:
$ docker run --privileged --rm tonistiigi/binfmt --install all
{
"supported": [
"linux/amd64",
"linux/arm64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64le",
"linux/mips64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-aarch64",
"qemu-arm",
"qemu-mips64",
"qemu-mips64el",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x"
]
}
$ docker run --rm -it --platform linux/arm64 erlang:latest /bin/bash
root#d7f9b846f13a:/# uname -m
aarch64
root#d7f9b846f13a:/# erl
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault
$ docker inspect erlang:latest --format '{{.Os}}/{{.Architecture}}/{{.Variant}}'
linux/arm64/v8
Above, platform linux/arm64 is aliasing to linux/arm64/v8. Running erl fails with a segmentation fault. I expect it to work the same as linux/arm/v7, which is able to start an erl session as below.
$ docker run --rm -it --platform linux/arm/v7 erlang:latest /bin/bash
root#5a786052f0e4:/# uname -m
armv7l
root#5a786052f0e4:/# erl
Erlang/OTP 25 [erts-13.1.1] [source] [32-bit] [smp:2:2] [ds:2:2:10] [async-threads:1]
Eshell V13.1.1 (abort with ^G)
1>
$ docker inspect erlang:latest --format '{{.Os}}/{{.Architecture}}/{{.Variant}}'
linux/arm/v7
How can my docker containers run Erlang commands with the linux/arm64/v8 platform on my x86_64/amd64 host?

Because of a bug/missing feature in qemu, the erlang JIT segfaults when running. So you need to either compile erlang without the jit, or use an older version of erlang without the jit.
See https://github.com/erlang/otp/pull/6340 for some more details.

Related

The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested

My server and docker info. are as follows:
Linux xxx 3.10.0-1160.66.1.el7.x86_64 #1 xxx x86_64 x86_64 x86_64 GNU/Linux
Docker version 20.10.17
Client:
Context: default
Debug Mode: false
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.8.2-docker)
scan: Docker Scan (Docker Inc., v0.17.0)
Server:
Server Version: 20.10.17
Kernel Version: 3.10.0-1160.66.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
I want to build a docker container by QEMU. I followed the instructions from the official QEMU github. But it gave errors.
$ uname -m
x86_64
$ docker run --rm -t arm64v8/ubuntu uname -m
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested
exec /usr/bin/uname: exec format error
Then I found a similar docker problem on stackoverflow. I tried both docker build and docker buildx, and it still doesn't work.
$ docker build --platform linux/arm64/v8 .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /work/home/chenning/Dockerfile: no such file or directory
$ docker buildx build --push --platform linux/amd64,linux/arm64 -t <tag> .
-bash: tag: No such file or directory
I also tried the following instruction, but it still reported errors.
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
sh: write error: Invalid argument
Setting /usr/bin/qemu-alpha-static as binfmt interpreter for alpha
Setting /usr/bin/qemu-arm-static as binfmt interpreter for arm
sh: write error: Invalid argument
Setting /usr/bin/qemu-armeb-static as binfmt interpreter for armeb
sh: write error: Invalid argument
Setting /usr/bin/qemu-sparc-static as binfmt interpreter for sparc
sh: write error: Invalid argument
...
I followed the guide from this link
it works when I try
docker run --rm --privileged multiarch/qemu-user-static:register
I have qemu interpreters (including qemu-aarch64) in /proc/sys/fs/binfmt_misc
My qemu-aarch64 is like this
enabled
interpreter /usr/bin/qemu-aarch64-static
flags:
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff
but I don't have the permission to change flags, I also don't have interpreter /usr/bin/qemu-aarch64-static.
Can I get some help, pls?
I got the same error, but executing this command fixed the issue:
$ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
So I can even spawn a shell:
$ docker run -it arm64v8/ubuntu /bin/bash
root#0b6162g03ka5:/# uname -m
aarch64
If it doesn't work take a look at this issue, otherwise you should create a new issue on github

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]

I saw similar treads but they are different because I am using WSL2 and docker and GPU aware docker.
I have windows 10 version 2004 (build 20161.1000)
I have installed WSL 2 and have Docker Desktop 2.3.0.3 on my Windows System running.
I have Ubuntu 18.04 LTS installed in WSL 2 too.
I have installed the NVIDIA driver
The linux version is 4.19.121-microsoft-standard.
The NVIDIA driver version is 455.41 for my Laptop GPU QUADRO M2000M.
Actually I followed all the steps described in https://ubuntu.com/blog/getting-started-with-cuda-on-ubuntu-on-wsl-2 until the step where I have to run "sudo service docker stop" in an Ubuntu terminal.
This results in a message docker: unrecognized service.
I have to restart docker desktop in WIndows 10 in order to get the deamon running.
I test then in the Ubuntu terminal : docker run hello-world ==> this runs fine
Also the command docker run -it ubuntu bash ==> runs file in the Ubuntu terminal os WSL 2.
BUT when I run :
docker run -u $(id -u):$(id -g) -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3-jupyter
then I get the error : docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]
This invoves microsoft,Ubuntu,NVIDIA. I have search the support sites but could not find anything that solves my prblem.
Can anyone help me here?
There is this strange answer mentioned here and here:
sudo service docker start
sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
This worked for me on WSL (Ubuntu 20.04), so I added it to the ~/.bashrc script.
Note, the first part may need to be restarting docker!

Linking graphic card in Docker via OpenCL

I am on Ubuntu 19.10. and would like to use OpenCL inside docker.
Inside of the docker container I have installed opencl-headers,ocl-icd-opencl-dev and clinfo.
When I run clinfo on my machine outside of docker I have following response:
Number of platforms 1
Platform Name NVIDIA CUDA
Platform Vendor NVIDIA Corporation
Platform Version OpenCL 1.2 CUDA 10.2.159
...
When same is run in docker:
Number of platforms 0
I thought docker container should be able to use my graphic card, but am unsure if/how I should allow it.
Thank you for some insights
You need to start docker with the --gpus all option, eg:
docker run --rm --gpus all nvidia/opencl clinfo
You can also expose just a specific gpu:
docker run -it --rm --gpus "device=0" ubuntu nvidia-smi
Read more here: https://docs.docker.com/config/containers/resource_constraints/
If you get this error:
$ docker run --rm --gpus all nvidia/opencl clinfo
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
On Ubuntu, you can remedy it with:
$ sudo apt install -y nvidia-container-toolkit; sudo systemctl restart docker

Setting up CUDA with docker meets the permission not granted problem

I would like to setup cuda using the following code:
docker run -ti --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 nvidia/cuda
I Kept getting these Errors:
Command 'docker' not found, but can be installed with:
snap install docker # version 18.06.1-ce, or
apt install docker.io # version 18.09.7-0ubuntu1~19.04.5
See 'snap info docker' for additional versions.
I tried to google these Errors, but failed.
System Environment: Ubuntu Desktop 19.04
I should explain that this is a clean System I'm currently using.
I should tell you one thing that, installing anything with docker comes with a prerequisite, which is that you should install docker first.
You can find the tutorials on how you could install docker in the following link:
How to install Docker
And then you could install Nvidia compiled docker container with the following command:
docker pull nvidia/cuda
docker run -ti --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 nvidia/cuda
which was referenced from Nvidia CUDA Docker Hub and Nvidia CUDA GitHub page

How to check what OS a docker image depends on?

I want to extend my jenkins image to have docker installed so it can build a Dockerfile out of a project.
I found a nice install script for docker but only for Ubuntu 64bit. What I need to know is if the parent images of my jenkins image base on Ubuntu 64bit so I can use this install script without any problems.
I used docker image inspect <imagename> already but it only yields hashes for former image versions it seems.
docker run <image-name> cat /etc/*release*
It will return the metadata about your image. In the following form.
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
VARIANT_ID="202011171307-al2.470.0"
Amazon Linux release 2 (Karoo)
cpe:2.3:o:amazon:amazon_linux:2
In the docker world you'll encounter OSes like Alpine more or less frequently.
Hence its mostly advisable to get contents of the /etc/os-release file which will in most scenarios be present.
# Tomcat 9 running on Alpine OS
docker run -it tomcat:9-alpine cat /etc/os-release
# Tomcat 9 running Debian (buster)
docker run -it tomcat:9 cat /etc/os-release
The fact that your Jenkins is built on an Ubuntu 64 bits or a Fedora 24 or a Debian jessie should not bother you, as it should work anyway.
See
Run Different Linux OS in Docker Container?
for more explanations
and also
Docker container isolation, does it care about underlying Linux OS?
Anyway, if you want to get the FROM line of the Dockerfile used to build this image,
you can use the docker image
https://hub.docker.com/r/dduvnjak/dockerfile-from-image/
to get the
FROM UBUNTU
or
FROM DEBIAN
example from
How to check for Certain Properties in Docker Images
$ docker run -v /var/run/docker.sock:/var/run/docker.sock dduvnjak/dockerfile-from-image k3ck3c/nethogs | grep FROM
will show
FROM alpine:latest
Following command worked docker run mysql cat /etc/os-release.
Output:
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
. . .
I don't think there is currently any docker command that allows you to do that. It seems that the only way is to launch the container and run those commands: determine OS distribution of a docker image
Solution: docker run mysql cat /etc/os-release
Output:
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Resources