Deploy Traefik as Load Balancer

By | June 21, 2021

Introduction

Assume that you have already setup a Docker Swarm cluster, and now you can add a main Traefik (CE – Community Edition) as the Load Balancer/Proxy to:
– Expose specific services or applications based on their domain or DNS name or sub-domain.
– Automatic & Dynamic Routing (within container micro-services).
– Auto Discovery container services based on Docker Labels.
– …etc.
Overview:

  • In this lab, we will have more than 3 nodes, 3 nodes for managers and 2 nodes for workers. Note: Traefik needs to run on manager nodes because it will be able to get “/var/run/docker.sock” otherwise you need to configure docker swarm manager to run TCP mode instead.
  • In case, we will deploy Traefik (CE) on all manager nodes and configure/expose HTTPs/443 with self-signed certificate.
  • We will use basic authentication in order to access Traefik Dashboard.
  • For testing, we will deploy an application name “Whoami” on 2 worker nodes, let says 2 whoami containers running each worker nodes.

Prerequisites

  • LAB Specs
RoleHostnameIPOSAWS EC2
Swarm Manager-01swmgr-0110.0.0.109Ubuntu 20.04t2.micro
Swarm Manager-02swmgr-0210.0.0.74Ubuntu 20.04t2.micro
Swarm Manager-03swmgr-0310.0.0.218Ubuntu 20.04t2.micro
Swarm Worker-01swwkr-0110.0.0.247Ubuntu 20.04t2.micro
Swarm Worker-02swwkr-0210.0.0.176Ubuntu 20.04t2.micro
  • Generate self-signed certificate if you do not have your own public certificate
mkdir -p /srv/traefik/certs
cd /srv/traefik/certs/

# Make "openssl" installed or if not yet, run command:
sudo apt install openssl

# Create "Self-Signed SSL Certificate" with command:
openssl req -newkey rsa:4096 \
            -x509 \
            -sha256 \
            -days 3560 \
            -nodes \
            -out server.crt \
            -keyout server.key

# "-newkey rsa:4096": Creates a new certificate request and 4096 bit RSA key. The default one is 2048 bits.
# "-x509": Creates a X.509 Certificate.
# "-sha256": Use 265-bit SHA (Secure Hash Algorithm).
# "-days 3650": The number of days to certify the certificate for 3650 is ten years. you can set days as your prefer.
# "-nodes": Create a key without a passphrase.
# "-out server.crt": Specific the filename to write the newly create certificate.
# "-keyout server.key": Specific the filename to write the newly created private key.

chmod 400 *.{key,crt}
chmod 600 ../certs
  • Create docker secret to store those self-signed certificates (.key, .pem) on any manager node
docker secret create server-key /srv/traefik/certs/server.key
docker secret create server-crt /srv/traefik/certs/server.crt
docker secret ls
  • Create docker overlay network for “Traefik” as Load Balancer and name “traefik-net”
docker network create --attachable --driver overlay traefik-net
  • Generate a hash-password for Traefik Dashboard basic authentication
# echo $(htpasswd -nb <user> <secure_password>) | sed -e s/\\$/\\$\\$/g
echo $(htpasswd -nb tfadmin changeme) | sed -e s/\\$/\\$\\$/g

--> The result should be similar: tfadmin:$$apr1$$dQnzkAzD$$HWO8dGh/dy5Ocy0KvZh/k.

Deploy Traefik as Load Balancer

  • Create main Traefik Configuration with YAML file
cd /srv/traefik/
cat <<'EOF' | sudo tee traefik.yml
## STATIC CONFIG (restart traefik to update)
# shows you a log msg if a newer image tag can be used
global:
  checkNewVersion: true

# log default is ERROR, but WARN is more helpful
log:
  level: WARN
  # level: INFO

# enable dashboard on 8080 with NO AUTH
api:
  insecure: true
  dashboard: true

# enable ping so the `traefik healthcheck` works
ping: {}

# auto-proxy containers if they have proper labels
# and also use this file for dynamic config (tls)
providers:
  docker:
    swarmMode: true
    exposedByDefault: false
    watch: true
  file:
    fileName: /etc/traefik/traefik.yml
    watch: true

