@lucjuggery
Published in

@lucjuggery

Docker Cloud’s Swarm mode feature

TL;DR

About Docker Cloud

  • “legacy”: it allows to manage single host or cluster but does not involves Swarm
  • Swarm mode: still in beta, it allows to manage native Docker Swarm clusters (currently free while in beta :) ).
Docker Cloud legacy mode vs Swarm mode

Setup the link with AWS

Creation of the Swarm

  • link Docker Cloud to an existing Swarm
  • create a new Swarm
  • selection of the cloud provider
  • selection of the region
  • size of the Swarm: we will go for a little 3 nodes cluster. We will define each node as a master to have a production like setup. By default, a master node is also a worker.

Behind the hood

  • VPC
  • Load Balancer
  • security groups
$ ssh -i PATH_TO_SSH_KEY docker@NODE_EXTERNAL_DNS
Welcome to Docker!

Accessing the Swarm

  • run a container locally based on the dockercloud/client image
  • using directly Docker for Mac or Docker for Windows to connect to the Swarm from the Desktop.

Deploying an application

version: "3"
services:

redis:
image: redis:alpine
ports:
- "6379"
networks:
- frontend
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
deploy:
placement:
constraints: [node.role == manager]
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- 5000:80
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- 5001:80
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure

worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints: [node.role == manager]

visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]

networks:
frontend:
external: true
backend:
external: true


volumes:
db-data:

Creation of the networks

[swarm01] ~ $ docker network create --driver overlay frontend
[swarm01] ~ $ docker network create --driver overlay backend

Deployment of the stack

[swarm01] ~ $ docker stack deploy -c docker-stack.yml voting
Creating network voting_default
Creating service voting_worker
Creating service voting_visualizer
Creating service voting_redis
Creating service voting_db
Creating service voting_vote
Creating service voting_result
  • 5000: voting interface
  • 5001: result interface
  • 8080: visualizer which provides a clean visualisation of the repartition of the tasks across the nodes

Pointing a domain name to our Swarm

result 10800 IN CNAME swarm01-XXX.eu-west-1.elb.amazonaws.com.
viz 10800 IN CNAME swarm01-XXX.eu-west-1.elb.amazonaws.com.
vote 10800 IN CNAME swarm01-XXX.eu-west-1.elb.amazonaws.com.

Setup a TLS termination with Traefik

  • setting up the TLS certificates through Let’s Encrypt
  • forwarding the traffic to the correct backend service based on rules on the Host header of the incoming requests

Traefik configuration

  • debug level (just in case)
  • address of the Traefik web interface
  • definition of 2 entrypoints, http and https. Traffic on http is automatically redirected to https
  • declaration of the backend used: swarm mode here
  • Let’s Encrypt configuration: Traefik will automatically get certificates for the domains listed
# traefik.toml# Global configuration
debug = true
logLevel = "DEBUG"
# Web configuration backend
[web]
address = ":8080"
# Entrypoints
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
# Docker configuration backend
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "lucarea.com"
watch = true
swarmmode = true
exposedbydefault = false
# Let’s Encrypt configuration
[acme]
email = "xxx"
storageFile = "acme.json"
entryPoint = "https"
[[acme.domains]]
main = "lucarea.com"
sans = ["vote.lucarea.com","result.lucarea.com","viz.lucarea.com"]
# Dockerfile
FROM traefik:1.3.5
COPY traefik.toml /etc/traefik/traefik.toml
$ docker image build -t lucj/voting-proxy:1.0 .
Sending build context to Docker daemon 3.584kB
Step 1/2 : FROM traefik:1.3.5
1.3.5: Pulling from library/traefik
df350fade9bb: Pull complete
16fac1cc7b67: Pull complete
Digest: sha256:f502c5f275f1518dcc27e63d7733b9c654a8f8ecfda2c41bacca687f20131eaa
Status: Downloaded newer image for traefik:1.3.5
---> 088bcecd63de
Step 2/2 : COPY traefik.toml /etc/traefik/traefik.toml
---> e8853944ed06
Removing intermediate container 15c8ed650f68
Successfully built e8853944ed06
Successfully tagged lucj/voting-proxy:1.0
$ docker image push lucj/voting-proxy:1.0
The push refers to a repository [docker.io/lucj/voting-proxy]
c40d8a836fbc: Pushed
15ab91aee858: Mounted from library/traefik
3b10c345cfdd: Mounted from library/traefik
1.0: digest: sha256:c67b887681c24ba3...768736cb28bb size: 946

Traefik service

# traefik.yamlversion: "3.3"
services:
traefik:
image: lucj/voting-proxy:1.0
networks:
— frontend
ports:
— "80:80"
— "443:443"
- "8081:8080"
volumes:
— /var/run/docker.sock:/var/run/docker.sock
deploy:
replicas: 1
labels:
— "traefik.enable=true"
placement:
constraints: [node.role == manager]
restart_policy:
condition: on-failure
networks:
frontend:
external: true

Adding Traefik’s labels to the services

vote:
image: dockersamples/examplevotingapp_vote:before
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host:vote.lucarea.com"
- "traefik.frontend.entryPoints=http,https"
- "traefik.backend=vote"
- "traefik.port=5000"

update_config:
parallelism: 2
restart_policy:
condition: on-failure

Putting everything together

$ docker stack deploy -c docker-stack.yaml voting$ docker stack deploy -c traefik.yaml tls

Delete the Swarm

Summary

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Luc Juggery

Docker & Kubernetes trainer (CKA / CKAD), 中文学生, Learning&Sharing