Je voulais mettre en place Traefik pour simplifier le routage vers mes conteneur. Dans le billet précédent j’ai découvert la nécessite de me plonger dans la mise en œuvre explicite du réseau de mes conteneurs car Traefik et les conteneurs doivent être dans le même réseau.
Réseau Traefik backend
Le réseau dédié à la communication entre Traefik et les serveurs sera créé en dehors de compose lors du déploiement de Traefik par le déploiement continu. Cela pose la problématique de sa création à la demande notamment dans la phase de test dans DIND. La définition de l’instance Traefik sera la suivante:
version: '3.7'
services:
reverse-proxy:
# The official v2 Traefik docker image
image: traefik:v2.2
restart: always
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
ports:
# The HTTP port
- "88:80"
# The Web UI (enabled by --api.insecure=true)
- "8888:8080"
networks:
- outside
- default
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
networks:
outside:
external: true
name: traefik_backend
On ajoute en plus du réseau default un réseau dédié outside. Ce réseau est définit comme externe (non géré par compose lors de la création de l’application) et on lui donne un nom spécifique: traefik_backend.
Dans le fichier .gitlab-ci.yml on appelle le script de création du réseau. Ainsi la job pour le test dans DIND devient:
script:
- echo "deploy $CI_PROJECT_NAME to staging"
- sh ./create_traefik_backend.sh
- docker-compose pull
- docker-compose up -d
Où le scripte create_traefik_backend.sh contient:
#! /bin/bash docker network ls | grep traefik_backend ; if [ $? -ne 0 ]; then echo "create traefik_backend network"; docker network create traefik_backend; fi;
Connexion d’un service au réseau Traefik
Les services doivent être agnostique de leur utilisation à travers Traefik. Leur définition de base ne doit pas y faire référence. Cela nous oblige à utiliser un mécanisme de fusion de configuration:
- docker-compose.yml qui ne porte pas de référence à Traefik
- docker-compose.staging.yml qui ajoute le réseau traefik_backend au conteneur (service) web
- docker-compose.production.yml qui ajoute le réseau traefik_backend au conteneur (service) web
J’introduis dors-et-déjà une configuration spéciale pour l’environnement de staging même si pour l’instant il est identique à celui de la production. En effet le moment venu les configurations vont diverger quand je vais déplacer staging sur l’infra. Inutile en effet d’allouer une VM pour la préprod qui n’a pas vocation à être allumée tout le temps. Une des caractéristique des conteneurs est leur éphémérité: on les créé quand on en a besoin puis on les détruit. Cela va me permettre de réserver plus de ressources pour la production car c’est là que j’en ai le plus besoin avec des OOM kill qui surviennent de temps en temps. Lorsque je devrais déplacer staging sur l’infra il va falloir avoir un nom de réseau et des ports différents d’exposition du haproxy et de traefik pour distinguer staging de l’infra !
Décomposition des docker-compose.yml
Voici comment procéder pour avoir une définition de l’application spécifique pour un environnement.
Par défaut l’application ne connait pas Traefik, donc son docker-compose.yml reste le même que avant:
version: '3.7'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- www_data:/var/www/html
ports:
- "8084:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
www_data: {}
On ajoute un docker-compose.staging.yml qui ajoute les spécifités Traefik à l’application:
version: '3.7'
services:
wordpress:
labels:
- "traefik.http.routers.kitejust4fun_asso.rule=Host(`www.kitejust4fun.fr`) || Host(`kitejust4fun.fr`)"
- "traefik.docker.network=traefik_backend"
networks:
- default
- outside
networks:
outside:
external: true
name: traefik_backend
Lors du lancement en environnement staging on utilisera la commande:
docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d
Tags: Docker Traefik