Installing a Docker Swarm cluster inside VirtualBox with Docker Machine

Table of Contents

1 Abstract

This document describes a setup to allow experimenting with Docker Swarm, the simple docker container orchestrator, over VirtualBox.

This allows you to play with orchestration scenarii without having to install docker on real machines.

Also, such an environment may be handy for teaching if you don't want to install docker on the lab's host. Installing the docker engine on Linux hosts for unprivileged users requires some care (refer to docs about securing Docker), as the default configuration may allow learners to easily gain root privileges (which may or not be desired).

While this was tested on a Debian GNU/Linux system, I expect much of it to work similarly on Windows or Mac OSX machines, as it mainly relies on Docker Machine, the docker client, and VirtualBox, which are all ported on most major OS.

I've provided below traces of executions happening on my system, to allow you to compare output and eventually spot meaningful differences in case of trouble. However, some traces aren't correct at the present time due to a bug in org-mode's babel which truncates part of the responses, sorry.

2 Install Docker Machine

We'll use Docker Machine to provision Virtual Machines on VirtualBox, to simulate a cluster of machines that will power a Docker Swarm cluster.

But we'll also use the docker client.

2.1 Install Docker CE

This may work with other versions, and the instructions here apply to a Debian system. YMMV.

Docker CE (Community Edition) is the lates version of Docker "upstream" (the Debian packages are probably outdated, or missing).

We'll perform the instructions provided in https://docs.docker.com/engine/installation/linux/debian/

2.1.1 Uninstall previous installations of Docker (if needed)

This is an optional step, in case you'd have already tested Docker from official1 Debian packages.

sudo apt-get remove docker docker-engine
ou
sudo apt-get remove docker.io

2.1.2 Install Docker CE

This should work on Debian or Ubuntu systems, but pay attention to differences in architecture (my system is 64 bits, …).

sudo apt-get install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce

2.1.3 Testing the local installation

If everything works locally (i.e.: with the docker daemon working on your host), the following works :

docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world


78445dd45222: Pulling fs layer 

78445dd45222: Downloading    971 B/971 B

78445dd45222: Download complete 

78445dd45222: Extracting    971 B/971 B

78445dd45222: Extracting    971 B/971 B

78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

2.2 Install Docker Machine

Docker Machine handles the provisioning of execution nodes (machines) for a Docker cluster, as VirtualBox Virtual Machines (VMs). This allows us to build a virtual mini-cluster, composed of (2) docker nodes.

We'll use the docker-machine executable from within the current directory (no need to pollute /usr/local/bin/).

wget -q https://github.com/docker/machine/releases/download/v0.10.0/docker-machine-`uname -s`-`uname -m`
chmod +x docker-machine-Linux-x86_64

Check that it works :

./docker-machine-Linux-x86_64 version
docker-machine-Linux-x86_64 version 0.10.0, build 76ed2a6

2.2.1 Test Docker Machine

We'll test that it works with VirtualBox. We don't cover here the process of installing VirtualBox. The following will hopefuly work with any default installation of VirtualBox (please report2 any issues)

./docker-machine-Linux-x86_64 create --driver virtualbox default
Running pre-create checks...
(default) Default Boot2Docker ISO is out-of-date, downloading the latest release...
(default) Latest release for github.com/boot2docker/boot2docker is v17.05.0-ce
(default) Downloading /home/olivier/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v17.05.0-ce/boot2docker.iso...
....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(default) Copying /home/olivier/.docker/machine/cache/boot2docker.iso to /home/olivier/.docker/machine/machines/default/boot2docker.iso...
(default) Creating VirtualBox VM...
(default) Creating SSH key...
(default) Starting the VM...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: ./docker-machine-Linux-x86_64 env default

Check that the machine is there. You may also open the VirtualBox GUI to see it running.

./docker-machine-Linux-x86_64 ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.05.0-ce

Now, it's time to set the environment variables that need to be used to run docker on that VM node, instead of the host.

Check the values of these variables :

./docker-machine-Linux-x86_64 env default

