Une règle de routage Traefik décrit à quelles requêtes un router répond, et quand deux règles correspondent à la même requête, Traefik retient celle de plus haute priorité, pas la plus précise. Cette leçon s'adresse à qui publie déjà un service derrière Traefik et veut écrire des règles sûres. Un router est l'objet qui reconnaît une requête et la confie à un service ; sa priorité est le nombre qui départage deux routers. La leçon apprend à choisir ce qu'une règle teste (nom d'hôte, chemin, en-tête, méthode), à prévoir laquelle gagne en cas de recouvrement et à le prouver par des requêtes. Les mesures citées viennent de Traefik 3.7.15, la version du lab.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »La leçon suit le raisonnement d'une règle : l'écrire, prévoir son arbitrage, puis la contrôler.
- Écrire une règle qui combine nom d'hôte, chemin, en-tête et méthode.
- Distinguer un chemin exact d'un préfixe, et en prévoir les débordements.
- Prévoir quel router l'emporte entre deux règles qui se recouvrent.
- Restreindre une application sensible à son nom d'hôte.
- Qualifier une référence de service ou de middleware avec son fournisseur.
- Prouver par une matrice de requêtes qu'un changement ne casse rien.
Prérequis
Section intitulée « Prérequis »Cette leçon part du vocabulaire de Traefik et ne redécrit ni la découverte des services, ni les middlewares.
- Le modèle de Traefik : entrypoints, routers, services et middlewares, pour les mots que la leçon reprend.
- La publication de conteneurs de Traefik avec Docker et la déclaration d'une route dans un fichier avec le fournisseur fichier : la leçon les suppose connues.
- Savoir lire un fichier YAML et envoyer une requête avec
curl.
Les leçons Docker et fichier enseignent comment Traefik découvre un service. Celle-ci enseigne ce qui vient après : comment une règle choisit ses requêtes, quel que soit le fournisseur qui l'a déclarée.
Sur quoi une règle de routage peut-elle porter ?
Section intitulée « Sur quoi une règle de routage peut-elle porter ? »Une règle est une expression que Traefik évalue pour chaque requête reçue : si elle est vraie, le router peut la prendre. Reprenons les mots. Un router est l'objet qui reconnaît une requête et la confie à un service, c'est-à-dire la liste des serveurs (les backends) qui y répondent. La règle (rule) est la condition du router. Chaque test élémentaire qu'elle contient s'appelle un matcher, comme Host ou PathPrefix.
Voici les matchers que cette leçon manipule, tous de la syntaxe v3 décrite dans la leçon de concepts. Les exemples de la dernière colonne ont été essayés sur Traefik 3.7.15.
| Matcher | Ce qu'il teste | Exemple |
|---|---|---|
Host(`…`) | le nom d'hôte demandé (en-tête Host) | Host(`m.lab.test`) |
Path(`…`) | le chemin, exactement | Path(`/v2`) |
PathPrefix(`…`) | le début du chemin | PathPrefix(`/api`) |
Header(`…`, `…`) | un en-tête de requête et sa valeur | Header(`X-Env`, `staging`) |
Method(`…`) | la méthode HTTP | Method(`POST`) |
Query(`…`, `…`) | un paramètre de la chaîne de requête | Query(`debug`, `1`) |
Le nom d'hôte est celui que le client écrit dans l'en-tête Host de sa requête, et c'est le client qui le fixe. Cette remarque servira plus bas : curl -H 'Host: m.lab.test' http://127.0.0.1/ suffit à se faire passer pour n'importe quel nom, sans toucher au DNS.
Les matchers se combinent avec && (ET), || (OU) et ! (NON), et les parenthèses regroupent. La règle Host(`n.lab.test`) && !PathPrefix(`/prive`) prend tout ce qui vise n.lab.test sauf ce qui commence par /prive : mesuré, /ok atteint le backend et /prive reçoit un 404. Les valeurs s'écrivent entre backticks, comme dans la leçon de concepts.
Où s'arrête vraiment un PathPrefix ?
Section intitulée « Où s'arrête vraiment un PathPrefix ? »Le matcher PathPrefix(`/api`) compare des caractères, pas des segments de chemin : il prend aussi /apiary. On croit souvent qu'un préfixe désigne un « dossier », comme /api/ et tout ce qui est dessous. Traefik applique la définition la plus littérale : le chemin de la requête commence-t-il par ces caractères ?
La mesure le confirme. Avec une règle Host(`m.lab.test`) && PathPrefix(`/api`), les requêtes /api/x et /apiary atteignent toutes les deux le backend. Avec Path(`/v2`), qui exige l'égalité, /v2 passe et /v2/x reçoit un 404.
| Règle | Chemin demandé | Résultat mesuré |
|---|---|---|
PathPrefix(`/api`) | /api/x | 200, router retenu |
PathPrefix(`/api`) | /apiary | 200, router retenu (inattendu) |
Path(`/v2`) | /v2 | 200, router retenu |
Path(`/v2`) | /v2/x | 404, aucun router |
Ce débordement n'est pas un défaut de Traefik, c'est une règle qu'il faut écrire avec le bon matcher. Pour ne prendre que /api et ce qui est sous /api/, la combinaison logique est Path(`/api`) || PathPrefix(`/api/`). Choisissez Path quand le chemin est unique (une sonde /health), PathPrefix quand tout un sous-arbre doit suivre, et ajoutez la barre finale du préfixe quand la frontière compte.
Retenez surtout la méthode : pour chaque PathPrefix, écrivez un chemin voisin qui ne doit pas passer et essayez-le. C'est la seule façon de voir un débordement avant qu'un utilisateur le trouve.
Comment Traefik choisit-il entre deux routers qui correspondent ?
Section intitulée « Comment Traefik choisit-il entre deux routers qui correspondent ? »Quand plusieurs routers correspondent à une requête, Traefik les trie par priorité décroissante et retient le premier ; les autres ne reçoivent rien, sans le moindre message. La priorité est un nombre attaché à chaque router. Si vous ne l'écrivez pas, Traefik utilise la longueur de la règle en caractères, comme l'explique la leçon de concepts.
Le schéma suivant montre le trajet d'une requête. Regardez le bloc central : le tri par priorité ne regarde que ce nombre, jamais la précision de la règle.
Prenons deux routers qui visent le même nom d'hôte. Le premier est générique, le second réserve un sous-chemin.
# FRAGMENT de configuration dynamique (non autonome)http: routers: boutique: rule: Host(`boutique.lab.test`) entryPoints: [web] service: boutique boutique-api: rule: Host(`boutique.lab.test`) && PathPrefix(`/api`) entryPoints: [web] service: apiLa première règle compte 25 caractères, la seconde 47. Sans priority, boutique-api a donc la priorité 47 et l'emporte sur /api, tandis que boutique reçoit le reste. L'ordre est le bon, mais par accident arithmétique : une règle plus longue passe devant. La mesure sur Traefik 3.7.15 le montre avec l'API de Traefik, qui affiche une priorité de 24 pour Host(`routage.lab.test`) et de 45 pour la même règle suivie de && PathPrefix(`/v2`). Ces nombres diffèrent des 25 et 47 ci-dessus parce que le nom d'hôte mesuré est plus court d'un caractère : la priorité suit la longueur exacte de la règle écrite, nom compris.
Le piège apparaît quand les deux mécanismes se croisent. Si le router générique porte priority: 100 et le router spécifique priority: 10, le générique passe devant. Mesuré : une requête /v2 partait alors vers le backend du router générique, avec un 200 parfaitement normal, donc aucune alerte pour signaler l'erreur.
Faut-il écrire une priorité explicite ?
Section intitulée « Faut-il écrire une priorité explicite ? »Écrivez priority quand l'ordre voulu ne découle pas de la longueur des règles, et seulement alors. C'est un jugement de bonne pratique et non une règle de Traefik : une priorité explicite est un nombre que personne ne relit, qui doit rester cohérent avec tous les autres routers du même point d'entrée.
Le cas qui l'impose est celui de la leçon de concepts : une règle courte et exacte qui doit passer devant une expression régulière plus longue. Hors de ce cas, laisser la longueur trier évite d'ajouter un nombre arbitraire à maintenir, à condition de vérifier le résultat. Une règle Host(`a`) && PathPrefix(`/b`) est naturellement plus longue que Host(`a`) seul, donc plus prioritaire.
Deux habitudes évitent la plupart des collisions.
- Une seule méthode par groupe de routers. Soit tous les routers qui se recouvrent laissent la longueur trier, soit tous portent une priorité explicite. Mélanger les deux compare une longueur à un nombre choisi à la main, et l'ordre obtenu devient difficile à lire.
- Un écart qui se lit. Si vous fixez des priorités, ordonnez-les par paliers (10, 50, 100) et notez dans un commentaire pourquoi ce router passe devant, sinon le prochain lecteur n'osera pas y toucher.
Après chaque changement de priorité, ne relisez pas seulement le fichier : envoyez les requêtes qui doivent atteindre chaque router, comme dans la section de vérification ci-dessous.
Comment empêcher une application sensible de répondre sous tous les noms ?
Section intitulée « Comment empêcher une application sensible de répondre sous tous les noms ? »Un router dont la règle ne contient pas de Host répond sous tous les noms d'hôte que le client choisit d'écrire. Un panneau d'administration publié avec la seule règle PathPrefix(`/admin`) est joignable par /admin sur n'importe quel nom qui arrive jusqu'à Traefik.
Mesuré avec une telle règle : une requête avec un nom d'hôte tiré au hasard sur /admin recevait un 200 depuis le backend d'administration. Une fois la règle complétée par un Host au nom prévu, la même requête reçoit un 404, et seule celle qui porte le nom prévu atteint l'application.
Ce 404 est l'issue normale quand aucun router ne correspond : Traefik répond lui-même, sans consulter aucun backend. Il est utile à savoir pour interpréter un test, car il ne dit pas « interdit », il dit « aucune règle ne me concerne ».
Gardez deux limites en tête. D'abord, restreindre le nom d'hôte n'est pas authentifier : puisque le client écrit l'en-tête Host, quiconque connaît le nom prévu peut l'écrire. La restriction réduit la surface exposée par erreur, elle ne remplace pas un contrôle d'accès. Ensuite, la protection réelle d'un panneau passe par des middlewares et par une exposition réseau limitée, ce que traitent les middlewares Traefik et la protection du point d'entrée.
Comment référencer un service ou un middleware d'un autre fournisseur ?
Section intitulée « Comment référencer un service ou un middleware d'un autre fournisseur ? »Un nom de service ou de middleware sans suffixe est cherché dans le fournisseur du router qui le cite ; pour viser un autre fournisseur, on écrit nom@fournisseur. Un fournisseur (provider) est la source qui déclare des objets à Traefik : un fichier, des labels Docker. Traefik suffixe chaque objet de son fournisseur : @file pour un fichier, @docker pour des conteneurs. La leçon de concepts détaille ce suffixe ; il sert ici à lever une ambiguïté.
Imaginons un middleware limite déclaré dans un fichier, et un service catalogue publié par les labels d'un conteneur. Un router du fichier qui cite service: catalogue cherche catalogue@file. Deux situations se présentent, et elles ne produisent pas la même erreur.
- Un objet du même nom existe dans le fichier. Traefik le prend, sans se plaindre. Mesuré avec un service
cibledéclaré dans le fichier et un autre publié par Docker : la route répondait502 Bad Gateway(le service du fichier visait une adresse injoignable), et le middleware appliqué ajoutait l'en-tête du fichier, pas celui du conteneur. La route marche en apparence, avec les mauvais objets. - Aucun objet de ce nom n'existe dans le fichier. Le router est marqué
disabledet répond404. Le journal écrit une ligneERRdu typethe service "inconnu@file" does not exist.
La parade est d'écrire le suffixe de l'objet que vous visez, par exemple service: catalogue@docker et middlewares: [limite@file]. Cela revient à nommer qui est responsable de l'objet : c'est une séparation de responsabilités entre ce que le fichier décrit et ce que les conteneurs publient.
Les deux fournisseurs se complètent : le fichier fixe des règles stables, Docker publie des services qui vont et viennent. Pour lire comment chacun déclare ses objets, reportez-vous aux leçons Docker et fichier.
Comment vérifier qu'une règle fait ce que l'on croit ?
Section intitulée « Comment vérifier qu'une règle fait ce que l'on croit ? »Une règle se vérifie par des requêtes qui doivent passer et par des requêtes qui doivent échouer, jamais par la seule relecture du fichier. Comme le nom d'hôte se fixe côté client, curl -H 'Host: …' suffit à simuler n'importe quel nom sans configurer de DNS.
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: m.lab.test' http://127.0.0.1/apiaryCette commande envoie une requête à Traefik avec le nom m.lab.test et n'affiche que le code HTTP. Vérifiez ensuite quel backend a répondu : les backends utilisés par le lab sont des serveurs whoami, dont la réponse contient une ligne Hostname: qui nomme la machine qui a répondu. Cette ligne dit à quel service la requête est arrivée, ce qu'un code 200 seul ne dit pas.
Pour construire une preuve utile, dressez une matrice : une ligne par couple (nom d'hôte, chemin), avec le backend attendu. Les lignes importantes sont les cas négatifs.
| Nom d'hôte | Chemin | Attendu |
|---|---|---|
| le nom prévu | la racine | le backend par défaut |
| le nom prévu | le chemin réservé et un sous-chemin | le backend du chemin |
| un nom tiré au hasard | le chemin sensible | un 404 |
| le nom prévu | un chemin voisin qui ne doit pas passer | le backend par défaut ou un 404 |
Traefik offre aussi un point de contrôle direct : son API liste chaque router avec sa règle, sa priorité calculée, son état (enabled ou disabled) et, pour un router désactivé, la cause de l'erreur. Lancez Traefik avec --api.insecure=true : l'option ouvre l'API sur l'entrypoint nommé traefik, qui écoute par défaut sur le port 8080. La requête curl localhost:8080/api/http/routers renvoie alors ces champs en JSON, ce qui a été mesuré sur 3.7.15 par un port de test publié par le lab. Cette option expose le tableau de bord sans authentification : elle convient à un banc d'essai local, jamais à un point d'entrée exposé, comme le rappelle la protection du point d'entrée.
Quand une requête ne va pas où vous l'attendiez, ne changez pas plusieurs choses à la fois. Regardez d'abord l'état et la priorité des routers qui visent ce nom, puis la règle qui a gagné ; la leçon Dépanner un point d'entrée Traefik détaille la lecture des 404, 502 et 504.
Ajouter une route peut-il en casser une autre ?
Section intitulée « Ajouter une route peut-il en casser une autre ? »Ajouter un router sans rapport ne casse ni les routes existantes ni le processus Traefik, mais un router qui recouvre une route existante peut la détourner. Avec le fournisseur fichier, Traefik surveille son répertoire et recharge la configuration à chaud, après un délai d'au moins 2 secondes par défaut (providersThrottleDuration), comme la leçon sur le fournisseur fichier le montre.
Mesuré sur 3.7.15 : l'ajout d'un second fichier qui déclare un router sur un nom d'hôte inédit a laissé inchangées les réponses des deux routes existantes, a rendu la nouvelle route joignable, et l'heure de démarrage du conteneur Traefik est restée la même. Rien n'a été redémarré, et rien ne s'est cassé.
Le risque tient au tri vu plus haut. Une règle nouvelle qui correspond aussi à des requêtes déjà servies entre dans le tri : si elle est plus longue ou plus prioritaire, elle passe devant, sans erreur. Un nom d'hôte inédit est sans danger ; un PathPrefix large sur un nom déjà utilisé ne l'est pas.
Une bonne pratique, qui relève du jugement : après chaque ajout, rejouez la matrice complète et pas seulement la ligne de la nouvelle route. Les lignes anciennes qui devaient rester stables sont celles qui détectent un détournement.
Mettre en pratique : résoudre des collisions de routage
Section intitulée « Mettre en pratique : résoudre des collisions de routage »Le lab pose un Traefik dont les routes sont mal réglées : une priorité qui empêche une route plus spécifique d'être atteinte, une application d'administration qui répond sous tous les noms, et des références de service et de middleware non qualifiées vers le fournisseur Docker. Vous corrigez le fichier de routes, puis vous prouvez qu'ajouter une route sans rapport ne perturbe rien.
La validation envoie de vraies requêtes au port 80 de la machine et lit le code de réponse, le backend qui répond et un en-tête. Elle vérifie quatre choses : la racine et le chemin réservé atteignent chacun leur backend, le catalogue répond avec l'en-tête venu de Docker, l'application d'administration n'est joignable que sous son nom prévu, et un router ajouté pendant l'exécution laisse les autres routes intactes sans redémarrer Traefik. Le scénario du lab donne la mission, pas la solution.
À retenir
Section intitulée « À retenir »Une règle de routage se juge à ses effets sur des requêtes, pas à sa lecture.
- Une règle combine des matchers (
Host,Path,PathPrefix,Header,Method,Query) avec&&,||et!. - Le matcher
PathPrefix(`/api`)prend aussi/apiary:Pathpour l'exact, une barre finale pour la frontière. - Entre deux routers qui correspondent, la plus haute priorité gagne ; à défaut de
priority, c'est la longueur de la règle, pas sa précision. - Un router sans
Hostrépond sous tous les noms ; restreindre le nom réduit l'exposition mais n'authentifie pas. - Un nom sans suffixe est cherché dans le fournisseur du router : écrivez
nom@fournisseurpour viser un autre fournisseur. - Prouvez avec une matrice de requêtes, cas négatifs compris, et rejouez-la après chaque ajout de route.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Le quiz porte sur la lecture d'une règle, l'arbitrage entre routers, la restriction par nom d'hôte et la qualification des références.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Traefik et HTTPS automatique : résolveur ACME, redirection et options TLS
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications