cloud · docker · linux · ppc64le · s390x · x86_64

docker: creating multi-arch images

One of the great advantages of using containers [1] is that it brings flexibility to you deployments. You can have a container configured with everything you need and move it around to be executed where you want, which is a time saving approach (and reminds me of the Java’s WORA [2]: write once, run anywhere). If all your systems run the same operating system on the same architecture, you do not need to worry about anything else, but how to handle a scenario where you have different operating systems and different architectures?

Luckily, Docker provides feature called manifest [3] that allows you to create a fat manifest [4], which is a virtual image that covers multiple architectures and contains pointers to real images. To use it, you need to enable the manifest CLI, which is a experimental feature, before starting using it (I’m assuming you already have Docker installed, if not this script can help you get it configured on Ubuntu [5]). To activate, you must add the option “experimental”: “enabled” in the file called config.json located at the home directory of your user:


14:16 $ cat ./.docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.09.2 (darwin)"
},
"credsStore": "osxkeychain",
"experimental": "enabled",
"stackOrchestrator": "swarm"
}

Once enabled, you are able to use it:


14:16 $ docker manifest

Usage: docker manifest COMMAND

Manage Docker image manifests and manifest lists

Commands:
annotate Add additional information to a local image manifest
create Create a local manifest list for annotating and pushing to a registry
inspect Display an image manifest, or manifest list
push Push a manifest list to a repository

Run 'docker manifest COMMAND --help' for more information on a command.

So, now that the manifest feature is enabled, how to create a multi-arch Docker image? The basic steps are:

  1. Create images on each architecture and push them to a Docker registry like Docker hub.
  2. Create a manifest (the virtual image we have mentioned before).
  3. Push this manifest image to the Docker registry you are using.
  4. Pull and run it wherever you want (if supported by your manifest).

This video shows the whole process:

The steps used are listed below:


# on x86_64, which was the machine used to create the fat manifest

FROM ubuntu:latest
CMD echo "Hello World from a container running on $(uname -m)"

docker build -f=Dockerfile.x8664 -t multi-arch-image:x8664 .
docker tag multi-arch-image:x8664 rpsene/multi-arch-image:x8664
docker login
docker push rpsene/multi-arch-image:x8664

vi ~/.docker/config.json
"experimental": "enabled",

docker manifest create rpsene/multi-arch-image:latest \
rpsene/multi-arch-image:x8664 rpsene/multi-arch-image:ppc64le \
rpsene/multi-arch-image:s390x

docker manifest push rpsene/multi-arch-image:latest

docker manifest inspect rpsene/multi-arch-image

docker stop $(docker ps -a -q)
docker rm -f $(docker ps -a -q)
docker rmi -f $(docker images -q)

docker pull rpsene/multi-arch-image:latest
docker run --rm rpsene/multi-arch-image:latest

# on ppc64le

FROM ppc64le/ubuntu:latest
CMD echo "Hello World from a container running on $(uname -m)"

docker build -f=Dockerfile.ppc64le -t multi-arch-image:ppc64le .
docker tag multi-arch-image:ppc64le rpsene/multi-arch-image:ppc64le
docker login
docker push rpsene/multi-arch-image:ppc64le

docker stop $(docker ps -a -q)
docker rm -f $(docker ps -a -q)
docker rmi -f $(docker images -q)

docker pull rpsene/multi-arch-image:latest
docker run --rm rpsene/multi-arch-image:latest

# on s390x

FROM s390x/ubuntu:latest
CMD echo "Hello World from a container running on $(uname -m)"

docker build -f=Dockerfile.s390x -t multi-arch-image:s390x .
docker tag multi-arch-image:s390x rpsene/multi-arch-image:s390x
docker login
docker push rpsene/multi-arch-image:s390x

docker stop $(docker ps -a -q)
docker rm -f $(docker ps -a -q)
docker rmi -f $(docker images -q)

docker pull rpsene/multi-arch-image:latest
docker run --rm rpsene/multi-arch-image:latest

That’s all!

References

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s