Comment utiliser Traefik en tant que proxy inverse pour les conteneurs Docker sur Ubuntu 18.04

L’auteur a sélectionné Girls Who Code pour recevoir un don dans le cadre du programme Write for DOnations .

introduction

https://www.docker.com [Docker] peut constituer un moyen efficace d’exécuter des applications Web en production, mais vous pouvez également exécuter plusieurs applications sur le même hôte Docker. Dans ce cas, vous devrez configurer un proxy inverse car vous souhaitez uniquement exposer les ports + 80 + et + 443 + au reste du monde.

https://traefik.io [Traefik] est un proxy inverse compatible Docker qui comprend son propre tableau de bord de surveillance. Dans ce didacticiel, vous utiliserez Traefik pour acheminer les demandes vers deux conteneurs d’applications Web différents: un conteneur http://wordpress.org [Wordpress] et un conteneur Adminer, chacun parlant. dans une base de données MySQL. Vous configurerez Traefik pour tout desservir via HTTPS en utilisant Let’s Encrypt.

Conditions préalables

Pour suivre ce tutoriel, vous aurez besoin des éléments suivants:

Étape 1 - Configuration et exécution de Traefik

Le projet Traefik a une image Docker officieuse official, nous allons donc l’utiliser pour exécuter Traefik dans un conteneur Docker.

Mais avant que notre conteneur Traefik soit opérationnel, nous devons créer un fichier de configuration et configurer un mot de passe crypté afin de pouvoir accéder au tableau de bord de surveillance.

Nous allons utiliser l’utilitaire + htpasswd + pour créer ce mot de passe crypté. Commencez par installer l’utilitaire inclus dans le paquet + apache2-utils +:

sudo apt-get install apache2-utils

Générez ensuite le mot de passe avec + htpasswd +. Remplacez «++» par le mot de passe que vous souhaitez utiliser pour l’administrateur Traefik:

htpasswd -nb admin

La sortie du programme ressemblera à ceci:

Outputadmin:

Vous utiliserez cette sortie dans le fichier de configuration Traefik pour configurer l’authentification HTTP de base pour le tableau de bord de contrôle de la santé et de surveillance Traefik. Copiez la totalité de la ligne de sortie pour pouvoir la coller ultérieurement.

Pour configurer le serveur Traefik, nous allons créer un nouveau fichier de configuration appelé + traefik.toml + en utilisant le format TOML. TOML est un langage de configuration similaire aux fichiers INI, mais normalisé. Ce fichier nous permet de configurer le serveur Traefik et diverses intégrations, ou fournisseurs, que nous souhaitons utiliser. Dans ce didacticiel, nous utiliserons trois des fournisseurs disponibles dans Traefik: + api,` + docker` et + acme, utilisés pour prendre en charge TLS à l’aide de Let’s Encrypt.

Ouvrez votre nouveau fichier dans + nano + ou votre éditeur de texte préféré:

nano traefik.toml

Premièrement, ajoutez deux points d’entrée nommés, + http + et + https +, auxquels tous les moteurs auront accès par défaut:

traefik.toml

defaultEntryPoints = ["http", "https"]

Nous allons configurer les points d’entrée + http + et + https + plus tard dans ce fichier.

Ensuite, configurez le fournisseur + api, qui vous donne accès à une interface de tableau de bord. C’est là que vous allez coller le résultat de la commande + htpasswd +:

traefik.toml

...
[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]

[api]
entrypoint="dashboard"

Le tableau de bord est une application Web distincte qui s’exécutera dans le conteneur Traefik. Nous avons configuré le tableau de bord pour qu’il s’exécute sur le port + 8080 +.

La section + entrypoints.dashboard + configure la façon dont nous allons nous connecter avec le fournisseur + api +, et la section + entrypoints.dashboard.auth.basic + configure l’authentification HTTP de base pour le tableau de bord. Utilisez le résultat de la commande + htpasswd + que vous venez d’exécuter pour la valeur de l’entrée + users +. Vous pouvez spécifier des noms de connexion supplémentaires en les séparant par des virgules.

