Comment utiliser Traefik v1 comme proxy inverse pour les conteneurs Docker sur Ubuntu 20.04

De Get Docs
Aller à :navigation, rechercher

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

Introduction

Docker peut être un moyen efficace d'exécuter des applications Web en production, mais vous souhaiterez peut-être exécuter plusieurs applications sur le même hôte Docker. Dans cette situation, vous devrez configurer un proxy inverse puisque vous souhaitez uniquement exposer les ports 80 et 443 au reste du monde.

Traefik est un proxy inverse compatible Docker qui inclut son propre tableau de bord de surveillance. Dans ce didacticiel, vous utiliserez Traefik pour acheminer les requêtes vers deux conteneurs d'applications Web différents : un conteneur Wordpress et un conteneur Adminer, chacun parlant à un MySQL. base de données. Vous allez configurer Traefik pour qu'il serve tout sur 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 officielle, nous allons donc l'utiliser pour exécuter Traefik dans un conteneur Docker.

Mais avant de mettre notre conteneur Traefik en service, 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 utiliserons l'utilitaire htpasswd pour créer ce mot de passe crypté. Tout d'abord, installez l'utilitaire, qui est inclus dans le package apache2-utils :

sudo apt-get install apache2-utils

Générez ensuite le mot de passe avec htpasswd. Remplacez secure_password par le mot de passe que vous souhaitez utiliser pour l'utilisateur administrateur Traefik :

htpasswd -nb admin secure_password

La sortie du programme ressemblera à ceci :

Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

Vous utiliserez votre sortie unique dans le fichier de configuration Traefik pour configurer l'authentification de base HTTP pour le tableau de bord de contrôle et de surveillance de l'état Traefik. Copiez toute votre ligne de sortie afin de pouvoir la coller plus tard. N'utilisez pas l'exemple de sortie.

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 standardisé. Ce fichier nous permet de configurer le serveur Traefik et diverses intégrations, ou providers, que nous souhaitons utiliser. Dans ce didacticiel, nous utiliserons trois des fournisseurs disponibles de Traefik : api, docker et acme. Le dernier d'entre eux, acme prend en charge les certificats TLS à l'aide de Let's Encrypt.

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

nano traefik.toml

Tout d'abord, ajoutez deux points d'entrée nommés, http et https, auxquels tous les backends auront accès par défaut :

traefik.toml

defaultEntryPoints = ["http", "https"]

Nous configurerons les points d'entrée http et https plus loin dans ce fichier.

Ensuite, configurez le fournisseur api, qui vous donne accès à une interface de tableau de bord. C'est ici que vous collerez la sortie de la commande htpasswd :

traefik.toml

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

