Open source Java projects: Docker Swarm

Container-managed clustering with Docker Swarm

Page 2 of 3


$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
agent1    -        virtualbox   Running   tcp://192.168.99.101:2376           v1.11.1
agent2    -        virtualbox   Running   tcp://192.168.99.102:2376           v1.11.1
default   -        virtualbox   Stopped                                       Unknown
manager   *        virtualbox   Running   tcp://192.168.99.100:2376           v1.11.1



You now have three running machines: manager, agent1, and agent2, as well as one stopped machine: default. Note the asterisk in the manager's ACTIVE column. This means that all Docker commands will be sent to the manager. You'll learn how to change the active machine a little later, when you setup the environment.

Create a discovery token

Next you'll need to obtain a Swarm discovery token. The discovery token is a unique identifier for your Swarm cluster. You'll use it to start your manager and to connect your agents to your manager. This discovery token should only be used in test environments; production deployments are a little more complex. Create a discovery token by running the Swarm container and passing it the create command, as follows:



$ docker run --rm swarm create
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm
eada7ab697d2: Pull complete
afaf40cb2366: Pull complete
7495da266907: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:12e3f7bdb86682733adf5351543487f581e1ccede5d85e1d5e0a7a62dcc88116
Status: Downloaded newer image for swarm:latest
7c14cbf2a86ecd490a7ea7ae4b795a6b



Notes about this command:

  • The docker run command launches the specified Docker image, which in this case is swarm, or more specifically swarm:latest.
  • The command that you've passed to the Swarm container is create, which is defined on the container and tells the Swarm application to connect to the DockerHub discovery service and retrieve a unique Swarm ID, the discovery token.
  • The -rm argument tells Docker to automatically remove the container when it exits. This command can be read: run the latest version of the swarm container, execute the create command, and, when the it completes, remove the swarm container from the local machine.
  • The last line in the output is the discovery token, which in this example is 7c14cbf2a86ecd490a7ea7ae4b795a6b.

Save your discovery token in a safe place: you'l need it for the next step.

Run the Swarm manager and agents

Next you'll start the Swarm manager and create agents to join your Swarm cluster. Both activities are accomplished by launching the swarm container and passing different arguments. The manager is already the "active" machine. Create the Swarm cluster manager with the following command:



$ docker run -d -p 3376:3376 -t -v ~/.docker/machine/machines/manager:/certs:ro swarm manage -H 0.0.0.0:3376
  --tlsverify
  --tlscacert=/certs/ca.pem
  --tlscert=/certs/server.pem
  --tlskey=/certs/server-key.pem
  token://7c14cbf2a86ecd490a7ea7ae4b795a6b


This command runs the swarm container with the following configuration:

  • -d (or --detach): run the swarm container in background and print its container ID after it starts
  • -t: allocate a pseudo-TTY terminal output
  • -p: map port 3376 on the Docker Container to port 3376 on the Docker Host (your local laptop). This is the default port that the docker command expects to connect to
  • -v: mount the local volume (~/.docker/machine/machines/manager) on the container at the specified location (/certs) with read-only access (ro)

Depending on your version of Docker and your operating system, your certificates directory may be in a different location: this is was the only problem that I ran into when starting the Swarm manager. On a Mac, Docker creates a .docker folder in your home directory. When you created your manager virtual machine, it created its configuration at the location: machine/machines/manager. If you run into problems finding files during startup for files such as server.key or server-key.pem, locate those files in your own Docker configuration and update your volume mounting accordingly:

  • manage: you've seen that the swarm Docker container has a create argument that starts the Swarm container, connects to DockerHub to obtain a discovery token, and then exits. Here you can see the manage argument in use. The manage argument tells the swarm container to run in "manage" mode, which essentially means that it will start your Swarm manager process.
  • -H: The -H argument tells Swarm what host and port to bind to, which in this case is localhost:3376.
  • tls: The various tls arguments tell the Swarm manager where to find certificate files for TLS (HTTPS) communication.
  • token: The token argument references the discovery token that we created earlier. (Be sure to use the token that you created and not the one that I created for this example!)