Note that you should see a different output here (org-mode bug) :

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/olivier/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
Run this command to configure your shell:
eval $(./docker-machine-Linux-x86_64 env default)

And follow the eval advice that was just given to you :

eval $(./docker-machine-Linux-x86_64 env default)

Now you can safely test :

docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world


78445dd45222: Pulling fs layer 

78445dd45222: Downloading    971 B/971 B

78445dd45222: Verifying Checksum 

78445dd45222: Download complete 

78445dd45222: Extracting    971 B/971 B

78445dd45222: Extracting    971 B/971 B

78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

You may notice no difference, but the execution took place inside the VM. This should all be transparent to the user. Of course performance won't be the same.

2.2.2 Troubleshooting

You may experience issues connecting to the VM if you have set a strict firewall on the host.

Docker Machine would then be able to instanciate a VM in VirtualBox, to which docker-machine could connect via SSH (with docker-machine ssh default) but the docker client couldn't talk to the docker daemon over port 2376 on the VM.

You may try commands like the following :

iptables -A INPUT -p tcp --dport 2376 -j ACCEPT

Note that you would need to let traffic pass also to port 3376 if you intend to use the Swarm mode (see below).

3 Configuring a Swarm cluster on VirtualBox nodes.

Now that Docker Machine can succesfully deploy nodes over VirtualBox, we'll test a Docker Swarm cluster using several such VMs as cluster nodes.

We'll follow instructions from Provision a Swarm cluster with Docker Machine (there may be more recent instructions, but at the time of writing, this worked).

