Docker and SwarmKit – Part 5 – going deep
In this post we will work with the SwarmKit directly and not use the Docker CLI to access it. For that we have to first build the necessary components from source which we can find on GitHub.
You can find the links to the previous 4 parts of this series here. There you will also find links to my other container related posts.
Build the infrastructure
Once again we will use VirtualBox to create a few virtual machines will be the members of our cluster. First make sure that you have no existing VM called nodeX
where X is a number between 1 and 5. Otherwise used docker-machine rm nodeX
to remove the corresponding nodes. Once we’re ready to go lets build 5 VMs with this command
for n in $(seq 1 5); do
docker-machine create --driver VirtualBox node$n
done;
As always buildling the infrastructure is the most time consuming task by far. On my laptop the above command takes a couple of minutes. The equivalent on say AWS or Azure would also take a few minutes.
Luckily we don’t have to do that very often. On the other hand, what I just said sounds a bit silly if you’re an oldie like me. I still remember the days when we had to wait weeks to get a new VM or even worse months to get a new physical server. So, we are totally spoiled. (Rant)
Once the VMs are built use
docker-machine ls
to verify that all machines are up and running as expected
Build SwarmKit Binaries
To build the binaries of the SwarmKit we can either use an existing GO environment on our Laptop and follow the instructions here or use the golang Docker container to build the binaries inside a container without the need to have GO natively installed
We can SSH into node1
which later should become the leader of the swarm.
docker-machine ssh node1
On our leader we first create a new directory, e.g.
mkdir /swarmkit
now cd into the swarmkit
folder
cd swarmkit
we then clone the source from GitHub using Go
docker run --rm -t -v $(pwd):/go golang:1.7 go get -d github.com/docker/swarmkit
this will put the source under the directory /go/src/github.com/docker/swarmkit
. Finally we can build the binaries, again using the Go container
docker run --rm -t \
-v $(pwd):/go \
-w /go/src/github.com/docker/swarmkit \
golang:1.7 bash -c "make binaries"
We should see something like this
and voila, you should find the binaries in the subfolder bin
of the swarmkit folder.
Using the SwarmCtl Utility
To make the swarmd
and swarmctl
available everywhere we can create a symlink to these two binaries into the /usr/bin
folder
sudo ln -s ~/swarmkit/src/github.com/docker/swarmkit/bin/swarmd /usr/bin/swarmd
sudo ln -s ~/swarmkit/src/github.com/docker/swarmkit/bin/swarmctl /usr/bin/swarmctl
now we can test the tool by entering
swarmctl version
and we should see something along the lines of
swarmctl github.com/docker/swarmkit v1.12.0-714-gefd44df
Create a Swarm
Initializing the Swarm
Similar to what we were doing in part 1 we need to first initialize a swarm. Still logged in to node
we can execute this command to do so
swarmd -d /tmp/node1 --listen-control-api /tmp/node1/swarm.sock --hostname node1
Let’s open a new ssh
session to node1
and assign the socket to the swarm to the environment variable SWARM_SOCKET
export SWARM_SOCKET=/tmp/node1/swarm.sock
Now we can use the swarmctl
to inspect the swarm
swarmctl cluster inspect default
and we should see something along the line of
Please note the two swarm tokens that we see at the end of the output above. We will be using those tokens to join the other VMs (we call them nodes) to the swarm either as master or as worker nodes. We have a token for each role.
Copy Swarmkit Binaries
To copy the swarm binaries (swarmctl and swarmd) to all the other nodes we can use this command
for n in $(seq 2 5); do
docker-machine scp node1:swarmkit/src/github.com/docker/swarmkit/bin/swarmd node$n:/home/docker/
docker-machine scp node1:swarmkit/src/github.com/docker/swarmkit/bin/swarmctl node$n:/home/docker/
done;
Joining Worker Nodes
Now let’s ssh
into e.g. node2 and join it to the cluster as a worker node
./swarmd -d /tmp/node2 --hostname node2 --join-addr 192.168.99.100:4242 --join-token <Worker Token>
In my case the <Worker Token>
is SWMTKN-1-4jz8msqzu2nwz7c0gtmw7xvfl80wmg2gfei3bzpzg7edlljeh3-285metdzg17jztsflhg0umde8
. The join-addr
is the IP address of node1
of your setup. You can get it via
docker-machine ip node
in my case it is 192.168.99.100
.
Repeat the same for node3
. Make sure to replace node2
with node3
in the join command.
On node1
we can now execute the command
swarmctl node ls
and should see something like this
As you can see, we now have a cluster of 3 nodes with one master (node1) and two workers (node2 and node3). Please join the remaining two nodes 4 and 5 with the same approach as above.
Creating Services
Having a swarm we can now create services and update them using the swarmctl
binary. Let’s create a service using the nginx
image
swarmctl service create --name nginx --image nginx:latest
This will create the service and run one container instance on a node of our cluster. We can use
swarmctl service ls
to list all our services that are defined for this cluster. We should see something like this
If we want to see more specific information about a particular service we can use the inspect
command
swarmctl service inspect nginx
and should get a much more detailed output.
We can see a lot of details in the above output. I want to specifically point out the column Node
which tells us on which node the nginx container is running. In my case it is node2
.
Now if we want to scale this service we can use the update
command
swarmctl service update nginx --replicas 2
after a short moment (needed to download the image on the remaining node) we should see this when executing the inspect
command again
As expected nginx is now running on two nodes of our cluster.
Summary
In this part we have used the Docker swarmkit directly to create a swarm and define and run services on this cluster. In the previous posts of this series we have used the Docker CLI to execute the same tasks. But under the hood the CLI just calls or uses the swarmd
and swarmctl
binaries.
If you are interested in more articles about containers in general and Docker in specific please refer to this index post