# Swarm cluster This section explains how to create a multi-host [swarm](https://docs.docker.com/swarm) cluster using [docker-machine](https://docs.docker.com/machine/) and how to deploy Traefik on it. The cluster consists of: - 2 servers - 1 swarm master - 2 swarm nodes - 1 [overlay](https://docs.docker.com/network/overlay/) network (multi-host networking) ## Prerequisites 1. You need to install [docker-machine](https://docs.docker.com/machine/) 2. You need the latest [VirtualBox](https://www.virtualbox.org/wiki/Downloads) ## Cluster provisioning We first follow [this guide](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) to create the cluster. ### Create machine `mh-keystore` This machine is the service registry of our cluster. ```shell docker-machine create -d virtualbox mh-keystore ``` Then we install the service registry [Consul](https://consul.io) on this machine: ```shell eval "$(docker-machine env mh-keystore)" docker run -d \ -p "8500:8500" \ -h "consul" \ progrium/consul -server -bootstrap ``` ### Create machine `mhs-demo0` This machine is a swarm master and a swarm agent on it. ```shell docker-machine create -d virtualbox \ --swarm --swarm-master \ --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \ --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \ --engine-opt="cluster-advertise=eth1:2376" \ mhs-demo0 ``` ### Create machine `mhs-demo1` This machine have a swarm agent on it. ```shell docker-machine create -d virtualbox \ --swarm \ --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \ --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \ --engine-opt="cluster-advertise=eth1:2376" \ mhs-demo1 ``` ### Create the overlay Network Create the overlay network on the swarm master: ```shell eval $(docker-machine env --swarm mhs-demo0) docker network create --driver overlay --subnet=10.0.9.0/24 my-net ``` ## Deploy Traefik Deploy Traefik: ```shell docker $(docker-machine config mhs-demo0) run \ -d \ -p 80:80 -p 8080:8080 \ --net=my-net \ -v /var/lib/boot2docker/:/ssl \ traefik \ -l DEBUG \ -c /dev/null \ --docker \ --docker.domain=traefik \ --docker.endpoint=tcp://$(docker-machine ip mhs-demo0):2376 \ --docker.tls \ --docker.tls.ca=/ssl/ca.pem \ --docker.tls.cert=/ssl/server.pem \ --docker.tls.key=/ssl/server-key.pem \ --docker.tls.insecureSkipVerify \ --docker.watch \ --api ``` Let's explain this command: | Option | Description | |-------------------------------------------|---------------------------------------------------------------| | `-p 80:80 -p 8080:8080` | we bind ports 80 and 8080 | | `--net=my-net` | run the container on the network my-net | | `-v /var/lib/boot2docker/:/ssl` | mount the ssl keys generated by docker-machine | | `-c /dev/null` | empty config file | | `--docker` | enable docker provider | | `--docker.endpoint=tcp://172.18.0.1:2376` | connect to the swarm master using the docker_gwbridge network | | `--docker.tls` | enable TLS using the docker-machine keys | | `--api` | activate the webUI on port 8080 | ## Deploy your apps We can now deploy our app on the cluster, here [whoami](https://github.com/containous/whoami), a simple web server in GO, on the network `my-net`: ```shell eval $(docker-machine env --swarm mhs-demo0) docker run -d --name=whoami0 --net=my-net --env="constraint:node==mhs-demo0" containous/whoami docker run -d --name=whoami1 --net=my-net --env="constraint:node==mhs-demo1" containous/whoami ``` Check that everything is started: ```shell docker ps ``` ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba2c21488299 containous/whoami "/whoamI" 8 seconds ago Up 9 seconds 80/tcp mhs-demo1/whoami1 8147a7746e7a containous/whoami "/whoamI" 19 seconds ago Up 20 seconds 80/tcp mhs-demo0/whoami0 8fbc39271b4c traefik "/traefik -l DEBUG -c" 36 seconds ago Up 37 seconds 192.168.99.101:80->80/tcp, 192.168.99.101:8080->8080/tcp mhs-demo0/serene_bhabha ``` ## Access to your apps through Traefik ```shell curl -H Host:whoami0.traefik http://$(docker-machine ip mhs-demo0) ``` ```yaml Hostname: 8147a7746e7a IP: 127.0.0.1 IP: ::1 IP: 10.0.9.3 IP: fe80::42:aff:fe00:903 IP: 172.18.0.3 IP: fe80::42:acff:fe12:3 GET / HTTP/1.1 Host: 10.0.9.3:80 User-Agent: curl/7.35.0 Accept: */* Accept-Encoding: gzip X-Forwarded-For: 192.168.99.1 X-Forwarded-Host: 10.0.9.3:80 X-Forwarded-Proto: http X-Forwarded-Server: 8fbc39271b4c ``` ```shell curl -H Host:whoami1.traefik http://$(docker-machine ip mhs-demo0) ``` ```yaml Hostname: ba2c21488299 IP: 127.0.0.1 IP: ::1 IP: 10.0.9.4 IP: fe80::42:aff:fe00:904 IP: 172.18.0.2 IP: fe80::42:acff:fe12:2 GET / HTTP/1.1 Host: 10.0.9.4:80 User-Agent: curl/7.35.0 Accept: */* Accept-Encoding: gzip X-Forwarded-For: 192.168.99.1 X-Forwarded-Host: 10.0.9.4:80 X-Forwarded-Proto: http X-Forwarded-Server: 8fbc39271b4c ``` ![GIF Magica](https://i.giphy.com/ujUdrdpX7Ok5W.gif)