Posted on January 13, 2016 by [https://il.linkedin.com/in/tgabay '''Tal Gabay''']
= Overview =
In this How-To, the steps for installing and configuring a Docker Swarm cluster, alongside DNS and Zookeeper, will be presented.
The cluster that will be set up will be on VMware Photon hosts.
A prerequisite to using this guide is to be familiar with Docker Swarm - information can be found [https://docs.docker.com/swarm/ here].
== Cluster description ==
The cluster will have 2 Swarm Managers and 3 Swarm Agents:
=== Masters ===
{| class="wikitable"
! style="text-align: center; font-weight: bold;" | Hostname
! style="font-weight: bold;" | IP Address
|-
| pt-swarm-master1.example.com
| 192.168.0.1
|-
| pt-swarm-master2.example.com
| 192.168.0.2
|}
=== Agents ===
{| class="wikitable"
! style="text-align: center; font-weight: bold; font-size: 0.100em;" | Hostname
! style="font-weight: bold;" | IP Address
|-
| pt-swarm-agent1.example.com
| 192.168.0.3
|-
| pt-swarm-agent2.example.com
| 192.168.0.4
|-
| pt-swarm-agent3.example.com
| 192.168.0.5
|}
= Docker Swarm Installation and Configuration =
== Setting Up the Managers ==
The following steps should be done on both managers.
Docker Swarm supports multiple methods of using service discovery, but in order to use failover, Consul, etcd or Zookeeper must be used. In this guide, Zookeeper will be used.
Download the latest stable version of Zookeeper and create the '' zoo.cfg '' file under the '' conf '' directory:
=== Zookeeper installation ===
The dataDir should be an empty, existing directory.
From the Zookeeper documentation: Every machine that is part of the ZooKeeper ensemble should know about every other machine in the ensemble. You accomplish this with the series of lines of the form server.id=host:port:port. You attribute the server id to each machine by creating a file named myid, one for each server, which resides in that server's data directory, as specified by the configuration file parameter dataDir. The myid file consists of a single line containing only the text of that machine's id. So myid of server 1 would contain the text "1" and nothing else. The id must be unique within the ensemble and should have a value between 1 and 255.
Set Zookeeper ID
Project Photon uses [https://en.wikipedia.org/wiki/Systemd Systemd] for services, so a zookeeper service should be created using systemd unit file.
Zookeeper comes with OpenJDK, so having Java on the Photon host is not a prerequisite. Simply direct the Environment variable to the location where the Zookeeper was extracted.
Now you need to enable and start the service. Enabling the service will make sure that if the host restarts for some reason, the service will automatically start.
Verify that the service was able to start:
On the Manager you elected to be the Swarm Leader (primary), execute the following (if you do not have a specific leader in mind, choose one of the managers randomly):
* '' docker run -d ''- run the container in the background.
* '' --name=manager1 ''- give the container a name instead of the auto-generated one.
* '' -p 8888:2375 ''- publish a container's port(s) to the host. In this case, when you connect to the host in port 8888, it connects to the container in port 2375.
* swarm - the image to use for the container.
* manage - the command to send to the container once it's up, alongside the rest of the parameters.
* '' --replication '' - tells swarm that the manager is part of a a multi-manager configuration and that this primary manager competes with other manager instances for the primary role. The primary manager has the authority to manage the cluster, replicate logs, and replicate events that are happening inside the cluster.
* '' --advertise 192.168.0.1:8888 ''- specifies the primary manager address. Swarm uses this address to advertise to the cluster when the node is elected as the primary.
* '' zk://192.168.0.1,192.168.0.2/swarm ''- specifies the Zookeepers' location to enable service discovery. The /swarm path is arbitrary, just make sure that every node that joins the cluster specifies that same path (it is meant to enable support for multiple clusters with the same Zookeepers).
On the second manager, execute the following:
Notice that the only difference is the --advertise flag value. The first manager will not lose leadership following this command.
Now 2 managers are alive, one is the primary and another is the replica. When we now look at the docker info on our primary manager, we can see the following information:
There are a few things that are worth noticing:
* The info command can be executed from ANY machine that can reach the master. The -H tcp://<ip>:<port> command specifies that the docker command should be executed on a remote host.
* Containers - this is the result of the docker ps -a command for the cluster we just set up.
* Images - the result of the docker images command.
* Role - as expected, this is the primary manager.
* Strategy - Swarm has a number of strategies it supports for setting up containers in the cluster. spread means that a new container will run on the node with the least amount of containers on it.
* Filters - Swarm can choose where to run containers based on different filters supplied in the command line. More info can be found [https://docs.docker.com/swarm/scheduler/filter/ here].
When we now look at the docker info on our replicated manager, we can see the following information:
Notice that the only differences between both managers are:
Role: as expected, this is the replicated manager.
Primary: contains the primary manager.
== Setting Up the Agents ==
In Swarm, in order for a node to become a part of the cluster, it should "join" that said cluster - do the following for each of the agents.
Edit the '' /usr/lib/systemd/system/docker.service '' file so that each agent will be able to join the cluster:
* '' -H tcp://0.0.0.0:2375 ''- This ensures that the Docker remote API on Swarm Agents is available over TCP for the Swarm Manager.
* '' -H unix:///var/run/docker.sock ''- The Docker daemon can listen for Docker Remote API requests via three different types of Socket: unix, tcp, and fd.
** tcp - If you need to access the Docker daemon remotely, you need to enable the tcp Socket.
** fd - On Systemd based systems, you can communicate with the daemon via Systemd socket activation.
* '' --cluster-advertise :2375 ''- advertises the machine on the network by stating the ethernet card and the port used by the Swarm Managers.
* '' --cluster-store zk://192.168.0.1,192.168.0.2/swarm ''- as we defined before, the service discovery being used here is Zookeeper.
Enable and start the docker service:
All that remains is to have the agents join the cluster:
A look at the output of the docker info command will now show:
== Setting Up DNS ==
Docker does not have its own self-provided DNS so we use a [https://github.com/ahmetalpbalkan/wagl wagl] DNS.
Setting it up is very simple. In this case, one of the masters will also be the DNS. Simply execute:
* '' --restart=always ''- Always restart the container regardless of the exit status. When you specify always, the Docker daemon will try to restart the container continuously. The container will also always start on daemon startup, regardless of the current state of the container.
* '' --link manager1:swarm ''- link the manager1 container (by name) and give it the alias swarm.
That's it, DNS is up and running.
= Test Your Cluster =
== Running Nginx ==
Execute the following commands from any docker client:
Note that this is the same command, executed twice. It tells the master to run 2 of the similar containers, each of which has 2 dns labels.
Now, from any container in the cluster that has dnsutils, you can execute the following (for example):