Cloud Native Blog - Container Solutions

Multi-arch Docker Images

Written by Adrian Mouat | Dec 28, 2016 1:57:59 PM

Although the promise of Docker is the elimination of differences when moving software between environments, you'll still face the problem that you can't cross platform boundaries, i.e. you can't run a Docker image built for x86_64 on a arm board such as the Raspberry Pi. This means that if you want to support multiple architectures, you typically end up tagging images with their arch (e.g. myimage-arm and myimage-x86_64). However, it turns out that the Docker image format already supports multi-platform images (or more accurately, "manifests"), it's just that tooling is lagging a little behind. This means that you can create and push an image to the Docker Hub that can be downloaded and run successfully on different architectures.

To prove this point, on my x86_64 laptop:

  
docker pull amouat/debian-multi
(out)Using default tag: latest
(out)latest: Pulling from amouat/debian-multi
(out)Digest: sha256:9ad51ec99905f6f4f30585d96e51d2f56d906756656162137153ffbacd4327c3
(out)Status: Image is up to date for amouat/debian-multi:latest
docker run amouat/debian-multi uname -m
(out)x86_64

And on a Raspberry Pi:

  
docker pull amouat/debian-multi
(out)Using default tag: latest
(out)latest: Pulling from amouat/debian-multi
(out)67e669aa5a70: Pull complete 
(out)Digest: sha256:9ad51ec99905f6f4f30585d96e51d2f56d906756656162137153ffbacd4327c3
(out)Status: Downloaded newer image for amouat/debian-multi:latest
docker run amouat/debian-multi uname -m
(out)armv7l

Note the matching names and digests, but the different architectures. The amouat/debian-multi image is public, so please try this out for yourself.

So how was this sorcery possible? Behind the scenes, the debian-multi manifest actually points to two separate images and the Docker daemon will automatically select the correct one for the current platform. To create the debian-multi manifest, I used the manifest tool by Phil Estes. I started by creating the following YAML file:

 
image: amouat/debian-multi:latest
manifests:
  - image: debian:latest
    platform:
      architecture: amd64
      os: linux
  - image: armhf/debian:latest
    platform:
      architecture: arm
      os: linux
	
	

Note that it contains links to two separate images - the official debian image for "amd64" and the semi-official "armhf/debian" image for arm (the armhf repos are a great resource for arm images). I then ran the manifest tool to turn the YAML into a proper Docker manifest and push it to the Hub:

  
manifest pushml ./debian-multi.yaml 
(out)iNFO[0000] Retrieving digests of images...              
(out)iNFO[0005] Image "debian:latest" is digest sha256:f7062cf040f67f0c26ff46b3b44fe036c29468a7e69d8170f37c57f2eec1261b; size: 529 
(out)INFO[0009] Image "armhf/debian:latest" is digest sha256:530ef496b362c7b8cae21c9eaf4e2af1f2f967523371d4ca8cfc8ce2ff2c3d02; size: 507 
(out)Digest: sha256:9ad51ec99905f6f4f30585d96e51d2f56d906756656162137153ffbacd4327c3
	
	

And that's it! Pretty sweet, but it would be even nicer if we didn't need to use a 3rd party tool and the official images already had multi-arch support - things that are coming soon.