Creating a test swarm - tooltwist/documentation GitHub Wiki
These steps are used to create a new test swarm on Digital Ocean.
Note 1 - that this is only required to create a completely new swarm
Note 2 - It is recommended that scripts are used to run all the commands shown here, so they can be rerun if there are ever any problems.
It is critical that the information used to access the swarm is never saved to github. Hackers troll github and other public repositories looking for api keys that will allow them to access private servers.
cat >> .gitignore << END
DO_ACCESS_TOKEN
SWARM_TOKEN
END
Log in to Digital Ocean, go to the API page and the Your Apps tab, and generate a new token. To remember this token - it isn't shown again - we'll save it to file. For example:
$ echo 12345b3e5c2abcda0242f28zyxwecf310098762f27ae1fabcdb1745accfdfbcb > DO_ACCESS_TOKEN
This step is used to get a Swarm Token. This token is used by Docker machines to attach to the swarm, using a discovery service provided by Docker. To get a token, run the following command on any Docker machine.
$ docker run --rm swarm create
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm
28d9e4361d1b: Pull complete
...
library/swarm:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security.
Digest: sha256:1502dd0c1d778d4f5e75d47820dd858ac1f67aa59c178f3244de17ccbde0067f
Status: Downloaded newer image for swarm:latest
b7798763f46abcdef2fa750e0e1234cf
Take note of last line of the output and save it as a file.
$ echo b7798763f46abcdef2fa750e0e1234cf > SWARM_TOKEN
Note that this command does not run the discovery service - it simply contacts the discovery server to register a new swarm. There is no need to run this command where the swarm will be created (e.g. at DigitalOcean) - it's quite okay to run this on your own machine.
We'll also choose a name for the swarm so we can recognise the servers in the swarm. For example:
$ echo myswarm > SWARM_NAME
Here we create a new virtual machine running Docker at Digital Ocean, to run the Swarm Master. This machine will be part of the swarm, but will also run a Docker container responsible for monitoring the other nodes in the swarm. Create a file named createMaster.sh
:
#!/bin/bash
#
# Create the swarm Master
#
DO_ACCESS_TOKEN=`cat DO_ACCESS_TOKEN`
SWARM_TOKEN=`cat SWARM_TOKEN`
SWARM_NAME=`cat SWARM_NAME`
REGION=sgp1
SIZE=4gb
SERVER_NAME=${SWARM_NAME}-master
docker-machine create --driver digitalocean \
--digitalocean-access-token ${DO_ACCESS_TOKEN} \
--digitalocean-region ${REGION} \
--digitalocean-size ${SIZE} \
--swarm \
--swarm-master \
--swarm-discovery token://${SWARM_TOKEN} \
${SERVER_NAME}
Notice the SWARM_TOKEN must be replaced with the token you obtained in step 1.
You can find out the running machines at any time using:
docker-machine ls
A swarm node is created in the same way as the master, but without the --swarm-master
parameter. Note that the server name is made unique by adding the current process ID as a suffix. This can be replaced with some other way of creating unique names if you prefer.
Create a file named createWorker.sh
:
#!/bin/bash
#
# Create a swarm worker node
#
DO_ACCESS_TOKEN=`cat DO_ACCESS_TOKEN`
SWARM_TOKEN=`cat SWARM_TOKEN`
SWARM_NAME=`cat SWARM_NAME`
REGION=sgp1
SIZE=4gb
SERVER_NAME=${SWARM_NAME}-worker-$$
docker-machine create --driver digitalocean \
--digitalocean-access-token ${DO_ACCESS_TOKEN} \
--digitalocean-region ${REGION} \
--digitalocean-size ${SIZE} \
--swarm \
--swarm-discovery token://${SWARM_TOKEN} \
${SERVER_NAME}
Once the swarm is running, check the state of the machines:
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
phil-master digitalocean Running tcp://128.199.84.133:2376 phil-master (master)
phil-worker-23725 * digitalocean Running tcp://188.166.245.99:2376 phil-master
We can take a look at the master machine (I've started a few application containers):
$ eval "$(docker-machine env phil-master)"
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e30c7e1f424 tooltwist/ttsite:30sep2015 "/sbin/my_init" 3 hours ago Up 3 hours 22/tcp, 39393/tcp, 0.0.0.0:32768->8080/tcp swarm2_ttdemo_1
1f97117847b8 swarm:latest "/swarm join --addr 6 hours ago Up 6 hours 2375/tcp swarm-agent
f5221c2ef67a swarm:latest "/swarm manage --tls 6 hours ago Up 6 hours 2375/tcp, 0.0.0.0:3376->3376/tcp swarm-agent-master
$ docker info
Containers: 9
Images: 123
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 141
Dirperm1 Supported: false
Execution Driver: native-0.2
Kernel Version: 3.13.0-57-generic
Operating System: Ubuntu 14.04.3 LTS
CPUs: 2
Total Memory: 3.861 GiB
Name: phil-master
ID: MF3M:U5UR:BT3U:G7QV:VDRA:X5DP:CN2F:CMES:7XNU:ZN4U:YPPV:KEUL
...
We can also look at the swarm. Notice the node prefix to the container names:
$ eval "$(docker-machine env --swarm phil-master)"
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6e30c7e1f424 tooltwist/ttsite:30sep2015 "/sbin/my_init" 3 hours ago Up 3 hours 22/tcp, 39393/tcp, 128.199.84.133:32768->8080/tcp phil-master/swarm2_ttdemo_1
abeb3540d1b4 tooltwist/ttsite:30sep2015 "/sbin/my_init" 6 hours ago Up 4 hours 22/tcp, 39393/tcp, 128.199.84.133:9080->8080/tcp phil-worker-23725/ttsite-container
$ docker info
Containers: 10
Images: 7
Storage Driver:
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 2
phil-master: 128.199.84.133:2376
└ Containers: 8
└ Reserved CPUs: 0 / 2
└ Reserved Memory: 0 B / 4.054 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.13.0-57-generic, operatingsystem=Ubuntu 14.04.3 LTS, provider=digitalocean, storagedriver=aufs
phil-worker-23725: 188.166.245.99:2376
└ Containers: 2
└ Reserved CPUs: 0 / 2
└ Reserved Memory: 0 B / 4.054 GiB
└ Labels: executiondriver=native-0.2, kernelversion=3.13.0-57-generic, operatingsystem=Ubuntu 14.04.3 LTS, provider=digitalocean, storagedriver=aufs
Execution Driver:
Kernel Version:
Operating System:
CPUs: 4
Total Memory: 8.108 GiB
Name: f5221c2ef67a
...
At this stage we can start a container on the swarm, but we have no way to route requests to the server other than guessing it's IP address from docker-machine ls
command and use the mapped port.
$ docker run -d -p 9080:8080 --name ttsite-container tooltwist/ttsite:30sep2015
dab942b78b129590ba0fce87f1f040fa59bfd1757e99826d8963c0596cf2ec85
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dab942b78b12 tooltwist/ttsite:30sep2015 "/sbin/my_init" About an hour ago Up 4 seconds 22/tcp, 39393/tcp, 0.0.0.0:9080->8080/tcp ttsite-container
1f97117847b8 swarm:latest "/swarm join --addr 2 hours ago Up 2 hours 2375/tcp swarm-agent
f5221c2ef67a swarm:latest "/swarm manage --tls 2 hours ago Up 2 hours 2375/tcp, 0.0.0.0:3376->3376/tcp swarm-agent-master
$ curl http://188.166.245.99:9080
curl: (7) Failed connect to 188.166.245.99:9080; Connection refused
$ curl http://128.199.84.133:9080
<!DOCTYPE html>
<html lang="en">
...
</html>