Traefik

· Read in about 7 min · (1338 words)

Aujourdh’ui, je vais vous présenter une technologie très intéressante qui est Traefik. C’est un reverse proxy qui permet de gérer un ensemble de service, telle que des containers Docker, Kubernetes, Marathon et autres. Pour cela, Traefik va créer des règles de routage et rediriger les flux vers les bons containers. Mais traefik ne s’arrête pas là, il permet aussi de load-balancer les trafics dans les containers situé dans un même cluster.

Pour mieux comprendre son utilité, je vais expliquer via un exemple. Vous hébergez un ensemble de services hébergés dans des containers différents et situés sur le même host. L’accès à ces services nécessitent un port d’écoute, en fonction de ce port, nous pouvons rediriger tout le trafic vers le bon container. Par exemple, nous pouvons très bien avoir deux containers qui hébergent un service Apache et qu’ils écoutent sur le port 80. Cependant, pour différencier ces services, nous pouvons un mappage de port. Pour le premier service Apache, on utilise le port 8080 et on redirige tous les flux à destination de ce port vers ce container et le second service Apache, ont redirige tous les flux ayant comme port de destination 8081 vers ce container. Mais, vous vous doutez bien que ce n’est pas très trivial de fournir ces adresses pour des utilisateurs. Pour palier à ce problème, ont à recourt à un reverse proxy, comme traefik qui va rediriger les flux vers le bon container.

Dans cet article, je vais vous présenter la mise en place de Traefik en tant que reverse proxy pour gérer des containers Dockers, puisque je l’utilise actuellement pour mes sites qui sont hébergés dans des containers Dockers.

Mise en place de notre infrastructure

Pour les besoins de cet article, nous allons utiliser trois containers qui vont chacun hébergés un service. La figure ci-dessous, illustre l’infrastructure que nous allons mettre en place:

Infrasturcture Docker

Comme le montre la figure ci-dessus, nous allons mettre en place un container Docker sous Traefik ainsi que deux autres containers qui hébergent le service Apache. Un Traefik va se positionner devant les services, c’est donc lui le frontal et qui va ensuite rediriger tous les flux vers le bon container, il n’est pas nécessaire d’ouvrir les ports HTTP des containers.

Création de nos containers

Pour permettre de gérer nos trois containers, je vais utiliser docker-compose, qui va me permettre de gérer mes containers.

Tout d’abord, nous allons créer nos containers qui vont héberger le service Apache en se basant sur des Dockerfile. Pour cela, j’ai créé deux dossiers qui contiennent une page index.html ainsi que le Dockerfile:

$ cat site1/Dockerfile
FROM php:7.0-apache
COPY index.html /var/www/html/
$ cat site2/Dockerfile
FROM php:7.0-apache
COPY index.html /var/www/html/

Nous allons maintenant créer notre fichier docker-compose.yml pour démarrer nos containers et vérifier que nous avons bien une page Web qui s’affiche.

$ cat docker-compose.yml
version: '3'
services:
  site1:
    build: 'site1/'
    ports:
      - '8081:80'
    networks:
      default:
        ipv4_address: 172.18.0.2
  site2:
    build: 'site2/'
    ports:
      - '8082:80'
    networks:
      default:
        ipv4_address: 172.18.0.3

$ sudo docker-compose up

Comme le montre mon fichier docker-compose.yml, je demande de construire mes deux sites, puis, je fait un mappage de port 808[1-2] vers le port 80 pour mes containers. Par ailleurs, ces containers hébergeant un site, je fixe une IP statique.

Nous pouvons maintenant tester via les adresses http://127.0.0.1:8081 et http://127.0.0.1:8082 pour vérifier si nous accédons bien aux services Web.

Maintenant que nos containers Apaches sont prêts, nous pouvons commencer à mettre en place Traefik. Il est possible d’utiliser Traefik en tant que container et d’ailleurs, il existe une image officielle:

$ sudo docker pull traefik

Avant de démarrer notre container Traefik, nous devons le paramétrer. Pour cela, Traefik s’appuie sur un fichier traefik.toml et qui contient un ensemble de règle. Etant donné que nous allons utiliser Traefik dans un container Docker, le fichier ci-dessous ne contient que les règles principales et permettant à Traefik de fonctionner:

$ cat traefik.toml
################################################################
# Global configuration
################################################################
defaultEntryPoints = ["http"]

################################################################
# Entrypoints configuration
################################################################
[entryPoints]
    [entryPoints.http]
    address = ":80"

    [entryPoints.api]
    address = ":8383"
    [entryPoints.api.auth]
      [entryPoints.api.auth.basic]
      users = [
        "toto:$apr1$1Q5rEw33$Od07mQJHZtokSm4HeXaJ/0"
      ]

 
################################################################
# API and dashboard configuration
################################################################

# Enable API and dashboard
[api]
entryPoint="api"
dashboard=true

################################################################
# Docker configuration backend
################################################################

