thegeeklab/content/posts/run-arm32-docker-daemon-on-arm64-servers/index.md
Robert Kaussow bfb36c6c89
All checks were successful
continuous-integration/drone/push Build is passing
publish new post
2020-09-24 10:38:27 +02:00

5.6 KiB

title date authors tags resources
Run an ARM32 Docker daemon on ARM64 servers 2020-09-24T10:30:00+02:00
robert-kaussow
Automation
Container
Sysadmin
name src params
feature images/feature.jpg
anchor credits
Center [Yannick Pipke](https://unsplash.com/@joker2000) on [Unsplash](https://unsplash.com/s/photos/cpu)

In the last days I worked on a suitable setup for a Drone CI server to support multi-arch builds. While the setup for common x86 Drone runners is easy, working with setups for ARM, especially ARM32, is a bit tricky. The easiest way would be to have native servers of the respective architecture available. However, it's difficult to find hosting offers for ARM at all - for ARM32 this seems almost impossible. I decided to use Amazon EC2 ARM64 servers, they are relatively cheap and can also be used as a private customer.

But how do you turn an ARM64 server into an ARM32 server? Basic requirement is an ARMv8 CPU. This type supports (in most cases) both AArch32 and AArch64. The first step is to enable multi-arch support on your operating system. I use Ubuntu 18.10 for this setup:

dpkg --add-architecture armhf

Then add the Docker CE repository for ARM32 and install the packages:

{{< highlight bash "linenos=table" >}}

add GPG key

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

add repos

add-apt-repository
"deb [arch=armhf] https://download.docker.com/linux/ubuntu
$RELEASE
stable

install

apt-get update apt-get install docker-ce:armhf {{< /highlight >}}

To use the right architecture within Docker containers you still have to force the Docker daemon into ARM32 mode. This can be accomplished by two systemd overwrites:

{{< highlight bash "linenos=table" >}}

overwrite docker.service

/etc/systemd/system/docker.service.d/override.conf

[Service] ExecStart= ExecStart=/usr/bin/setarch linux32 -B /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

overwrite containerd.service

/etc/systemd/system/containerd.service.d/override.conf

[Service] ExecStart= ExecStart=/usr/bin/setarch linux32 -B /usr/bin/containerd {{< /highlight >}}

That's it. Don't forget to reload and restart the systemd daemon:

systemctl, daemon reload
systemctl, restart, docker

What you get is a Docker daemon that runs in ARM32 mode. This can be used for example to start a Golang container and build apps without cross-compile.

{{< highlight bash "linenos=table" >}} root@ip-10-0-225-151:~# docker version Client: Docker Engine - Community Version: 19.03.13 API version: 1.40 Go version: go1.13.15 Git commit: 4484c46 Built: Wed Sep 16 17:07:23 2020 OS/Arch: linux/arm Experimental: false

Server: Docker Engine - Community Engine: Version: 19.03.13 API version: 1.40 (minimum version 1.12) Go version: go1.13.15 Git commit: 4484c46 Built: Wed Sep 16 17:01:08 2020 OS/Arch: linux/arm Experimental: false containerd: Version: 1.3.7 GitCommit: 8fba4e9a7d01810a393d5d25a3621dc101981175 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683 root@ip-10-0-225-151:~# docker run alpine uname -a Linux dbad5ddeb5ea 5.3.0-1035-aws #37-Ubuntu SMP Sun Sep 6 01:17:41 UTC 2020 armv8l Linux {{< /highlight >}}

Just a word of warning. I'm not a hardware specialist and there might be some situations where this setup does not work. Furthermore it seems that some operating systems have problems to recognize armv8l as ARM32 architecture. For OpenSuse as an example I had to force zypper into armv7hl mode to get it working. After this step building ARM32 OpenSuse Docker images also works for me.

sed -i 's/# arch = s390/arch = armv7hl/g' /etc/zypp/zypp.conf

If you want to give it a try, I've prepared a minimal Cloud-Init configuration:

{{< highlight yaml "linenos=table" >}} #cloud-config

apt_reboot_if_required: false package_update: true package_upgrade: true

bootcmd:

  • [ dpkg, --add-architecture, armhf ]

apt: sources: docker.list: source: deb [arch=armhf] https://download.docker.com/linux/ubuntu $RELEASE stable keyid: 0EBFCD88

packages:

  • 'docker-ce:armhf'

write_files:

  • path: /etc/systemd/system/docker.service.d/override.conf content: | [Service] ExecStart= ExecStart=/usr/bin/setarch linux32 -B /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

  • path: /etc/systemd/system/containerd.service.d/override.conf content: | [Service] ExecStart= ExecStart=/usr/bin/setarch linux32 -B /usr/bin/containerd

runcmd:

  • [ systemctl, daemon-reload ]
  • [ systemctl, restart, docker ]

{{< /highlight >}}