This is pre-release Docker stuff. Although agreed in principle at time of writing, this may never become part of Docker or may be changed in significant ways. Once this is supported by Docker, you should use their documentation.
I used Stefan Scherer’s WhoAmI image to help me understand this functionality.
In an earlier post, I mentioned that I have set up a Swarm cluster at home built out of Raspberry Pis for testing OpenFAAS. The beauty of this serverless framework is that it can run on anything that runs Docker Swarm or Kubernetes. So, because I will likely graduate from using it on a Pi to using it on a “proper” server one day, I thought it might be a nice idea to write all my functions so that they can be used in multiple architectures.
With QEMU and using the Resin containers, there’s a well-established way of building an ARM container on an AMD64 machine (see Docker). This way I can build all the different Docker images in my continuous integration tool, publish to the Docker Hub and get my Swarm cluster to pull down the relevant images.
If it all worked that easily, then life would be far too simple. When I deployed the images to my Swarm cluster, I would
wait hours and the containers would be stuck in a
pending state. Eventually, I found that the Swarm was reporting that
there was no suitable nodes available. Confused, I ran the image on a Pi and it all worked fine.
After lots of Googling, I did a
docker inspect on the container and found that the architecture was reporting as
amd64. You can still see this on the Resin containers.
It appears that the
Architecture key is set by whatever the machine that builds the container is, not by what the
image is. This is a right pain in the arse and would mean being unable to build ARM containers on my CI machine.
Manifest To The Rescue
The concept of the manifest seems fairly simple and not dissimilar to that of a symbolic link. You upload your Docker
image as normal, with a descriptive name (for example,
linux-arm-latest). Then you create
the manifest with the tag
latest, tell it which images are included within it and what the operating system and
architecture is. Then, when you pull the
latest tag down, it will get the relevant image dependent upon your operating
system and architecture.
A Working Example
This is based upon the Makefile in my Distance Finder function. This is written as a series of commands so they can be explained, but something like a Makefile would be more usable. This will build an AMD64 and an ARM version - you can add further variants as required.
Fortunately, you won’t need to get your downloaded Docker binary to log in as it will get anything it needs from the main Docker binary.