First we'll create a standalone node which won't take part in the cluster, called local (I'm not sure about the need for this step. Feel free to suggest improvements):

./docker-machine-Linux-x86_64 create -d virtualbox local
$ Running pre-create checks...
[::1]:53: read: connection refused
Creating machine...
[::1]:53: read: connection refused
(local) Copying /home/olivier/.docker/machine/cache/boot2docker.iso to /home/olivier/.docker/machine/machines/local/boot2docker.iso...
(local) Creating VirtualBox VM...
(local) Creating SSH key...
(local) Starting the VM...
(local) Check network to re-create if needed...
(local) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: ./docker-machine-Linux-x86_64 env local

Now, we'll set the environment for running containers inside that VirtualBox guest (instead of the docker daemon on your host). Similar instructions as before:

./docker-machine-Linux-x86_64 env local
echo
eval "$(./docker-machine-Linux-x86_64 env local)"
echo
env | grep -i docker
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/olivier/.docker/machine/machines/local"
export DOCKER_MACHINE_NAME="local"
Run this command to configure your shell:
eval $(./docker-machine-Linux-x86_64 env local)

$
DOCKER_TLS_VERIFY=1
DOCKER_MACHINE_NAME=local
DOCKER_CERT_PATH=/home/olivier/.docker/machine/machines/local
DOCKER_HOST=tcp://192.168.99.100:2376

Now is the time to create a Swarm ID, also known as a "discovery token" via the Docker Swarm "discovery service" (there may be other ways to initiate the Swarm cluster). This is done by "executing" the swarm container (inside the local node).

docker run swarm create
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm


ebe0176dcf9a: Pulling fs layer 


19f771faa982: Pulling fs layer 


902eeedf931a: Pulling fs layer 

902eeedf931a: Downloading    125 B/125 B

902eeedf931a: Verifying Checksum 

902eeedf931a: Download complete 

19f771faa982: Downloading 16.38 kB/157.8 kB

19f771faa982: Downloading 157.8 kB/157.8 kB

19f771faa982: Verifying Checksum 

19f771faa982: Download complete 

ebe0176dcf9a: Downloading 49.15 kB/4.309 MB

ebe0176dcf9a: Downloading 457.9 kB/4.309 MB

ebe0176dcf9a: Downloading 949.4 kB/4.309 MB

ebe0176dcf9a: Downloading 1.392 MB/4.309 MB

ebe0176dcf9a: Downloading 1.883 MB/4.309 MB

ebe0176dcf9a: Downloading 2.473 MB/4.309 MB

ebe0176dcf9a: Downloading 3.014 MB/4.309 MB

ebe0176dcf9a: Downloading 3.505 MB/4.309 MB

ebe0176dcf9a: Downloading 4.046 MB/4.309 MB

ebe0176dcf9a: Verifying Checksum 

ebe0176dcf9a: Download complete 

ebe0176dcf9a: Extracting 65.54 kB/4.309 MB

ebe0176dcf9a: Extracting 2.163 MB/4.309 MB

ebe0176dcf9a: Extracting  4.26 MB/4.309 MB

ebe0176dcf9a: Extracting 4.309 MB/4.309 MB

ebe0176dcf9a: Extracting 4.309 MB/4.309 MB

ebe0176dcf9a: Pull complete 

19f771faa982: Extracting 32.77 kB/157.8 kB

19f771faa982: Extracting 157.8 kB/157.8 kB

19f771faa982: Extracting 157.8 kB/157.8 kB

19f771faa982: Pull complete 

902eeedf931a: Extracting    125 B/125 B

902eeedf931a: Extracting    125 B/125 B

902eeedf931a: Pull complete 
Digest: sha256:815fc8fd4617d866e1256999c2c0a55cc8f377f3dade26c3edde3f0543a70c04
Status: Downloaded newer image for swarm:latest
0360ff24c3119a7e1cadd439db981233

Copy the token displayed on the last line, to save it as an environment variable ($discotoken):

export discotoken=0360ff24c3119a7e1cadd439db981233

Now, we'll add the first (master) node in the Swarm cluster (swarm-manager machine), reusing the saved token (--swarm-discovery token://$discotoken):

./docker-machine-Linux-x86_64 create     -d virtualbox     --swarm     --swarm-master     --swarm-discovery token://$discotoken     swarm-manager
$ Running pre-create checks...
Creating machine...
(swarm-manager) Copying /home/olivier/.docker/machine/cache/boot2docker.iso to /home/olivier/.docker/machine/machines/swarm-manager/boot2docker.iso...
(swarm-manager) Creating VirtualBox VM...
(swarm-manager) Creating SSH key...
(swarm-manager) Starting the VM...
(swarm-manager) Check network to re-create if needed...
(swarm-manager) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Configuring swarm...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: ./docker-machine-Linux-x86_64 env swarm-manager

Then, let's add another node (node-01):

./docker-machine-Linux-x86_64 create \
    -d virtualbox \
    --swarm \
    --swarm-discovery token://$discotoken \
    node-01
$ > > > > Running pre-create checks...
Creating machine...
(node-01) Copying /home/olivier/.docker/machine/cache/boot2docker.iso to /home/olivier/.docker/machine/machines/node-01/boot2docker.iso...
(node-01) Creating VirtualBox VM...
(node-01) Creating SSH key...
(node-01) Starting the VM...
(node-01) Check network to re-create if needed...
(node-01) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Configuring swarm...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: ./docker-machine-Linux-x86_64 env node-01

Now, let's check the available machines :

./docker-machine-Linux-x86_64 ls
NAME            ACTIVE   DRIVER       STATE     URL                         SWARM                    DOCKER        ERRORS
local           *        virtualbox   Running   tcp://192.168.99.100:2376                            v17.05.0-ce   
node-01         -        virtualbox   Running   tcp://192.168.99.102:2376   swarm-manager            v17.05.0-ce   
swarm-manager   -        virtualbox   Running   tcp://192.168.99.101:2376   swarm-manager (master)   v17.05.0-ce

We can now set the environment to allow deployment over the Swarm cluster that was just created:

./docker-machine-Linux-x86_64 env --swarm swarm-manager
echo
eval "$(./docker-machine-Linux-x86_64 env --swarm swarm-manager)"
echo
env | grep -i docker
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.101:3376"
export DOCKER_CERT_PATH="/home/olivier/.docker/machine/machines/swarm-manager"
export DOCKER_MACHINE_NAME="swarm-manager"
Run this command to configure your shell:
eval $(./docker-machine-Linux-x86_64 env --swarm swarm-manager)

$
DOCKER_TLS_VERIFY=1
DOCKER_MACHINE_NAME=swarm-manager
DOCKER_CERT_PATH=/home/olivier/.docker/machine/machines/swarm-manager
DOCKER_HOST=tcp://192.168.99.101:3376

Let's then check the characteristics of that cluster (you may need to wait a bit before the 2 nodes appear in the cluster):

docker info
echo
docker ps -a
Containers: 3
 Running: 3
 Paused: 0
 Stopped: 0
Images: 2
Server Version: swarm/1.2.6
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint, whitelist
Nodes: 2
 node-01: 192.168.99.102:2376
  └ ID: UEQP:ZLT5:TAY6:AB5F:KCAY:M6UD:IJN3:XS25:UHLS:M7FX:EQ5J:LDRC
  └ Status: Healthy
  └ Containers: 1 (1 Running, 0 Paused, 0 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: kernelversion=4.4.66-boot2docker, operatingsystem=Boot2Docker 17.05.0-ce (TCL 7.2); HEAD : 5ed2840 - Fri May  5 21:04:09 UTC 2017, provider=virtualbox, storagedriver=aufs
  └ UpdatedAt: 2017-05-12T08:17:52Z
  └ ServerVersion: 17.05.0-ce
 swarm-manager: 192.168.99.101:2376
  └ ID: E233:ZWMB:ZEBR:CP5Y:NZZU:FK4R:LJBR:MC4M:POLZ:2JNM:4WOC:BXFL
  └ Status: Healthy
  └ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: kernelversion=4.4.66-boot2docker, operatingsystem=Boot2Docker 17.05.0-ce (TCL 7.2); HEAD : 5ed2840 - Fri May  5 21:04:09 UTC 2017, provider=virtualbox, storagedriver=aufs
  └ UpdatedAt: 2017-05-12T08:18:32Z
  └ ServerVersion: 17.05.0-ce
Plugins: 
 Volume: 
 Network: 
Swarm: 
 NodeID: 
 Is Manager: false
 Node Address: 
Kernel Version: 4.4.66-boot2docker
Operating System: linux
Architecture: amd64
CPUs: 2
Total Memory: 2.042 GiB
Name: 8633e84fff15
Docker Root Dir: 
Debug Mode (client): false
Debug Mode (server): false
WARNING: No kernel memory limit support
Experimental: false
Live Restore Enabled: false

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                     NAMES
5881290b472c        swarm:latest        "/swarm join --adv..."   2 minutes ago       Up 2 minutes        2375/tcp                                  node-01/swarm-agent
c648e8b7e7b6        swarm:latest        "/swarm join --adv..."   5 minutes ago       Up 5 minutes        2375/tcp                                  swarm-manager/swarm-agent
3376/tcp   swarm-manager/swarm-agent-master

We can now safely deploy a container on the cluster:

docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://cloud.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

3.1 Special case for users with homes over NFS

Our lab machines mount user homes over NFS, which means that the user's Docker directory is actually shared among machines, including ~/.docker/machine/ used by Docker Machine for storing nodes.

The nodes instanciations by Docker Machine may be better done on a local filesystem on the hosts, instead of that default dir, which would be storing the underlying boot2docker.iso files many times over NFS. Similarly, the .vmdk storage of the nodes may pose space and performance issues if it lives in NFS

Also you may be careful not to try and perform the same commands simultaneously on several machines in parallel with the same user. Otherwise, docker-machine won't really be able to distinguish different nodes running in different VirtualBox virtualizers, but named the same.

In short, you may set MACHINE_STORAGE_PATH globally to a value on a local disk (inside /tmp maybe ?) so that it doesn't use the default $HOME/.docker/machine. Alternatively you can provide the --storage-path / -s option to the docker-machine command.

4 Bonus step: Install Portainer monitoring

We'll install a Web dashboard to allow monitoring the Swarm cluster, called Portainer.

4.1 Install client certificates in the Swarm manager node

Identify the IP address of the master docker node in the cluster (swarm-manager):

./docker-machine-Linux-x86_64 ip swarm-manager
192.168.99.101

Save it to an env. variable ($managerip).

export managerip=192.168.99.101

You may test that you can succesfully connect to the Docker API of the cluster through TLS, using the cert:

curl "https://$managerip:3376/images/json" --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem
$ [{"Containers":-1,"Created":1484706726,"Id":"sha256:36b1e23becabc0b27c5787712dce019982c048665fd9e7e6cb032a46bcac510d","Labels":{},"ParentId":"","RepoDigests":["swarm@sha256:815fc8fd4617d866e1256999c2c0a55cc8f377f3dade26c3edde3f0543a70c04"],"RepoTags":["swarm:latest"],"SharedSize":-1,"Size":15852351,"VirtualSize":15852351},{"Containers":-1,"Created":1484347856,"Id":"sha256:48b5124b2768d2b917edcb640435044a97967015485e812545546cbed5cf0233","Labels":{},"ParentId":"","RepoDigests":["hello-world@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7"],"RepoTags":["hello-world:latest"],"SharedSize":-1,"Size":1840,"VirtualSize":1840}]

Now, copy that certificate and associate files over to the master node:

./docker-machine-Linux-x86_64 ssh swarm-manager rm -fr /home/docker/client-certs
./docker-machine-Linux-x86_64 ssh swarm-manager mkdir /home/docker/client-certs
./docker-machine-Linux-x86_64 scp $DOCKER_CERT_PATH/cert.pem swarm-manager:client-certs/cert.pem
./docker-machine-Linux-x86_64 scp $DOCKER_CERT_PATH/key.pem swarm-manager:client-certs/key.pem
./docker-machine-Linux-x86_64 scp $DOCKER_CERT_PATH/ca.pem swarm-manager:client-certs/ca.pem
$ $ 
cert.pem                                        0%    0     0.0KB/s   --:-- ETA
cert.pem                                      100% 1078     3.4MB/s   00:00
key.pem                                         0%    0     0.0KB/s   --:-- ETA
key.pem                                       100% 1679     1.3MB/s   00:00
ca.pem                                          0%    0     0.0KB/s   --:-- ETA
ca.pem                                        100% 1038     2.7MB/s   00:00

Now, check that connecting to the cluster indeed works, from the inside of the master node, over TLS:

./docker-machine-Linux-x86_64 ssh swarm-manager docker --tlsverify --tlscacert=/home/docker/client-certs/ca.pem --tlscert=/home/docker/client-certs/cert.pem --tlskey=/home/docker/client-certs/key.pem -H "tcp://$managerip:3376" info
$ Containers: 5
 Running: 3
 Paused: 0
 Stopped: 2
Images: 4
Server Version: swarm/1.2.6
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint, whitelist
Nodes: 2
 node-01: 192.168.99.102:2376
  └ ID: UEQP:ZLT5:TAY6:AB5F:KCAY:M6UD:IJN3:XS25:UHLS:M7FX:EQ5J:LDRC
  └ Status: Healthy
  └ Containers: 2 (1 Running, 0 Paused, 1 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: kernelversion=4.4.66-boot2docker, operatingsystem=Boot2Docker 17.05.0-ce (TCL 7.2); HEAD : 5ed2840 - Fri May  5 21:04:09 UTC 2017, provider=virtualbox, storagedriver=aufs
  └ UpdatedAt: 2017-05-12T08:27:30Z
  └ ServerVersion: 17.05.0-ce
 swarm-manager: 192.168.99.101:2376
  └ ID: E233:ZWMB:ZEBR:CP5Y:NZZU:FK4R:LJBR:MC4M:POLZ:2JNM:4WOC:BXFL
  └ Status: Healthy
  └ Containers: 3 (2 Running, 0 Paused, 1 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: kernelversion=4.4.66-boot2docker, operatingsystem=Boot2Docker 17.05.0-ce (TCL 7.2); HEAD : 5ed2840 - Fri May  5 21:04:09 UTC 2017, provider=virtualbox, storagedriver=aufs
  └ UpdatedAt: 2017-05-12T08:27:53Z
  └ ServerVersion: 17.05.0-ce
Plugins: 
 Volume: 
 Network: 
Swarm: 
 NodeID: 
 Is Manager: false
 Node Address: 
Kernel Version: 4.4.66-boot2docker
Operating System: linux
Architecture: amd64
CPUs: 2
Total Memory: 2.042GiB
Name: 8633e84fff15
Docker Root Dir: 
Debug Mode (client): false
Debug Mode (server): false
Experimental: false
Live Restore Enabled: false

WARNING: No kernel memory limit support

You can now deploy the Portainer container on the master node, so that it monitors the whole cluster:

./docker-machine-Linux-x86_64 ssh swarm-manager docker run -d -p 9000:9000 -v /home/docker/client-certs/:/client-certs portainer/portainer -H tcp://$managerip:3376 --tlsverify --tlscacert=/client-certs/ca.pem --tlscert=/client-certs/cert.pem --tlskey=/client-certs/key.pem
$ Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
a3ed95caeb02: Pulling fs layer
802d894958a2: Pulling fs layer
a64eb441970e: Pulling fs layer
802d894958a2: Verifying Checksum
802d894958a2: Download complete
a3ed95caeb02: Verifying Checksum
a3ed95caeb02: Download complete
a3ed95caeb02: Pull complete
802d894958a2: Pull complete
a64eb441970e: Verifying Checksum
a64eb441970e: Download complete
a64eb441970e: Pull complete
Digest: sha256:40bf7e42c9cd4b95ab70b9eca8c9b772e7ef65e78fa094ccb6f745e117b5237c
Status: Downloaded newer image for portainer/portainer:latest
b8ae2beee71adb371339f3824e7df044ae4ca2e2def5d4124dc403ffdcb0a537

And if all works, you get:

docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                           NAMES
9000/tcp   swarm-manager/nostalgic_keller

Now, you can connect to http://$managerip:9000/ in your preferred browser, and after creating an admin password, you'll be able to monitor your Swarm virtual cluster.

The Web interface of Portainer should display a Swarm entry in the left column, which proves that this worked.

5 Cleanup

./docker-machine-Linux-x86_64 kill node-01
./docker-machine-Linux-x86_64 rm -f node-01
./docker-machine-Linux-x86_64 kill swarm-manager
./docker-machine-Linux-x86_64 rm -f swarm-manager
./docker-machine-Linux-x86_64 kill local
./docker-machine-Linux-x86_64 rm -f local
./docker-machine-Linux-x86_64 kill default
./docker-machine-Linux-x86_64 rm -f default
Killing "node-01"...
Machine "node-01" was killed.
About to remove node-01
WARNING: This action will delete both local reference and remote instance.
Successfully removed node-01
Killing "swarm-manager"...
Machine "swarm-manager" was killed.
About to remove swarm-manager
WARNING: This action will delete both local reference and remote instance.
Successfully removed swarm-manager

6 About this document

This document was authored using the Literate DevOps approach using Org-Mode.

Source of the latest source : https://gitlab.com/olberger/experiments/tree/master

7 Todo

  1. Merge default and local which only result of merge of 2 docs : no justification
  2. Make sure that local is needed of whether it can be replaced by something else
  3. Fix org-mode babel
  4. Document tests of the cluster to show placement, etc.

Footnotes:

1

The notion of "official" package is relative to your viewpoint. Me being a Debian developer, I consider official Debian packages to be packages provided by the Debian project from debian.org. Others may consider official (docker) packages to be provided by Docker Inc (or a trusted third party) to be installed with dpkg (.deb format), thus compatible with Debian.

2

See About this document for a pointer to the source repository.

Author: Olivier Berger

Created: 2017-05-12 ven. 17:34

Validate