traefik

Traefik 2.0: Cloud Native Edge Router for Containers

Traefik is a cloud-native reverse proxy/load balancer that makes deploying micro-services easy, it automatically discovers the right configuration for the services that are going to deploy, which makes Traefik more popular, besides its many features.

In my previous post, I explained how to set up / build a docker swarm cluster in Azure on Ubuntu with GlusterFS as persistent storage to host container-based micro-services. In this post, I am going to show you how to deploy Traefik in the Docker Swarm Cluster using docker-compose to act as a Reverse Proxy and Load Balancer for the micro-services.

Traefik is a cloud-native reverse proxy/load balancer that makes deploying micro-services easy, it automatically discovers the right configuration for the services that are going to deploy, which makes Traefik more popular, besides its many features.

In my previous post, I explained how to set up / build a Docker Swarm Cluster in Azure on Ubuntu with GlusterFS as persistent storage to host container-based micro-services.

In this post, I am going to show you how to deploy Traefik in the Docker Swarm Cluster using docker-compose to act as a Reverse Proxy and Load Balancer for the micro-services.

Traefik Introduction

Traefik is a modern HTTP reverse proxy and load balancer that makes deploying micro-services easy. Traefik integrates with most of the existing infrastructure components (DockerSwarm modeKubernetesMarathonConsulEtcdRancherAmazon ECS) and configures itself automatically and dynamically. (It even works for legacy software running on bare metal.)

Traefik Architecture

Traefik automatically discovers the right configuration for the services who are going to deploy, which makes Traefik more popular, besides its many features. The magic happens when Traefik inspects our infrastructure, where it finds relevant information and discovers which service serves which request.

Follow the below links if you want to know more about Traefik

Github

Traefik Docs

Traefik Flavors

You can install Traefik with the following flavors:

I used the official docker image, especially Alpine Docker Container which is lightweight in my traefik.yml configuration file.

I struggled a lot to convert my Traefik configuration from version 1 to 2.

There are so many improvements in version 2. Frontends and Backends are dead…long live Routers, Middlewares, and Services, etc…

Typically, a router replaces a frontend, and a service assumes the role of a backend, with each router referring to a service.

TLS parameters used to be specified in the static configuration, as an entryPoint field. With Traefik v2, a new dynamic TLS section at the root contains all the desired TLS configurations.

You can find the changes here

I found this blog post and it helped me a lot to properly understand the configuration of Traefik 2.0

Authentication

Before spinning the Traefik stack in our docker swarm cluster, let’s set up an encrypted password to access the Traefik monitoring dashboard securely.

I use htpasswd utility to create the encrypted password. Install the utility on the master node, which is included in the apache2-utils package:

sudo apt-get install apache2-utils

Now generate the password with htpasswd. Replace secure_password with the password you’d like to use for the Traefik admin user.

htpasswd -nb admin secure_password

Output from the above code will look like below:

admin:$apr1$/RhNAq/6$9Lh.isfKrOwKMfxliqrdD/

We’ll use this password in the Traefik configuration file to set up HTTP Basic Authentication for the Traefik health check and a monitoring dashboard.

Store it in a separate file, so you can paste it later.

Configuration

Let’s create a Docker network for our Traefik proxy to share with other stacks or containers. This network is necessary so that we can use it with applications that are run using Docker Compose. Let’s call this network as proxy.

docker network create -d overlay proxy

When the Traefik stack starts, we will add it to the proxy network. Then we can add additional stacks or containers to this network later for Traefik to serve the stacks to the outside world.

Now let’s create a folder called traefik in /opt file location where I am going to put all the micro-services configurations individually (nothing but .yml files in different folders under /opt directory). Now on-wards everything executed on the master node.

cd /opt
sudo mkdir -p traefik
cd traefik

Now create 2 files, acme.json (storing letsencrypt certificates and traefik can use this info) and traefik.yml (Traefik configuration).

sudo touch acme.json
sudo touch traefik.yml
sudo chmod 600 acme.json

Lock down the permissions on acme.json so that only the owner of the file has read and write permission.

Open traefik.yml file in nano or any text editor of your choice (I use nano because it’s easy to use)

sudo nano traefik.yml

Traefik Docker Compose

Here is the docker compose file for Traefik.

Copy and paste the below code in traefik.yml file.

version: "3.7"