Once you have the Swarm manager running, your next step is to start your agents and tell them to join the cluster. Accomplish this by running the Swarm container in "join" mode. Before you do that, you need to tell your local docker command-line client to send commands to the "agent1" machine that you created earlier. Do so with the command:

$ eval $(docker-machine env agent1)

This command tells the docker client to send all docker commands to the Docker engine running on the "agent1" machine. Now run the following command to start agent1:



$ docker run -d swarm join --addr=$(docker-machine ip agent1):2376 token://7c14cbf2a86ecd490a7ea7ae4b795a6b
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm
eada7ab697d2: Pull complete
afaf40cb2366: Pull complete
7495da266907: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:12e3f7bdb86682733adf5351543487f581e1ccede5d85e1d5e0a7a62dcc88116
Status: Downloaded newer image for swarm:latest
99c5ec703dc3230fcf769eb13e639079803ee36c33447a0290a2fb7ffe5e7952


This command, similar to the previous one, tells Docker to run the swarm container, but this time in "join" mode. You'll tell it to run in detached mode (-d) and pass it two arguments:

  • --addr: The address and port of the agent, which is used to advertise the presence of the agent to the manager.
  • token: the discovery token that we created earlier and used to start the manager.

With agent1 running, execute the same command to start agent2:



$ eval $(docker-machine env agent2)
$ docker run -d swarm join --addr=$(docker-machine ip agent2):2376 token://7c14cbf2a86ecd490a7ea7ae4b795a6b
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm
eada7ab697d2: Pull complete
afaf40cb2366: Pull complete
7495da266907: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:12e3f7bdb86682733adf5351543487f581e1ccede5d85e1d5e0a7a62dcc88116
Status: Downloaded newer image for swarm:latest
0b16ee511399c27d849c6a6c628822375c27755b14719b5295c9038f97ede72a


At this point, the manager and both agents should be running. Next you'll configure the docker client to connect to the Docker Swarm manager and retrieve information about the environments. First, set your DOCKER_HOST environment variable to point to the manager Docker machine:

$ DOCKER_HOST=$(docker-machine ip manager):3376

You can retrieve the manager's IP address by executing the docker-machine ip command and passing it the name of the machine for which you want to retrieve the IP address (manager). Likewise, on Windows you can execute the SET DOCKER_HOST command to setup the environment. With the DOCKER_HOST environment set, you can now retrieve information about your Swarm cluster by executing the docker info command:



$ docker info
Containers: 2
 Running: 2
 Paused: 0
 Stopped: 0
Images: 2
Server Version: swarm/1.2.2
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint
Nodes: 2
 agent1: 192.168.99.101:2376
  - ID: RDNQ:VD3I:AZPE:LSWW:7NND:XV7C:KHGH:5KR5:MZHG:4I7H:7RMU:XGQG
  - Status: Healthy
  - Containers: 1
  - Reserved CPUs: 0 / 1
  - Reserved Memory: 0 B / 1.021 GiB
  - Labels: executiondriver=, kernelversion=4.4.8-boot2docker, operatingsystem=Boot2Docker 1.11.1 (TCL 7.0); HEAD : 7954f54 - Wed Apr 27 16:36:45 UTC 2016, provider=virtualbox, storagedriver=aufs
  - Error: (none)
  - UpdatedAt: 2016-05-22T19:03:35Z
  - ServerVersion: 1.11.1
 agent2: 192.168.99.102:2376
  - ID: DXN7:FLLA:RMDW:HSPS:WT74:YM2I:CM3G:QBY7:FR7G:4WEO:LJ72:XB6L
  - Status: Healthy
  - Containers: 1
  - Reserved CPUs: 0 / 1
  - Reserved Memory: 0 B / 1.021 GiB
  - Labels: executiondriver=, kernelversion=4.4.8-boot2docker, operatingsystem=Boot2Docker 1.11.1 (TCL 7.0); HEAD : 7954f54 - Wed Apr 27 16:36:45 UTC 2016, provider=virtualbox, storagedriver=aufs
  - Error: (none)
  - UpdatedAt: 2016-05-22T19:03:32Z
  - ServerVersion: 1.11.1