# Enable Docker configuration backend
[docker]
endpoint = "unix:///var/run/docker.sock"
  • Les entrypoints sont les points d’entré de Traefik qui écoute sur ces ports et permet de rediriger les flux vers le bon container. Ici, nous avons définis 2 points d’entrée. La première (http) est celle par défaut et la seconde est le port d’écoute pour accéder au tableau de bord de Traefik. Par défaut, il écoute sur le port 8080. Par mesure de sécurité, j’ai changé ce port et mis en place une authentification en utilisant l’utiliaire htpasswd.
  • Ensuite, nous avons la section api, dans lequel nous indiquons l’entrypoint api et avoir un accès sur le port 8383. Ont indique aussi d’activer le dashboard (même si c’est activé par défaut).
  • La dernière partie concerne Docker. Le paramètre endpoint est obligatoire et prend comme valeur le chemin du socket pour que Traefik puisse y avoir un accès car il utilise l’API Docker pour rediriger le trafic.

Maintenant que la configuration de Traefik est prête, nous allons le démarrer:

$ sudo docker run -d -p 8383:8383 -v $PWD/traefik.toml:/etc/traefik/traefik.toml traefik
$ sudo docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                            NAMES
e4f59f24f967        traefik             "/traefik"          2 minutes ago       Up 2 minutes        80/tcp, 0.0.0.0:8383->8383/tcp   distracted_shockley

Maintenant que notre container est bien démarré, nous pouvons y accéder via l’adresse http://127.0.0.1:8383. Si vous avez activé l’authentification, vous devez saisir identifiant.

Voilà, vous devriez normalement avoir le tableau de bord s’affiché. Vous remarquerez vous n’avez aucune entrée dans le corps de cete page, ce qui est normale, puisque nous n’avons pas encore définit nos containers.

Démarrage de notre Docker compose

Maintenant que Traefik est opérationnel, nous allons l’ajouter dans notre Docker compose avec nos deux containers Apache. Pour cela, ajouter ceci dans votre fichier docker-compose.yml:

traefik:
  image: traefik
  ports:
    - "8383:8383"
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./traefik.toml:/etc/traefik/traefik.toml
  labels:
    - "traefik.enable=true"
    - "traefik.port=8383"
    - "traefik.frontend.rule=Host:traefik.local"

Comme vous pouvez le voir, j’indique d’utiliser l’image traefik que nous avons téléchargé précédemment, puis, je fait le mappage de port 8383 et j’ajoute mes différents volumes, c’est-à-dire le socket Docker ainsi que le fichier traefik.toml. Vous remarquerez l’apparition d’une nouvelle section: labels. C’est dans cette section, que nous devons indiquer les règles permettant à Traefik de rediriger le trafic vers le bon container:

  • La directive traefik.enable indique d’activer où non Traefik pour ce container
  • La directive traefik.port prend comme paramètre le port d’écoute, en fonction de cette règle, il va pouvoir rediriger tout le trafic vers le port d’écoute
  • La dernière directive traefik.frontend.rule, permet d’indiquer la règle du frontend, c’est-à-dire l’adresse saisit par l’utilisateur. Ici, j’indique que pour un Host ayant comme nom traefik.local, je redirige les flux vers le container de Traefik.

Il est impératif d’indiquer la section labels et les différentes règles pour les autres containers. Vous trouverez ci-dessous, mon fichier docker-compose.yml avec toutes les règles:

$ cat docker-compose.yml
version: '3'
services:
  traefik:
    image: traefik
    ports:
      - "8383:8383"
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/etc/traefik/traefik.toml
    labels:
      - "traefik.enable=true"
      - "traefik.port=8383"
      - "traefik.frontend.rule=Host:traefik.local"
  site1:
    build: 'site1/'
    labels:
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.frontend.rule=Host:site1.local"
    networks:
      default:
        ipv4_address: 172.18.0.2
  site2:
    build: 'site2/'
    labels:
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.frontend.rule=Host:site2.local"
    networks:
      default:
        ipv4_address: 172.18.0.3

Ont n’a plus qu’à démarrer nos containers via la commande sudo docker-compose up et tester l’accès. Pour le premier site, vous n’avez plus qu’à saisir l’adresse http://site1.local et pour le second site http://site2.local. Pour m’a part, n’ayant pas de serveur DNS, j’ai ajouter deux entrées pointant sur mon localhost dans le fichier /etc/hosts:

127.0.0.1     traefik.local
127.0.0.1     site1.local
127.0.0.1     site2.local

Si vous vous connectez sur le tableau de bord de traefik (http://traefik.local), vous verez apparaître les différentes entrées permettant la redirection.

Voilà, nous avons terminé avec Traefik. Je vous invite à lire la documentation officielle qui fournit beaucoup plus d’exemple pour la configuration car c’est un outil très puissant et qui offre beaucoup de fonctionnalité, comme le load-balancing mais permet aussi la configuration via une API.