Blog

Combining Salt with Docker

14 Jun, 2014

You could use Salt to build and run Docker containers but that is not how I use it here. This blogpost is about Docker containers that run Salt minions, which is just an experiment. The use case? Suppose you have several containers that run a particular piece of middleware, and this piece of middleware needs a security update, i.e. an OpenSSL hotfix. It is necessary to perform the update immediately.
 
The Dockerfile
In order to build a container you have to write down the container description in a file called Dockerfile. Here is the Dockerfile:

#-------
# Standard heading stuff
FROM centos
MAINTAINER No Reply noreply@xebia.com
# Do Salt install stuff and squeeze in a master.conf snippet that tells the minion
# to contact the master specified.
RUN rpm -Uvh http://ftp.linux.ncsu.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm
RUN yum install -y salt-minion --enablerepo=epel-testing
RUN [ ! -d /etc/salt/minion.d ] && mkdir /etc/salt/minion.d
ADD ./master.conf /etc/salt/minion.d/master.conf
# Run the Salt Minion and do not detach from the terminal.
# This is important because the Docker container will exit whenever
# the CMD process exits.
CMD /usr/bin/salt-minion
#-------

 
Build the image
Time to run the Dockerfile through docker. The command is:

$ docker build --rm=true -t salt-minion .

provided that you run this command in the directory where file Dockerfile and master.conf resides. Docker creates an image with tag ‘salt-minion’ and throws away all intermediate images after a successful build.
 
Run a container
The command is:

$ docker run -d salt-minion

and Docker returns:

aab154310ba6452ba2c686d15b1e3ca5fd85124d38c7935f1200d33b3a3e7ced

The Salt minion on the container is started and searches for a Salt master to connect to, defined by the configuration setting “master” in file /etc/salt/minion.d/master.conf. You might want to run the Salt master in “auto_accept” mode so that minion keys are accepted automatically. Docker assigns a container id to the running container. That is the magic key that docker reports as a result of the run command.
The following command shows the running container:

$ docker ps
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              NAMES
273a6b77a8fa        salt-minion:latest   /bin/sh -c /etc/rc.l   3 seconds ago       Up 3 seconds        distracted_lumiere

 
Apply the hot fix
There you are: the Salt minion is controlled by your Salt master. Provided that you have a state module that contains the OpenSSL hot fix, you can now easily update all docker nodes to include the hotfix:

salt \* state.sls openssl-hotfix

That is all there is to it.

guest
8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Andrew Phillips
Andrew Phillips
7 years ago

Interesting idea, Erwin! Just out of curiosity: would you say that the idea of modifying Docker containers rather than creating a new container version somewhat goes “against the grain” of Docker thinking?
It’s certainly technically possible, but many (most?) of the stories around Docker so far seem to treat containers as a lightweight, “destroy and recreate” delivery mechanism, rather than something that would be sufficiently long-lived that you would need to patch it while running..?

Erwin Embsen
Erwin Embsen
7 years ago

Hi Andrew,
You are right, the idea of modifying a container goes against the grain. It’s against the immutable server pattern that Docker is promoting. I prefer to destroy and recreate containers when there is need to, and avoid long-lived containers. This was just an an experiment where I tried to combine Salt and Docker in an unusual way.

Peter
Peter
7 years ago

Nice and simple pattern. Given me some ideas to play with. Thanks for sharing.

Eric Burghard
Eric Burghard
7 years ago

Docker doesn’t resolve configuration managament problems and this is where salt comes in to the rescue. Perhaps an update is not the best example of what to do with salt + docker.
If you have dozens of running containers with the same image but slighty different configuration and links between containers it’s really a pain do it the docker way (intermediate container playing with docker socket, interactive scripts, …).
Linking several containers is easy with salt mine and events and it can be highly dynamic, but what’s more important, is that salt express state (what needs to be done) and not how to do it (like Dockerfile).
Docker for me is amazing for preparing new base images and firing new vm in second but i like keeping the Dockerfile damn simple and let salt manage the state of my hundreds of containers in second. It would be very unpraticable to do it by rebuilding new images.
Now there is a lot of dogmas around how you are supposed to use Docker, that docker container are not a vm but process, that there should be one process per container, no ssh, short lived, no update, whatever, … Just don’t limit yourself, seek efficiency over dogmas.

askar
askar
7 years ago

I run Docker container run Salt-minions by building image from existing ubuntu image by committing changes to different image instead of using Dockerfile
– Run container from Ubuntu image (docker run -i -t –name red ubuntu /bin/bash)
– Install salt-minions (sudo apt-get install salt-minion)
– Edit /etc/salt/minions configuration file for Master IP
– Stopped container (docker stop
– Now create our own image
# docker commit -m=”Added salt-minions” -a=”Askar” red ubuntu:v2
– Now create as many containers you want from the image
# docker run -i -t –name green ubuntu:v2 /bin/bash
– Once inside container vi /etc/salt/minions and change the id (id: green)
– salt-minions -d (or -l debug for debuging)

Diego Woitasen
Diego Woitasen
7 years ago

Nice phrase: “seek efficiency over dogmas”
I don’t like the Dockerfile as provisioning tool. It’s like going back in time to use script to automate installation. There should be a way to use a “provisioner” for Docker like we have in Vagrant. I have some ideas about how to do it, but I’d like to hear other experiences.

Sergio
Sergio
6 years ago
Reply to  Diego Woitasen

Try using https://packer.io/ from HashiCorp

Explore related posts