services:
traefik:
  image: traefik:v2.0
  command:
    - "--api=true"
    - "--api.dashboard=true"
    - "--providers.docker=true"
    - "--providers.docker.exposedbydefault=false"
    - "--providers.docker.swarmMode=true"
    - "--providers.docker.network=http"
    - "--entrypoints.web.address=:80"
    - "--entrypoints.websecure.address=:443"
    - "--certificatesresolvers.default.acme.email=your email address"
    - "--certificatesresolvers.default.acme.storage=/acme.json"
    - "--certificatesresolvers.default.acme.tlschallenge=true"
  ports:
    - 80:80
    - 443:443
  deploy:
    placement:
      constraints:
        - node.role == manager
    replicas: 1
    update_config:
    parallelism: 2
    delay: 10s
    restart_policy:
      condition: on-failure
    labels:
      # Dashboard
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=default"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.middlewares=authtraefik"
      - "traefik.http.middlewares.authtraefik.basicauth.users=admin:$apr1$/RhNAq/6$9Lh.isfKrOwKMfxliqrdD/"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"

      # global redirect to https
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      
      # middleware redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./acme.json:/etc/traefik/acme.json
  networks:
    - proxy

networks:
  proxy:
    external: true

I am not going to explain more about the configuration, you can find a detailed explanation of each and every command associated with traefik here which helped me a lot as I mentioned early in this article.

Let’s discuss some of the configurations under deploy key

deploy key

It allows us to specify configurations related to the deployment and running of services. The deploy key can also be used to constrain some services to run only on the manager node.

This only takes effect when deploying to a swarm cluster with `docker stack deploy` command and is ignored by docker-compose up and docker-compose run commands.

deploy:
  mode: replicated
  replicas: 1
  update_config:
    parallelism: 2
    delay: 10s
  restart_policy:
    condition: on-failure

Several sub-options are available for deploy key

mode is specified either as global (exactly one container per swarm node) or replicated (a specified number of containers). Default is replicated.

mode: global

replicas is to specify the number of containers that should be running at any given time.

replicas: 1

placement is to specify the placement constraints for the stack or service to run

placement:
  constraints:
    - node.role == manager

update_config to configure how the service should be updated. Useful for configuring rolling updates.

  • parallelism: The number of containers to update at a time.
  • delay: The time to wait between updating a group of containers.
  • failure_action: What to do if an update fails. Either continue or pause Default is pause.
preformatted: 
  parallelism: 2 
  delay: 10s

resources are to configure resource constraints. This replaces the older resource constraint options in Compose files prior to version 3 (cpu_sharescpu_quotacpusetmem_limitmemswap_limit).

resources:
  limits:
    cpus: '1.5'
    memory: 500M
  reservations:
    cpus: '1.0'
    memory: 200M

restart_policy is to configure whether and how to restart containers when they exit.

  • condition: One of noneon-failure or anyDefault is any.
  • delay: How long to wait between restart attempts? Default is 0.
  • max_attempts: How many times to attempt to restart a container before giving up? Default is never give up.
  • window: How long to wait before deciding if a restart has succeeded? Default is decide immediately.
restart_policy: 
  condition: on-failure 
  delay: 5s 
  max_attempts: 3 
  window: 120s

labels is to specify labels for the service. These labels will be set only on the service, and not on any containers for the service.

version: "3.7"
services:
  traefik:
    image: traefik:v2.0
    deploy:
      labels:
        - "traefik.enable=true"

To set labels on containers instead, use the labels key outside of deploy:

version: "3.7"

services:
  traefik:
    image: traefik:v2.0
    labels:
       - "traefik.enable=true"

By enabling traefik label, our traefik stack will be available for all stacks / micro-services on our swarm cluster

Deploy Traefik Stack using Docker Compose

Now it’s time to deploy our docker-compose file above, traefik.yml using the below command

docker stack deploy --compose-file traefik.yml proxy

In the above command, you have to replace traefik.yml with your docker-compose file name and rock with whatever name you want to call this particular application

As mentioned earlier I named my docker-compose as traefik.yml and named my application stack as proxy

Check the status of the stack by using docker stack ps proxy

Check proxy stack logs using docker service logs proxy

Now the traefik stack is running, now we can browse the dashboard to see the health of the running stack or containers. Access the dashboard by pointing our browser to traefik.example.com. You will be prompted for your username and password, which are admin and the password we configured in Basic Configuration.

One thing we observe is that it automatically re-directs to https with Letsencrypt generated certificate. The information is stored in acme.json file.

Traefik Dashboard

Find the screencaps below for reference.

Traefik Dashboard Secure Login
Traefik Dashboard
Traefik Routers / Services
Traefik Features / Providers

I will be using this proxy stack as a reverse proxy / load balancer for the applications I am going to deploy to Docker Swarm Cluster.

Also I use docker network proxy to access the applications externally.

Please watch the below video for Traefik installation

In coming posts, I will show how to deploy/run MariaDB (back end database server for all the applications), WordPress, Nextcloud, Rocker Chat, Dolibarr ERP, CRM, Metabase, Flarum, etc…to our Docker Swarm Cluster behind Traefik proxy

Stay tuned for other deployments… 🙂

2 Comments

Leave a Reply

Your email address will not be published.

  1. your indents are wrong in the top section
    later when you explain the deploy it is correct oddly.

    cut and pasting the above returns “..” must be a mapping