Note: This is all very experimental; Docker does not support any architecture other than X86_64.
The last few evenings I’ve been working on Mulitifarious, a means of creating heterogenous Docker Swarms. I’d previously found that I can create a swarm with heterogenous members — a swarm which has, say, X86_64 and Raspberry Pi members. The problem arose, of course, once I attempted to run containers in the swarm. Containers are architecture specific.
Enter Multifarious. And no, multifarious isn’t nefarious, even if the words sound similar. Rather it means “many varied parts or aspects” (Google)
Multifarious uses dependency injection to tell Docker the name of a container suited to an Architecture.
In the preliminary version, ClusterHQ’s powerstrip is used in order to inject the proper image name into the request to build a Docker container. Powerstrip, in turn, calls a small Sinatra Application which performs a lookup in Redis to find the proper name for the host’s architecture. If the image name is not registered with Redis, then it is passed through without modification. It can be configured to either provide the image name for every architecture of a canonical name, or such that multifarious replaces the default name only in the case of a “special case”.
Quite possibly a future version will be written in Go and rather than requiring multiple executables to perform the injection, I expect to merge powerstrip and the adapter into one. This should reduce the footprint a good deal.
I am still working on a cohesive demo, but the following will show that the dependency injection is working:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
matt@argentum:~$ docker -H tcp://127.0.0.1:2375 run -i hello Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (Assuming it was not already locally available.) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash For more examples and ideas, visit: http://docs.docker.com/userguide/ matt@argentum:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d07bf225819 hello-world:latest "/hello" 16 seconds ago Exited (0) 15 seconds ago tender_hawking matt@argentum:~$ docker images |grep hello hello-world latest e45a5af57b00 3 months ago 910 B luisbebop/docker-sinatra-hello-world latest 9f12dabcf938 17 months ago 357.5 MB |
The -i
is needed due to a powerstrip quirk. However, take note that the docker image being invoked on the command line is ‘hello’. The docker image being run is that of ‘hello-world’ and there is no ‘hello’ image. Injection is working and I can configure images to run based upon the architecture.
I’ve injected the proper name for the image based upon a Redis lookup. I chose Redis because it’s available for multiple platforms and is pretty easy to use. It just needs to have the lookup table fed to it.
The items are stored in Redis as a HSET
:
1 2 |
hset multifarious:hello x86_64 "hello-world" |
At runtime the image is chosen and injected and life proceeds.
The repository is available on github and will be added to in the next couple of days, with a full-fledged writeup and demo to follow in the next couple of days.
The Feaured Image is a modification of a photo by JD Hancock:
flickr photo shared by JD Hancock under a Creative Commons ( BY ) license