Docker Swarm (mode) cluster

This section explains how to create a multi-host docker cluster with swarm mode using docker-machine and how to deploy Træfɪk on it.

The cluster consists of:

  • 3 servers
  • 1 manager
  • 2 workers
  • 1 overlay network (multi-host networking)

Prerequisites

Cluster provisioning

First, let's create all the required nodes. It's a shorter version of the swarm tutorial.

  1. docker-machine create -d virtualbox manager
  2. docker-machine create -d virtualbox worker1
  3. docker-machine create -d virtualbox worker2

Then, let's setup the cluster, in order :

  • initialize the cluster
  • get the token for other host to join
  • on both workers, join the cluster with the token
  1. docker-machine ssh manager "docker swarm init \
  2. --listen-addr $(docker-machine ip manager) \
  3. --advertise-addr $(docker-machine ip manager)"
  4. export worker_token=$(docker-machine ssh manager "docker swarm \
  5. join-token worker -q")
  6. docker-machine ssh worker1 "docker swarm join \
  7. --token=${worker_token} \
  8. --listen-addr $(docker-machine ip worker1) \
  9. --advertise-addr $(docker-machine ip worker1) \
  10. $(docker-machine ip manager)"
  11. docker-machine ssh worker2 "docker swarm join \
  12. --token=${worker_token} \
  13. --listen-addr $(docker-machine ip worker2) \
  14. --advertise-addr $(docker-machine ip worker2) \
  15. $(docker-machine ip manager)"

Let's validate the cluster is up and running.

  1. docker-machine ssh manager docker node ls
  2. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
  3. 2a770ov9vixeadep674265u1n worker1 Ready Active
  4. dbi3or4q8ii8elbws70g4hkdh * manager Ready Active Leader
  5. esbhhy6vnqv90xomjaomdgy46 worker2 Ready Active

Finally, let's create a network for Træfik to use.

  1. docker-machine ssh manager "docker network create --driver=overlay traefik-net"

Deploy Træfik

Let's deploy Træfik as a docker service in our cluster. The only requirement for Træfik to work with swarm mode is that it needs to run on a manager node — we are going to use a constraint for that.

  1. docker-machine ssh manager "docker service create \
  2. --name traefik \
  3. --constraint=node.role==manager \
  4. --publish 80:80 --publish 8080:8080 \
  5. --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  6. --network traefik-net \
  7. traefik \
  8. --docker \
  9. --docker.swarmmode \
  10. --docker.domain=traefik \
  11. --docker.watch \
  12. --web"

Let's explain this command:

  • —publish 80:80 —publish 8080:8080: we publish port 80 and 8080 on the cluster.
  • —constraint=node.role==manager: we ask docker to schedule Træfik on a manager node.
  • —mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock: we bind mount the docker socket where Træfik is scheduled to be able to speak to the daemon.
  • —network traefik-net: we attach the Træfik service (and thus the underlying container) to the traefik-net network.
  • —docker: enable docker backend, and —docker.swarmmode to enable the swarm mode on Træfik.
  • —web: activate the webUI on port 8080

Deploy your apps

We can now deploy our app on the cluster, here whoami, a simple web server in Go. We start 2 services, on the traefik-net network.

  1. docker-machine ssh manager "docker service create \
  2. --name whoami0 \
  3. --label traefik.port=80 \
  4. --network traefik-net \
  5. emilevauge/whoami"
  6. docker-machine ssh manager "docker service create \
  7. --name whoami1 \
  8. --label traefik.port=80 \
  9. --network traefik-net \
  10. --label traefik.backend.loadbalancer.sticky=true \
  11. emilevauge/whoami"

Note that we set whoami1 to use sticky sessions (—label traefik.backend.loadbalancer.sticky=true). We'll demonstrate that later. If using docker stack deploy, there is a specific way that the labels must be defined in the docker-compose file.

Check that everything is scheduled and started:

  1. docker-machine ssh manager "docker service ls"
  2. ID NAME REPLICAS IMAGE COMMAND
  3. ab046gpaqtln whoami0 1/1 emilevauge/whoami
  4. cgfg5ifzrpgm whoami1 1/1 emilevauge/whoami
  5. dtpl249tfghc traefik 1/1 traefik --docker --docker.swarmmode --docker.domain=traefik --docker.watch --web

Access to your apps through Træfɪk

  1. curl -H Host:whoami0.traefik http://$(docker-machine ip manager)
  2. Hostname: 8147a7746e7a
  3. IP: 127.0.0.1
  4. IP: ::1
  5. IP: 10.0.9.3
  6. IP: fe80::42:aff:fe00:903
  7. IP: 172.18.0.3
  8. IP: fe80::42:acff:fe12:3
  9. GET / HTTP/1.1
  10. Host: 10.0.9.3:80
  11. User-Agent: curl/7.35.0
  12. Accept: */*
  13. Accept-Encoding: gzip
  14. X-Forwarded-For: 192.168.99.1
  15. X-Forwarded-Host: 10.0.9.3:80
  16. X-Forwarded-Proto: http
  17. X-Forwarded-Server: 8fbc39271b4c
  18. curl -H Host:whoami1.traefik http://$(docker-machine ip manager)
  19. Hostname: ba2c21488299
  20. IP: 127.0.0.1
  21. IP: ::1
  22. IP: 10.0.9.4
  23. IP: fe80::42:aff:fe00:904
  24. IP: 172.18.0.2
  25. IP: fe80::42:acff:fe12:2
  26. GET / HTTP/1.1
  27. Host: 10.0.9.4:80
  28. User-Agent: curl/7.35.0
  29. Accept: */*
  30. Accept-Encoding: gzip
  31. X-Forwarded-For: 192.168.99.1
  32. X-Forwarded-Host: 10.0.9.4:80
  33. X-Forwarded-Proto: http
  34. X-Forwarded-Server: 8fbc39271b4c

