Docker Swarm is part of the official Docker orchestration effort, and allows for managing containers across a fleet of hosts rather than just on a single host.
The Puppet Docker module supports installing and managing Docker, and running individual docker containers. Given Swarm is packaged as containers, that means we can install a Swarm cluster using Puppet.
Swarm supports a number of discovery backends. For this example I'll be using Consul, again all managed by Puppet.
vagrant up --provider virtualbox
This will launch 2 virtual machines, install Consul and register a cluster, install Docker and Swarm and then establish the swarm.
You can access the swwarm using a docker client, either from you local machine or from one of the virtual machines. For instance:
docker -H tcp://10.20.3.11:3000 info
If you don't have docker installed locally you can run the above command from one of the virtual machines using:
vagrant ssh swarm-1 -c "docker -H tcp://localhost:3000 info"
This should print something like:
Containers: 4
Nodes: 2
swarm-1: 10.20.3.11:2375
└ Containers: 3
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
swarm-2: 10.20.3.12:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
We can also automatically scale the cluster by launching additional virtual machines.
INSTANCES=4 vagrant up --provider virtualbox
This will give us a total of 4 virtual machines, 2 new ones and the 2 existing machines we already launched. Once the machines have launched you should be able to run the above commands again, this time you'll get something like:
Containers: 6
Nodes: 4
swarm-1: 10.20.3.11:2375
└ Containers: 3
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
swarm-2: 10.20.3.12:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
swarm-3: 10.20.3.13:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
swarm-4: 10.20.3.14:2375
└ Containers: 1
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 490 MiB
The example uses the Docker module to launch the swarm containers. First we run the main swarm container on all hosts.
::docker::run { 'swarm':
image => 'swarm',
command => "join --addr=${::ipaddress_eth1}:2375 consul://${::ipaddress_eth1}:8500/swarm_nodes"
}
Then on one host we run the swarm manager:
::docker::run { 'swarm-manager':
image => 'swarm',
ports => '3000:2375',
command => "manage consul://${::ipaddress_eth1}:8500/swarm_nodes",
require => Docker::Run['swarm'],
}
Consul is managed by the excellent Consul module from Kyle Anderson. Much of the Consul configuration is in the hiera data, for example:
consul::config_hash:
data_dir: '/opt/consul'
client_addr: '0.0.0.0'
bind_addr: "%{::ipaddress_eth1}"