Nous avons défini notre premier + entryPoint +, mais nous devrons en définir d’autres pour les communications HTTP et HTTPS standard qui ne sont pas dirigées vers le fournisseur + api +. La section + entryPoints + configure les adresses que Traefik et les conteneurs mandatés peuvent écouter. Ajoutez ces lignes au fichier sous l’en-tête + entryPoints +:

traefik.toml

...
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]
...

Le point d’entrée + http + gère le port + 80 +, tandis que le point d’entrée + https + utilise le port + 443 + pour TLS / SSL. Nous redirigeons automatiquement tout le trafic sur le port + 80 + vers le point d’entrée + https + afin de forcer les connexions sécurisées pour toutes les demandes.

Ajoutez ensuite cette section pour configurer la prise en charge des certificats de Let Encrypt pour Traefik:

traefik.toml

...
[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

Cette section s’appelle + acme + car ACME est le nom du protocole utilisé pour communiquer avec Let Encrypt afin de gérer les certificats. Le service Let’s Encrypt nécessite une inscription avec une adresse e-mail valide. Par conséquent, pour que Traefik génère des certificats pour nos hôtes, définissez la clé + email + sur votre adresse e-mail. Nous spécifions ensuite que nous allons stocker les informations que nous allons recevoir de Let’s Encrypt dans un fichier JSON appelé + acme.json +. La touche + entryPoint + doit pointer sur le port de traitement du point d’entrée + 443 +, qui dans notre cas est le point d’entrée + https +.

La clé + onHostRule + indique comment Traefik doit générer des certificats. Nous voulons récupérer nos certificats dès que nos conteneurs avec les noms d’hôte spécifiés sont créés, et c’est ce que le paramètre + onHostRule + fera.

La section + acme.httpChallenge + nous permet de spécifier comment Let’s Encrypt peut vérifier que le certificat doit être généré. Nous le configurons pour servir un fichier dans le cadre du défi via le point d’entrée + http +.

Enfin, configurons le fournisseur + docker + en ajoutant ces lignes au fichier:

traefik.toml

...
[docker]
domain = ""
watch = true
network = "web"

Le fournisseur + docker + permet à Traefik d’agir en tant que proxy devant les conteneurs Docker. Nous avons configuré le fournisseur pour + surveiller de nouveaux conteneurs sur le réseau` + web` (que nous allons créer bientôt) et les exposer en tant que sous-domaines de ++.

À ce stade, + traefik.toml + devrait avoir le contenu suivant:

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
 [entryPoints.dashboard]
   address = ":8080"
   [entryPoints.dashboard.auth]
     [entryPoints.dashboard.auth.basic]
       users = [""]
 [entryPoints.http]
   address = ":80"
     [entryPoints.http.redirect]
       entryPoint = "https"
 [entryPoints.https]
   address = ":443"
     [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = ""
storage = "acme.json"
entryPoint = "https"
onHostRule = true
 [acme.httpChallenge]
 entryPoint = "http"

[docker]
domain = ""
watch = true
network = "web"

Enregistrez le fichier et quittez l’éditeur. Avec toute cette configuration en place, nous pouvons lancer Traefik.

Étape 2 - Exécution du conteneur Traefik

Créez ensuite un réseau Docker que le proxy va partager avec les conteneurs. Le réseau Docker est nécessaire pour pouvoir être utilisé avec des applications exécutées à l’aide de Docker Compose. Appelons ce réseau + web.

docker network create

Lorsque le conteneur Traefik démarrera, nous l’ajouterons à ce réseau. Ensuite, nous pourrons ajouter ultérieurement des conteneurs supplémentaires à ce réseau pour que Traefik puisse utiliser un proxy.

Ensuite, créez un fichier vide qui contiendra nos informations Let Encrypt. Nous allons partager cela dans le conteneur afin que Traefik puisse l’utiliser:

touch

Traefik ne pourra utiliser ce fichier que si l’utilisateur root à l’intérieur du conteneur dispose d’un accès unique en lecture et en écriture. Pour ce faire, verrouillez les autorisations sur + acme.json + afin que seul le propriétaire du fichier dispose des autorisations de lecture et d’écriture.

chmod 600

Une fois le fichier transmis à Docker, le propriétaire passe automatiquement à l’utilisateur * root * à l’intérieur du conteneur.

Enfin, créez le conteneur Traefik avec cette commande:

docker run -d \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v $PWD/traefik.toml:/traefik.toml \
 -v $PWD/acme.json:/acme.json \
 -p 80:80 \
 -p 443:443 \
 -l traefik.frontend.rule=Host:monitor. \
 -l traefik.port=8080 \
 --network web \
 --name traefik \
 traefik:1.7.2-alpine

La commande est un peu longue, alors décomposons-la.

Nous utilisons l’indicateur + -d + pour exécuter le conteneur en arrière-plan en tant que démon. Nous partageons ensuite notre fichier + docker.sock + dans le conteneur afin que le processus Traefik puisse écouter les modifications apportées aux conteneurs. Nous partageons également le fichier de configuration + traefik.toml + et le fichier + acme.json + que nous avons créés dans le conteneur.

Ensuite, nous mappons les ports +: 80 + et +: 443 + de notre hôte Docker aux mêmes ports du conteneur Traefik afin que Traefik reçoive tout le trafic HTTP et HTTPS vers le serveur.

Nous avons ensuite configuré deux étiquettes Docker qui indiquent à Traefik de diriger le trafic sur le nom d’hôte + monitor. + Sur le port +: 8080 + dans le conteneur Traefik, ce qui expose le tableau de bord de surveillance.

Nous définissons le réseau du conteneur sur + web +, et nous nommons le conteneur + traefik +.

Enfin, nous utilisons l’image + traefik: 1.7.2-alpine + pour ce conteneur, car il est petit.

Une image Docker + ENTRYPOINT est une commande toujours exécutée lorsqu’un conteneur est créé à partir de l’image. Dans ce cas, la commande est le binaire + traefik + dans le conteneur. Vous pouvez transmettre des arguments supplémentaires à cette commande lorsque vous lancez le conteneur, mais nous avons configuré tous nos paramètres dans le fichier + traefik.toml +.

Une fois le conteneur démarré, vous disposez désormais d’un tableau de bord auquel vous pouvez accéder pour voir la santé de vos conteneurs. Vous pouvez également utiliser ce tableau de bord pour visualiser les interfaces et les applications que Traefik a enregistrées. Accédez au tableau de bord de surveillance en pointant votre navigateur sur + https: // monitor. +. Vous serez invité à entrer votre nom d’utilisateur et votre mot de passe, qui sont * admin * et le mot de passe que vous avez configuré à l’étape 1.

Une fois connecté, vous verrez une interface semblable à celle-ci:

image: http: //assets.digitalocean.com/articles/63957_Traefik/Empty_Traefik_dashboard.png [Tableau de bord vide de Traefik]

Il n’ya pas grand-chose à voir pour l’instant, mais laissez cette fenêtre ouverte et vous verrez le contenu changer à mesure que vous ajoutez des conteneurs avec lesquels Traefik peut travailler.

Nous avons maintenant notre proxy Traefik en cours d’exécution, configuré pour fonctionner avec Docker et prêt à surveiller d’autres conteneurs Docker. Commençons par quelques conteneurs pour que Traefik puisse agir en tant que proxy.

Étape 3 - Enregistrement des conteneurs avec Traefik

Avec le conteneur Traefik en cours d’exécution, vous êtes prêt à exécuter les applications qui s’y trouvent. Lançons les partenaires suivants derrière Traefik:

  1. Un blog utilisant l’image official Wordpress.

  2. Un serveur de gestion de base de données utilisant l’image official Adminer.

Nous allons gérer ces deux applications avec Docker Compose en utilisant un fichier + docker-compose.yml +. Ouvrez le fichier + docker-compose.yml + dans votre éditeur:

nano docker-compose.yml

Ajoutez les lignes suivantes au fichier pour spécifier la version et les réseaux que nous utiliserons:

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

Nous utilisons la version "+ 3 +" de Docker Compose car il s’agit de la dernière version majeure du format de fichier Compose.

Pour que Traefik reconnaisse nos applications, elles doivent faire partie du même réseau et, puisque nous avons créé le réseau manuellement, nous le récupérons en spécifiant le nom du réseau + web + et en définissant + external + sur + true +. Ensuite, nous définissons un autre réseau afin de pouvoir connecter nos conteneurs exposés à un conteneur de base de données que nous n’exposons pas via Traefik. Nous appellerons ce réseau + internal +.

Ensuite, nous définirons chacun de nos «+ services », un à la fois. Commençons par le conteneur ` blog +`, que nous baserons sur l’image officielle de WordPress. Ajoutez cette configuration au fichier:

docker-compose.yml

version: "3"
...

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql

La clé + environment vous permet de spécifier des variables d’environnement qui seront définies à l’intérieur du conteneur. En ne définissant pas de valeur pour + WORDPRESS_DB_PASSWORD +, nous demandons à Docker Compose d’obtenir la valeur de notre shell et de la transmettre lors de la création du conteneur. Nous définirons cette variable d’environnement dans notre shell avant de démarrer les conteneurs. De cette façon, nous ne codons pas en dur les mots de passe dans le fichier de configuration.

La section + labels + vous permet d’indiquer les valeurs de configuration pour Traefik. Les étiquettes Docker ne font rien d’elles-mêmes, mais Traefik les lit pour savoir comment traiter les contenants. Voici ce que chacune de ces étiquettes fait:

  • + traefik.backend + spécifie le nom du service backend de Traefik (qui pointe sur le conteneur + blog + actuel).

  • + traefik.frontend.rule = Hôte: blog. + indique à Traefik d’examiner l’hôte demandé et s’il correspond au modèle + blog. +, il doit acheminer le trafic vers le conteneur + blog +.

  • + traefik.docker.network = web + spécifie le réseau sous lequel Traefik doit rechercher l’IP interne de ce conteneur. Puisque notre conteneur Traefik a accès à toutes les informations de Docker, il pourrait potentiellement utiliser l’adresse IP du réseau + internal + si nous ne l’indiquions pas.

  • + traefik.port + spécifie le port exposé que Traefik doit utiliser pour acheminer le trafic vers ce conteneur.

Avec cette configuration, tout le trafic envoyé au port + 80 + de notre hôte Docker sera acheminé vers le conteneur + blog +.

Nous affectons ce conteneur à deux réseaux différents afin que Traefik puisse le trouver via le réseau + web + et qu’il puisse communiquer avec le conteneur de base de données via le réseau + internal +.

Enfin, la clé + depend_on + indique à Docker Compose que ce conteneur doit démarrer après que ses dépendances s’exécutent. Comme WordPress a besoin d’une base de données pour fonctionner, nous devons exécuter notre conteneur + mysql avant de démarrer votre conteneur` + blog`.

Ensuite, configurez le service MySQL en ajoutant cette configuration à votre fichier:

docker-compose.yml

services:
...
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false

Nous utilisons l’image officielle de MySQL 5.7 pour ce conteneur. Vous remarquerez que nous utilisons à nouveau un élément + environment + sans valeur. Les variables + MYSQL_ROOT_PASSWORD + et + WORDPRESS_DB_PASSWORD + devront être définies sur la même valeur pour que notre conteneur WordPress puisse communiquer avec MySQL. Nous ne souhaitons pas exposer le conteneur + mysql + à Traefik ou au monde extérieur, nous l’assignons donc uniquement au réseau + internal +. Puisque Traefik a accès au socket Docker, le processus exposera toujours une interface pour le conteneur + mysql + par défaut. Nous allons donc ajouter l’étiquette + traefik.enable = false + pour spécifier que Traefik ne doit pas exposer ce conteneur. .

Enfin, ajoutez cette configuration pour définir le conteneur Adminer:

docker-compose.yml

services:
...
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

Ce conteneur est basé sur l’image officielle de l’administrateur. Les configurations + network + et + includes_on + de ce conteneur correspondent exactement à ce que nous utilisons pour le conteneur + blog +.

Cependant, comme nous dirigeons tout le trafic sur le port + 80 + de notre hôte Docker directement vers le conteneur + blog +, nous devons configurer ce conteneur différemment afin que le trafic parvienne à notre administrateur + adminer + `conteneur. La ligne `+ traefik.frontend.rule = Hôte: db-admin. + Indique à Traefik d’examiner l’hôte demandé. S’il correspond au modèle + db-admin. +, Traefik acheminera le trafic vers le conteneur + adminer +.

À ce stade, + docker-compose.yml + devrait avoir le contenu suivant:

docker-compose.yml

version: "3"

networks:
 web:
   external: true
 internal:
   external: false

services:
 blog:
   image: wordpress:4.9.8-apache
   environment:
     WORDPRESS_DB_PASSWORD:
   labels:
     - traefik.backend=blog
     - traefik.frontend.rule=Host:blog.
     - traefik.docker.network=web
     - traefik.port=80
   networks:
     - internal
     - web
   depends_on:
     - mysql
 mysql:
   image: mysql:5.7
   environment:
     MYSQL_ROOT_PASSWORD:
   networks:
     - internal
   labels:
     - traefik.enable=false
 adminer:
   image: adminer:4.6.3-standalone
   labels:
     - traefik.backend=adminer
     - traefik.frontend.rule=Host:db-admin.
     - traefik.docker.network=web
     - traefik.port=8080
   networks:
     - internal
     - web
   depends_on:
     - mysql

Enregistrez le fichier et quittez l’éditeur de texte.

Ensuite, définissez des valeurs dans votre shell pour les variables + WORDPRESS_DB_PASSWORD + et + + MYSQL_ROOT_PASSWORD + avant de démarrer vos conteneurs:

export WORDPRESS_DB_PASSWORD=
export MYSQL_ROOT_PASSWORD=

Remplacez ++ par le mot de passe souhaité pour la base de données. N’oubliez pas d’utiliser le même mot de passe pour + WORDPRESS_DB_PASSWORD + et + + MYSQL_ROOT_PASSWORD +.

Avec ces variables définies, exécutez les conteneurs en utilisant + docker-compose +:

docker-compose up -d

Examinons maintenant le tableau de bord de l’administrateur Traefik. Vous verrez qu’il existe maintenant un + backend + et un + frontend + pour les deux serveurs exposés:

image: http: //assets.digitalocean.com/articles/63957_Traefik/Populated_Traefik_dashboard.png [Tableau de bord Traefik rempli]

Accédez à + ​​blog. +, En substituant + votre_domaine + avec votre domaine. Vous serez redirigé vers une connexion TLS et pouvez maintenant terminer la configuration de Wordpress:

image: http: //assets.digitalocean.com/articles/63957_Traefik/WordPress_setup_screen.png [Écran d’installation de WordPress]

Maintenant, accédez à Adminer en visitant + db-admin. + Dans votre navigateur, en substituant à nouveau + votre_domaine + avec votre domaine. Le conteneur + mysql + n’est pas exposé au monde extérieur, mais le conteneur + adminer + y a accès via le réseau + internal + Docker qu’ils partagent en utilisant le nom du conteneur + mysql + comme nom d’hôte.

Sur l’écran de connexion de l’administrateur, utilisez le nom d’utilisateur * root *, l’utilisateur + mysql pour le * serveur * et la valeur que vous avez définie pour` + MYSQL_ROOT_PASSWORD` pour le mot de passe. Une fois connecté, vous verrez l’interface utilisateur de l’administrateur:

image: http: //assets.digitalocean.com/articles/63957_Traefik/adminer-mysql-database/Adminer_MySQL_database.png [Administrateur connecté à la base de données MySQL]

Les deux sites fonctionnent maintenant et vous pouvez utiliser le tableau de bord sur + monitor. + Pour surveiller vos applications.

Conclusion

Dans ce tutoriel, vous avez configuré Traefik pour envoyer des requêtes à d’autres applications dans des conteneurs Docker.

La configuration déclarative de Traefik au niveau du conteneur d’applications facilite la configuration de plusieurs services. Il n’est pas nécessaire de redémarrer le conteneur + traefik + lorsque vous ajoutez de nouvelles applications au trafic proxy car Traefik remarque immédiatement les modifications dans le fichier de socket Docker qu’il surveille. .

Pour en savoir plus sur ce que vous pouvez faire avec Traefik, rendez-vous à la documentation officielle Traefik.