Plugins:
 Volume:
 Network:
Kernel Version: 4.4.8-boot2docker
Operating System: linux
Architecture: amd64
CPUs: 2
Total Memory: 2.042 GiB
Name: 77d61b0fe67f
Docker Root Dir:
Debug mode (client): false
Debug mode (server): false
WARNING: No kernel memory limit support



From this output you can see that you're running two containers (Swarm containers running in "join" mode) for your two agents and those agents are healthy. Note that these are the Docker machine containers and not your custom Docker containers, such as Nginx Docker containers. You can view the running custom containers by executing the docker ps command:



$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES



As expected, no custom containers are running.

Running containers in Docker Swarm

Thus far you've created three Docker machines and created a discovery token for your cluster. You've started one instance of the swarm container in "manage" mode and two instances of the swarm container in "join" mode. You have a running cluster, but it's not yet running any containers. In this section you'll start a Nginx container and connect to it. Begin with the following command:



$ docker run -d -p 80:80 nginx
cc6d627873f7b33f910129fafdcc5c544048cc864ef5433e667afc9a88632931



In this example, you run an nginx container (note that omitting a version defaults to latest) in detached mode and bind port 80 on the container to port 80 on the Docker host. Use the docker client to view your running container:



$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
cc6d627873f7        nginx               "nginx -g 'daemon off"   28 seconds ago      Up 27 seconds       192.168.99.101:80->80/tcp, 443/tcp   agent1/goofy_bassi



The Docker manager deployed the Nginx container to agent1. We can connect to it by opening a browser to the following URL: http://192.168.99.101/.

If successful you should see a website similar to the interface in Figure 5.

dockerswarm fig05

Figure 5. A running Nginx container

To complete this example, let's startup a second Nginx container and review its deployment:


$ docker run -d -p 80:80 nginx

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                NAMES
737d5d37d5a6        nginx               "nginx -g 'daemon off"   About a minute ago   Up About a minute   192.168.99.102:80->80/tcp, 443/tcp   agent2/condescending_galileo
cc6d627873f7        nginx               "nginx -g 'daemon off"   3 minutes ago        Up 3 minutes        192.168.99.101:80->80/tcp, 443/tcp   agent1/goofy_bassi


As you can see, Swarm deployed the first Nginx container to agent1 and the second to agent2. The algorithm it uses to deploy containers is to search for the agent with the least number of containers and deploy the newly requested container there. You can connect to the new instance at the following URL: http://192.168.99.102/.

You now have a Swarm cluster with two agents running two Nginx containers. Verify that you can access both. When you're finished, you can clean up your environment by stopping containers as you normally would, with the docker stop command:



$ docker stop 737
737

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
cc6d627873f7        nginx               "nginx -g 'daemon off"   6 minutes ago       Up 6 minutes        192.168.99.101:80->80/tcp, 443/tcp   agent1/goofy_bassi

$ docker stop cc6
cc6

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES


Both Nginx containers are now stopped. You can stop Docker Swarm using the docker-machine stop command:



$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
agent1    -        virtualbox   Running   tcp://192.168.99.101:2376           v1.11.1
agent2    -        virtualbox   Running   tcp://192.168.99.102:2376           v1.11.1
default   -        virtualbox   Stopped                                       Unknown
manager   -        virtualbox   Running   tcp://192.168.99.100:2376           v1.11.1

$ docker-machine stop agent1
Stopping "agent1"...
Machine "agent1" was stopped.

$ docker-machine stop agent2
Stopping "agent2"...
Machine "agent2" was stopped.

$ docker-machine stop manager
Stopping "manager"...
Machine "manager" was stopped.

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
agent1    -        virtualbox   Stopped                 Unknown
agent2    -        virtualbox   Stopped                 Unknown
default   -        virtualbox   Stopped                 Unknown
manager   -        virtualbox   Stopped                 Unknown



| 1 2 3 Page 2