# listen on 80/443, and redirect all 80 to 443 via 301
entryPoints:
  web:
    address: :80
    # comment out these lins if you don't want to redirect everything
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
          permanent: true
  websecure:
    address: :443

## DYNAMIC CONFIG
tls:
  certificates:
    - certFile: /certs/server.crt
      keyFile: /certs/server.key
  options:
    default:
      sniStrict: true
EOF
  • Create Docker Compose file to deploy Traefik
cd /srv/traefik/
cat <<'EOF' | sudo tee docker-compose.yml
version: "3.7"

networks:
  traefik-net:
    external: true

configs:
  traefik_yml:
    file: ./traefik.yml

secrets:
  server-key:
    external: true
  server-crt:
    external: true

services:
  traefik:
    image: traefik:v2.4.8
    deploy:
        mode: global
        restart_policy:
          condition: on-failure
        update_config:
          parallelism: 1
          delay: 10s
        placement:
          constraints:
            - node.role == manager
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.traefik-dashboard.tls=true"
            - "traefik.http.routers.traefik-dashboard.entrypoints=websecure"
            - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik-dashboard.lab.local`)"
            - "traefik.http.routers.traefik-dashboard.service=api@internal"
            - "traefik.http.routers.traefik-dashboard.middlewares=tfdash-auth"
            - "traefik.http.middlewares.tfdash-auth.basicauth.users=tfadmin:$$apr1$$dQnzkAzD$$HWO8dGh/dy5Ocy0KvZh/k." # generate your own credential echo $(htpasswd -nb <user> <secure_password>) | sed -e s/\\$/\\$\\$/g
            # Dummy service for Swarm port detection. The port can be any valid integer value.
            - "traefik.http.services.traefik-dashboard.loadbalancer.server.port=9999"
    healthcheck:
      test:
        - CMD
        - traefik
        - healthcheck
      interval: 10s
      timeout: 5s
      retries: 3
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    networks:
      - traefik-net
    configs:
      - source: traefik_yml
        target: /etc/traefik/traefik.yml
        mode: 0440
    secrets:
      - source: server-key
        target: /certs/server.key
        mode: 0440
      - source: server-crt
        target: /certs/server.crt
        mode: 0440
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
EOF
  • Start deploy Traefik stack with stack named “traefik”
cd /srv/traefik/
docker stack deploy -c docker-compose.yml traefik
  • Verify the deployment
docker stack ls
docker service ls
docker service logs -ft traefik_traefik
docker service ps traefik_traefik

Testing

To test, you can set your host file or DNS name point to any of manager node(s). In case we use AWS EC2 then there are 3 Public IPv4 addresses (temporarily):
– 54.179.128.50 –> swmgr-01
– 13.212.142.91 –> swmgr-02
– 54.255.152.199 –> swmgr-03

To access dashboard, we can set host file named “traefik-dashboard.lab.local” point to any above manager public IPv4 with basic authentication:

Deploy Whoami application as the following:

mkdir -p /srv/whoami
cd /srv/whoami/
cat <<'EOF' | sudo tee docker-compose.yml
version: '3.7'

networks:
  traefik-net:
    external: true

services:
  whoami:
    image: containous/whoami:latest
    networks:
      - traefik-net
    deploy:
      mode: replicated
      replicas: 4
      restart_policy:
        condition: on-failure
      update_config:
        parallelism: 1
        delay: 10s
      placement:
        constraints:
          - node.role == worker
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.entrypoints=websecure"
        - "traefik.http.routers.whoami.tls=true"
        - "traefik.http.routers.whoami.rule=Host(`whoami.lab.local`)"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"
EOF
  • To deploy Whoami Application and replicates as 4 containers on worker nodes, run the command:
cd /srv/whoami/
docker stack deploy -c docker-compose.yml whoami
  • To verify Whoami application deployment
docker stack ls
docker service ls
docker service ps whoami_whoami
  • Now if we shutdown, swwkr-02, Whoami containers will startup all on swwrk-01 without interruption.
  • Now if we shutdown swmgr-01, Traefik Load balancer service will be still running. But note we need to re-set host file address again by pointing to any available manager nodes.

Thanks!

Leave a Reply

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