Note that as Træfik is published, you can access it from any machine and not only the manager.

  1. curl -H Host:whoami0.traefik http://$(docker-machine ip worker1)
  2. Hostname: 8147a7746e7a
  3. IP: 127.0.0.1
  4. IP: ::1
  5. IP: 10.0.9.3
  6. IP: fe80::42:aff:fe00:903
  7. IP: 172.18.0.3
  8. IP: fe80::42:acff:fe12:3
  9. GET / HTTP/1.1
  10. Host: 10.0.9.3:80
  11. User-Agent: curl/7.35.0
  12. Accept: */*
  13. Accept-Encoding: gzip
  14. X-Forwarded-For: 192.168.99.1
  15. X-Forwarded-Host: 10.0.9.3:80
  16. X-Forwarded-Proto: http
  17. X-Forwarded-Server: 8fbc39271b4c
  18. curl -H Host:whoami1.traefik http://$(docker-machine ip worker2)
  19. Hostname: ba2c21488299
  20. IP: 127.0.0.1
  21. IP: ::1
  22. IP: 10.0.9.4
  23. IP: fe80::42:aff:fe00:904
  24. IP: 172.18.0.2
  25. IP: fe80::42:acff:fe12:2
  26. GET / HTTP/1.1
  27. Host: 10.0.9.4:80
  28. User-Agent: curl/7.35.0
  29. Accept: */*
  30. Accept-Encoding: gzip
  31. X-Forwarded-For: 192.168.99.1
  32. X-Forwarded-Host: 10.0.9.4:80
  33. X-Forwarded-Proto: http
  34. X-Forwarded-Server: 8fbc39271b4c

Scale both services

  1. docker-machine ssh manager "docker service scale whoami0=5"
  2. docker-machine ssh manager "docker service scale whoami1=5"

Check that we now have 5 replicas of each whoami service:

  1. docker-machine ssh manager "docker service ls"
  2. ID NAME REPLICAS IMAGE COMMAND
  3. ab046gpaqtln whoami0 5/5 emilevauge/whoami
  4. cgfg5ifzrpgm whoami1 5/5 emilevauge/whoami
  5. dtpl249tfghc traefik 1/1 traefik --docker --docker.swarmmode --docker.domain=traefik --docker.watch --web

Access to your whoami0 through Træfɪk multiple times.

Repeat the following command multiple times and note that the Hostname changes each time as Traefik load balances each request against the 5 tasks.

  1. curl -H Host:whoami0.traefik http://$(docker-machine ip manager)
  2. Hostname: 8147a7746e7a
  3. IP: 127.0.0.1
  4. IP: ::1
  5. IP: 10.0.9.3
  6. IP: fe80::42:aff:fe00:903
  7. IP: 172.18.0.3
  8. IP: fe80::42:acff:fe12:3
  9. GET / HTTP/1.1
  10. Host: 10.0.9.3:80
  11. User-Agent: curl/7.35.0
  12. Accept: */*
  13. Accept-Encoding: gzip
  14. X-Forwarded-For: 192.168.99.1
  15. X-Forwarded-Host: 10.0.9.3:80
  16. X-Forwarded-Proto: http
  17. X-Forwarded-Server: 8fbc39271b4c

Do the same against whoami1.

  1. curl -H Host:whoami1.traefik http://$(docker-machine ip manager)
  2. Hostname: ba2c21488299
  3. IP: 127.0.0.1
  4. IP: ::1
  5. IP: 10.0.9.4
  6. IP: fe80::42:aff:fe00:904
  7. IP: 172.18.0.2
  8. IP: fe80::42:acff:fe12:2
  9. GET / HTTP/1.1
  10. Host: 10.0.9.4:80
  11. User-Agent: curl/7.35.0
  12. Accept: */*
  13. Accept-Encoding: gzip
  14. X-Forwarded-For: 192.168.99.1
  15. X-Forwarded-Host: 10.0.9.4:80
  16. X-Forwarded-Proto: http
  17. X-Forwarded-Server: 8fbc39271b4c

Wait, I thought we added the sticky flag to whoami1? Traefik relies on a cookie to maintain stickyness so you'll need to test this with a browser.

First you need to add whoami1.traefik to your hosts file:

  1. if [ -n "$(grep whoami1.traefik /etc/hosts)" ];
  2. then
  3. echo "whoami1.traefik already exists (make sure the ip is current)";
  4. else
  5. sudo -- sh -c -e "echo '$(docker-machine ip manager)\twhoami1.traefik'
  6. >> /etc/hosts";
  7. fi

Now open your browser and go to http://whoami1.traefik/

You will now see that stickyness is maintained.

Swarm mode 集群 - 图1