October 21, 2020

Out Here In The Fields

…of musings and ramblings

Docker Swarm Load Balancing and SSL Termination with Traefik

5 min read

Update September 22nd 2019:

It seems that traefik has recently updated their docker registry, in such that when you do pull request will get you traefik version 2.0 by default instead the previous stable version 1.7.xx. Since the article below uses configuration that is applicable for 1.7.x, I have made some update to all pull request in this article to use v1.7.16 to ensure that commands or scripts contained in this article will still work. Check Traefik’s docker page to see the latest version for 1.7.xx branch

If you have read my previous post on Docker Swarm and HAProxy, this post will be more of the same, but with traefik instead of DockerCloud HAProxy serving as front end load-balancer and SSL termination. Also, instead of docker-compose scripts, I’ll be using docker command line to bring up the network and services.

Prerequisite & Host preparations

My post on Docker Swarm and HAProxy contains most parts of preparing the prerequisites, such as:

Additional step is required to prepare Let’s Encrypt SSL certificate to be used by Traefik. Do the following:

surfer@M5Dock02:~$ sudo mkdir /app/certs/traefik/
surfer@M5Dock02:~$ sudo cp /etc/letsencrypt/live/dockers.mach5.web.id/cert.pem /app/certs/traefik/
surfer@M5Dock02:~$ sudo cp /etc/letsencrypt/live/dockers.mach5.web.id/privkey.pem /app/certs/traefik/

Adjust accordingly if you’re using a a CA provided or self-signed certificate

Configuring Traefik

Do

surfer@M5Dock02:~$ sudo mkdir /app/conf/traefik/
surfer@M5Dock02:~$ sudo nano /app/conf/traefik/traefik.toml

on traefik.toml, we’ll be configuring the SSL termination and http to https redirection. Here’s how mine looks like:

logLevel = "DEBUG"
defaultEntryPoints = ["http", "https"]

# WEB interface of Traefik - it will show web page with overview of frontend and backend configurations
[web]
address = ":8080"
certFile="/certs/cert.pem"
keyFile="/certs/privkey.pem"
[web.auth.basic]
usersFile="/conf/.htpasswd"
# Connection to docker host system (docker.sock)
[docker]
swarmmode = true
domain = "dockers.mach5.web.id"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false


[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]
      [[entryPoints.https.tls.certificates]]
      certFile = "/certs/cert.pem"
      keyFile = "/certs/privkey.pem"

The traefik provides dashboard than can be used to monitor the health and performance of your nodes. We will be  securing the dashboard with a basic .htpasswd that you can create here, and put into “/apps/conf/traefik” directory on the first VM.

surfer@M5Dock02:/app/conf/traefik$ ls -lat
total 16
drwxr-xr-x 2 root root 4096 Jun 22 18:10 .
-rw-r--r-- 1 root root   44 Jun 22 18:10 .htpasswd
-rw-r--r-- 1 root root  824 Jun 17 07:58 traefik.toml
drwxr-xr-x 4 root root 4096 Jun 11 08:01 ..
Bringing up the network and services

First the network. Since the hosts hosting the containers will be spanned over multiple nodes, we will need to use the overlay driver

surfer@M5Dock02:~$ sudo docker network create --driver=overlay web
odyg9lhk3nms3hyx9vi50n7sj

The first service we will bring up is the application service. For the purpose of this post, we will be using tomcat

surfer@M5Dock02:~$ sudo docker service create --name tcserv --network web --label traefik.enable=true --label traefik.backend=tcserv --label traefik.port=8080 --label traefik.frontend.rule=Host:dockers.mach5.web.id --label traefik.backend.loadbalancer.stickiness=true --mount type=bind,src=/app/conf/tomcat/server.xml,dst=/usr/local/tomcat/conf/server.xml --mount type=bind,src=/app/logs,dst=/usr/local/tomcat/logs --mount type=bind,src=/app/webapps,dst=/usr/local/tomcat/webapps tomcat
k3yeseal9n0xwbuz1o0j56zgw
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged

The most important line from the command above are  the “–label”

  • –label traefik.enable=true tells our traefik service that the containers in the service are enabled in traefik
  • –label traefik.backend=tcserv tells traefik that the backend service is named “tcserv”
  • –label traefik.port=8080 tells traefik that the containers are serving the application through port 8080
  • –label traefik.frontend.rule=Host:dockers.ready.web.id tells traefik that requests to the particular domain should be forwarded to the containers in the service
  • –label traefik.backend.loadbalancer.stickiness=true tells traefik that sticky session is active for the containers in the service

Let see if we have managed to spawn a service

surfer@M5Dock02:~$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
k3yeseal9n0x        tcserv              replicated          1/1                 tomcat:latest

..And see if the container is up

surfer@M5Dock02:~$ sudo docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
zco5lu92ozm10igs78tvviv23 *   M5Dock01            Ready               Active              Leader              18.09.5
uqqw3e2bbmxh7ch6ewocrzhz3     M5Dock02            Ready               Active                                  18.09.5
surfer@M5Dock02:~$ sudo docker node ps
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE       ERROR               PORTS
surfer@M5Dock02:~$ sudo docker node ps M5Dock01
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE       ERROR               PORTS
surfer@M5Dock02:~$ sudo docker node ps M5Dock02
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
iq8jr1z7msfj        tcserv.1            tomcat:latest       M5Dock03            Running             Running 9 minutes ago   

The next service we need to create is the one hosting the traefik loadbalancer

surfer@M5Dock02:~$ sudo docker service create --name traefik --constraint=node.role==manager --publish 443:443 --publish 8080:8080 --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock  --mount type=bind,source=/app/conf/traefik/traefik.toml,target=/traefik.toml --mount type=bind,source=/app/conf/traefik/,target=/conf --mount type=bind,source=/app/certs/traefik/,target=/certs --network web traefik:v1.7.16
vdk2liq2cjjhrjmj1bbuf1wym
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged

The command above should spawn a traefik container. Pay attention to the “–mount” option and ensure the container uses docker.sock from the host so that it can discover and recognize other containers in the swarm and it uses the traefik.toml that we have previously created.

surfer@M5Dock02:~$ sudo docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
k3yeseal9n0x        tcserv              replicated          1/1                 tomcat:latest       
vdk2liq2cjjh        traefik             replicated          1/1                 traefik:latest      *:443->443/tcp, *:8080->8080/tcp

As you can see, we should now have 2 services, one for tomcat and another for traefik. See if application can be accessed through traefik

And see if the dashboard is up. Type in the user and password that we have previously configured on the .htpasswd file:

The dashboard will show information regarding the frontend and backend services

Now, let’s scale tcserv to add more containers

surfer@M5Dock02:~$ sudo docker service scale tcserv=10
tcserv scaled to 10
overall progress: 10 out of 10 tasks 
1/10: running   [==================================================>] 
2/10: running   [==================================================>] 
3/10: running   [==================================================>] 
4/10: running   [==================================================>] 
5/10: running   [==================================================>] 
6/10: running   [==================================================>] 
7/10: running   [==================================================>] 
8/10: running   [==================================================>] 
9/10: running   [==================================================>] 
10/10: running   [==================================================>] 
verify: Service converged

And check the dashboard whether they are recognized

Great!

Now, can someone translate this to a docker compose script?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Copyright © All rights reserved. | Newsphere by AF themes.