[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 de base HTTP pour le tableau de bord. Utilisez la sortie de la commande htpasswd que vous venez d'exécuter pour la valeur de l'entrée users. Vous pouvez spécifier des identifiants 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 sur lesquelles 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 pour forcer des connexions sécurisées pour toutes les requêtes.

Ensuite, ajoutez cette section pour configurer la prise en charge des certificats Let's Encrypt pour Traefik :

traefik.toml

...
[acme]
email = "[email protected]_domain"
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's Encrypt pour gérer les certificats. Le service Let's Encrypt nécessite une inscription avec une adresse e-mail valide, donc pour que Traefik génère des certificats pour nos hôtes, définissez la clé email sur votre adresse e-mail. Nous précisons ensuite que nous stockerons les informations que nous recevrons de Let's Encrypt dans un fichier JSON nommé acme.json. La clé entryPoint doit pointer vers le port de gestion du point d'entrée 443, qui dans notre cas est le point d'entrée https.

La clé onHostRule dicte comment Traefik doit procéder pour 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 fera le paramètre onHostRule.

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 = "your_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 sur watch pour les nouveaux conteneurs sur le réseau web, que nous créerons bientôt, et les exposerons en tant que sous-domaines de your_domain.

À 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 = ["admin:your_encrypted_password"]
  [entryPoints.http]
    address = ":80"
      [entryPoints.http.redirect]
        entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[api]
entrypoint="dashboard"

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

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

Enregistrez le fichier et quittez l'éditeur. Avec ces configurations en place, nous pouvons initialiser Traefik.

Étape 2 - Exécution du conteneur Traefik

Ensuite, créez un réseau Docker que le proxy partagera avec les conteneurs. Le réseau Docker est nécessaire pour que nous puissions l'utiliser avec des applications exécutées à l'aide de Docker Compose. Appelons ce réseau web :

docker network create web

Lorsque le conteneur Traefik démarrera, nous l'ajouterons à ce réseau. Ensuite, nous pouvons ajouter des conteneurs supplémentaires à ce réseau plus tard pour que Traefik puisse être mandaté.

Ensuite, créez un fichier vide qui contiendra nos informations Let's Encrypt. Nous partagerons ceci dans le conteneur afin que Traefik puisse l'utiliser :

touch acme.json

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 acme.json

Une fois le fichier transmis à Docker, le propriétaire passera 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.your_domain \
  -l traefik.port=8080 \
  --network web \
  --name traefik \
  traefik:1.7-alpine

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

Nous utilisons le drapeau -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 dans le conteneur Traefik afin que Traefik reçoive tout le trafic HTTP et HTTPS vers le serveur.

Ensuite, nous avons configuré deux étiquettes Docker qui indiquent à Traefik de diriger le trafic vers le nom d'hôte monitor.your_domain vers le port :8080 dans le conteneur Traefik, ce qui exposera 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-alpine pour ce conteneur, car il est petit.

L'ENTRYPOINT d'une image Docker est une commande qui s'exécute toujours 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 maintenant 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 frontends et backends que Traefik a enregistrés. Accédez au tableau de bord de surveillance en pointant votre navigateur vers https://monitor.your_domain. 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 similaire à celle-ci :

Il n'y a 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 à gérer par Traefik.

Nous avons maintenant notre proxy Traefik en cours d'exécution, configuré pour fonctionner avec Docker et prêt à surveiller d'autres conteneurs Docker. Ajoutons quelques conteneurs pour Traefik au proxy.

Étape 3 - Enregistrement des conteneurs avec Traefik

Avec le conteneur Traefik en cours d'exécution, vous êtes prêt à exécuter des applications derrière lui. Lançons les conteneurs suivants derrière Traefik :

  1. Un blog utilisant l'image WordPress officielle.
  2. Un serveur de gestion de base de données utilisant l'image Adminer officielle.

Nous gérerons ces deux applications avec Docker Compose en utilisant un fichier docker-compose.yml.

Créez et 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 Docker Compose 3 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 l'intégrons en spécifiant le nom de réseau de web et en définissant external sur [ X208X]. 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'exposerons 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 allons baser sur l'image officielle de WordPress. Ajoutez cette configuration au bas de votre fichier :

docker-compose.yml

...

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

La clé environment vous permet de spécifier les variables d'environnement qui seront définies à l'intérieur du conteneur. En ne définissant pas de valeur pour WORDPRESS_DB_PASSWORD, nous disons à Docker Compose d'obtenir la valeur de notre shell et de la transmettre lorsque nous créons le 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 les mots de passe en dur dans le fichier de configuration.

La section labels est l'endroit où vous spécifiez les valeurs de configuration pour Traefik. Les étiquettes Docker ne font rien par elles-mêmes, mais Traefik les lit pour savoir comment traiter les conteneurs. Voici ce que fait chacune de ces étiquettes :

  • traefik.backend spécifie le nom du service backend dans Traefik (qui pointe vers le conteneur blog réel).
  • traefik.frontend.rule=Host:blog.your_domain indique à Traefik d'examiner l'hôte demandé et s'il correspond au modèle de blog.your_domain, il doit acheminer le trafic vers le conteneur blog.
  • traefik.docker.network=web spécifie sous quel réseau rechercher Traefik pour trouver l'adresse IP interne de ce conteneur. Étant donné que notre conteneur Traefik a accès à toutes les informations Docker, il prendrait potentiellement l'adresse IP du réseau internal si nous ne le spécifions 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 attribuons 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é depends_on indique à Docker Compose que ce conteneur doit démarrer après que ses dépendances sont en cours d'exécution. Étant donné que WordPress a besoin d'une base de données pour fonctionner, nous devons exécuter notre conteneur mysql avant de démarrer notre conteneur blog.

Ensuite, configurez le service MySQL en ajoutant cette configuration au bas de votre fichier :

docker-compose.yml

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

Nous utilisons l'image officielle 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 s'assurer que notre conteneur WordPress peut communiquer avec MySQL. Nous ne voulons pas exposer le conteneur mysql à Traefik ou au monde extérieur, nous n'attribuons donc ce conteneur qu'au réseau internal. Étant donné que Traefik a accès au socket Docker, le processus exposera toujours une interface pour le conteneur mysql par défaut, nous ajouterons donc l'étiquette traefik.enable=false pour spécifier que Traefik ne doit pas exposer ce conteneur .

Enfin, ajoutez cette configuration en bas de votre fichier pour définir le conteneur Adminer :

docker-compose.yml

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

Ce conteneur est basé sur l'image officielle d'Adminer. La configuration network et depends_on pour ce conteneur correspond exactement à ce que nous utilisons pour le conteneur blog.

Cependant, étant donné que nous dirigeons tout le trafic vers le port 80 sur notre hôte Docker directement vers le conteneur blog, nous devons configurer ce conteneur différemment pour que le trafic parvienne à notre Conteneur adminer. La ligne traefik.frontend.rule=Host:db-admin.your_domain indique à Traefik d'examiner l'hôte demandé. S'il correspond au modèle de db-admin.your_domain, 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.your_domain
      - 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.your_domain
      - 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 les valeurs dans votre shell pour les variables WORDPRESS_DB_PASSWORD et MYSQL_ROOT_PASSWORD avant de démarrer vos conteneurs :

export WORDPRESS_DB_PASSWORD=secure_database_password
export MYSQL_ROOT_PASSWORD=secure_database_password

Remplacez secure_database_password par le mot de passe de votre base de données. N'oubliez pas d'utiliser le même mot de passe pour WORDPRESS_DB_PASSWORD et MYSQL_ROOT_PASSWORD.

Une fois ces variables définies, exécutez les conteneurs à l'aide de docker-compose :

docker-compose up -d

Jetez maintenant un autre coup d'œil au tableau de bord d'administration de Traefik. Vous verrez qu'il y a maintenant un backend et un frontend pour les deux serveurs exposés :

Accédez à blog.your_domain. Vous serez redirigé vers une connexion TLS et pourrez maintenant terminer la configuration de WordPress :

Accédez maintenant à Adminer en visitant db-admin.your_domain dans votre navigateur, en remplaçant à nouveau your_domain par 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 Docker internal qu'ils partagent à l'aide du mysql. ] nom du conteneur en tant que nom d'hôte.

Sur l'écran de connexion Adminer, définissez le menu déroulant Système sur MySQL. Entrez maintenant mysql pour le Serveur, entrez root pour le nom d'utilisateur, et entrez la valeur que vous avez définie pour MYSQL_ROOT_PASSWORD pour [ X134X]Mot de passe. Laissez Database vide. Appuyez maintenant sur Connexion.

Une fois connecté, vous verrez l'interface utilisateur Adminer :

Les deux sites fonctionnent maintenant et vous pouvez utiliser le tableau de bord sur monitor.your_domain pour garder un œil sur vos applications.

Conclusion

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

La configuration déclarative de Traefik au niveau du conteneur d'applications facilite la configuration de plus de services, et il n'est pas nécessaire de redémarrer le conteneur traefik lorsque vous ajoutez de nouvelles applications au trafic proxy, car Traefik remarque les modifications immédiatement via le fichier de socket Docker qui c'est de la surveillance.

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