Using Docker Swarm in Production

[Introduction]

I have always been fascinated with Docker Swarm and how it can cluster multiple computers together to run containers. I mainly used Swarm via docker-machine with the Virtual Box provider for testing. I felt that now it is time to try and run this in production. This blog post will explain how to create a simple Swarm cluster and secure it with a firewall. Docker officially recommends that you enable TLS on each node but I wanted to make it simpler with firewall rules to prevent unauthorized access.

[Setup]

Docker v1.10 has been installed on each of these machines running Ubuntu 15.10:

node_0 – The Swarm Master.
node_1 – A Swarm node.
node_2 – Another Swarm node.

[Installation]

1. Setup each node to have Docker listen on it’s own host IP address and disable the firewall rules:

First, stop the Docker daemon so we can make configuration changes:

systemctl stop docker

Edit: /etc/default/docker.  Uncomment if needed and modify DOCKER_OPTS as follows:

DOCKER_OPTS=”-H tcp://node_0_ip:2375 –iptables=false”

Start the Docker daemon again:

systemctl start docker

(Repeat this process for all the nodes)

2. On the Swarm Master node, create a cluster token. Each Swarm client will need the token to form a cluster. The output of this command will be a long token that you will need in the next steps.

docker run swarm create

3. On the Swarm Master node, create a Swarm Manager using the token from step 2. The Swarm manager will listen on port 5000.

docker run -d -p 5000:2375 -t swarm manage token://6b11f566db288878e16e56f37c58599f

2. Type the following commands from the master node to join the slave nodes to the cluster using the token from step 2.

docker run -d swarm join –addr=node_0_ip:2375 token://6b11f566db288878e16e56f37c58599f
docker run -d swarm join –addr=node_1_ip:2375 token://6b11f566db288878e16e56f37c58599f
docker run -d swarm join –addr=node_2_ip:2375 token://6b11f566db288878e16e56f37c58599f

3. Since the Swarm manager is running on port 5000 on node_0, we need to tell the Docker client such as a laptop to connect to that host and port to use the cluster. The following command will show the status of the Swarm cluster.

docker -H tcp://node_0_ip:5000 ps

[Securing]

4. Finally, we need to secure the Swarm cluster with firewall rules so that only the nodes in the cluster can talk to the Docker engine. The following rules will deny all incoming traffic and only allow Docker access from the nodes.

Node_0:

ufw allow 22
ufw allow 5000
ufw default deny incoming
ufw allow from node_1_ip
ufw allow from node_2_ip
ufw enable

Node_1:

ufw allow 22
ufw default deny incoming
ufw allow from node_0_ip
ufw allow from node_2_ip
ufw enable

Node_2:

ufw allow 22
ufw default deny incoming
ufw allow from node_0_ip
ufw allow from node_1_ip
ufw enable

[Conclusion]

Now you should have a three node Docker Swarm Cluster that is locked down. If you need to enable an external port for a container, the firewall rules will need to be adjusted manually.