This is a continuation of my previous blog on Docker machine. In this blog, I will cover Docker Swarm.
Swarm manages a set of Docker nodes as a single cluster. This has the following advantages:
- Rather than managing individual Docker nodes, the cluster can be managed as a single entity.
- Swarm has an in-built scheduler that will decide the placement of Containers in the cluster. There are different constraints and affinities that can be mentioned which Swarm uses to decide the Container placement. Constraints could be cpu, memory etc and Affinity could be for grouping related Containers together. Swarm also has the provision to take its scheduler out and work with other schedulers like Mesos and Kubernetes.
- Swarm will take care of node failures so that Container HA can be provided.
Swarm has the following software components:
- Swarm Manager that takes of scheduling and HA. HA piece is not yet available.
- Swarm agent that runs in each node and communicates to Swarm manager.
- Node discovery. There are different approaches available for Swarm worker nodes to discover Swarm master. Discovery is needed because Swarm master and agents run on different nodes and there is a need to find the discovery parameters dynamically. Available discovery mechanisms are docker hub, etcd, Consul etc.
Following picture from 1 of Docker Swarm presentations shows high level overview of Swarm:
Following picture from here shows the Docker Swarm software components:
Following are some things I tried. I did this in my Ubuntu machine running inside Windows VMWare Player.
Setting up Swarm cluster with Docker machine:
I used the docker hub approach where docker hub is used as central repository for Swarm master and agents to discover each other.
First step is to create the token
docker run swarm create
Create the Swarm master. Use the tokenid generated from previous step.
docker-machine create \ -d virtualbox \ --swarm \ --swarm-master \ --swarm-discovery token://796c3dbac605d9bb7d93df341eb86fc9 \ swarm-master
Create Swarm worker nodes. Use the tokenid generated from previous step.
docker-machine create \ -d virtualbox \ --swarm \ --swarm-discovery token://796c3dbac605d9bb7d93df341eb86fc9 \ swarm-node-00
Following are the containers created in my master node. The first container is the Swarm agent and the second is Swarm master. Its not a good idea to create Master and Agent in same node.
86ccc1bd5250 swarm:latest "/swarm join --addr 24 hours ago Up 24 hours 2375/tcp swarm-agent ed541f32f42d swarm:latest "/swarm manage --tls 24 hours ago Up 24 hours 2375/tcp, 0.0.0.0:3376->3376/tcp swarm-agent-master
Following container gets created in the worker node, it is the Swarm agent container.
e266d7ec68d9 swarm:latest "/swarm join --addr 24 hours ago Up 24 hours 2375/tcp swarm-agent
To create containers on the Swarm cluster, we need to create the environment variables needed for Docker client to talk to Swarm manager:
eval "$(docker-machine env --swarm swarm-master)"
Following are the environmental variables that are set:
$ docker-machine env swarm-master export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.99.100:2376" export DOCKER_CERT_PATH="/home/sreeni/.docker/machine/machines/swarm-master" # Run this command to configure your shell: # eval "$(docker-machine env swarm-master)"
Now, Docker client is setup to talk to Swarm master. We can see the Swarm cluster detail using below command. We can see the 2 nodes listed below.
$ docker info Containers: 6 Strategy: spread Filters: affinity, health, constraint, port, dependency Nodes: 2 swarm-master: 192.168.99.100:2376 └ Containers: 4 └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.023 GiB swarm-node-00: 192.168.99.103:2376 └ Containers: 2 └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.023 GiB
At this point, I tried creating many containers and I could see that the containers getting distributed between the 2 nodes.
Setting up Swarm cluster natively:
Instead of using docker-machine, we can create Swarm cluster using native Swarm commands. With this approach, Swarm master can be run on 1 system and Swarm agent can be run on worker nodes.
First, I created token using dockerhub:
docker run --rm swarm create
Then, I created 2 nodes using docker machine.
On each node, I did the following to start Swarm agent.
docker run -d swarm join --addr=:2375 token://
On my Ubuntu machine, I ran the swarm master:
docker run -d -p 2375:2375 swarm manage token://
I could not get the Swarm agents to register with Swarm master as I saw the node list empty.
$ docker -H tcp://0.0.0.0:2375 info Containers: 0 Strategy: spread Filters: affinity, health, constraint, port, dependency Nodes: 0
Not sure if I am missing something here. I have raised this issue in Swarm github.
Picture used in this blog are from references.