Traefik comme reverse proxy sur GKE

0

Traefik est un reverse proxy / load balancer qui supporte de nombreux backends (Docker, Swarm mode, Kubernetes, Marathon, et plus). GKE (Google Kubernetes Engine)  est le service Kubernetes managé par Google.

Dans cet article je vais vous montrer comment utiliser Traefik comme reverse proxy pour vos applications hébergées sur GKE. Nous l’utiliserons également pour répartir la charge entre les pods et pour sécuriser le trafic en https grâce à des certificats TLS générés avec Let’s Encrypt.

Le projet

Je vais déployer une application composée de deux conteneurs. Un front en HTML / Javascript et un back en NodeJS.

Le back incrémente un compteur et nous renvoie le nom du host sur lequel il est hébergé.

server.js :

Le front appelle l’api back et affiche la réponse :

index.html :

Les images des conteneurs sont disponibles sur Docker Hub :

Les sources sont sur GitHub : https://github.com/Zenika/traefik-gke-demo/tree/1.0.0

Préparation

Pour commencer, je prépare mon environnement pour créer le cluster dans la zone europe-west-1-c sur mon projet :

Les fichiers de configuration présentés dans cet article sont appliqués sur le cluster via la commande suivante :

Création du cluster kubernetes

Je vais créer un cluster Kubernetes en version 1.9.6 et composé de trois noeuds. J’utilise des instances préemptibles pour faire diminuer la facture (pour plus de détails, je vous invite à consulter cet article).

Création du cluster :

On peut vérifier que GKE a créé un cluster ainsi que trois machines virtuelles :

Ensuite je configure la commande kubectl pour qu’elle se connecte au cluster et je vérifie que l’accès au cluster fonctionne :

Création du service back

J’ajoute un déploiement pour le service back. Deux instances de ce dernier seront déployées, elles écoutent sur le port 3000.

01_back_deployment.yml :

Ensuite j’expose les pods créés avec un service. Ce dernier est de type NodePort, c’est nécessaire pour fonctionner avec Traefik.

02_back_service.yml :

Création du service front

Maintenant je vais déployer le service front sur le cluster. Cette fois je déploie une seule copie du conteneur qui répond sur le port 80.

03_front_deployment.yml :

Je déclare le service associé, encore une fois de type NodePort.

04_front_service.yml :

Création des autorisations pour Traefik

Depuis la version 1.6 de Kubernetes, RBAC (Role-Based Access Control) est activé par défaut sur GKE. Lorsque RBAC est activé, il faut donner l’autorisation à Traefik d’accéder aux API Kubernetes pour mettre à jour dynamiquement les règles de routage.

Pour commencer, je dois me donner le droit de créer des nouveaux rôles dans le cluster :

Ensuite, je crée un nouveau rôle avec les droits dont à besoin Traefik et j’affecte ce rôle à un compte de service.

05_traefik_cluster_role.yml :

Configuration de Traefik

Je vais déployer le fichier de configuration Traefik en utilisant une ConfigMap qui sera montée en lecture seule via un volume. Ce fichier de configuration active le https pour le domaine traefik-gke-demo.zenika.com grâce à Let’s Encrypt,  ainsi que la redirection http vers https.

06_traefik_config.yml :

Remarque : Pour que la génération du certificat https fonctionne, le domaine listé doit exister et répondre sur le port 80 (l’obtention de l’adresse ip du service est faite plus bas).

Sauvegarde acme.json

La configuration ci-dessus spécifie que le fichier de gestion des certificats générés par Let’s Encrypt doit être enregistré dans /etc/traefik/acme/acme.json. Or je veux conserver ce fichier lorsque le pod est recréé, pour cela je vais le sauvegarder sur un disque persistent.

La création du disque se fait avec la commande suivante :

Ensuite, je crée une machine virtuelle temporaire pour y attacher le disque afin de le formater et d’y créer le fichier acme.json vide avec les bonnes permissions (nécessaire pour le lancement de Traefik).

Création de la machine virtuelle et ajout du disque :

Connexion à la VM, formatage du disque, création du fichier acme.json :

Une fois ces opérations terminées je détache le disque et supprime la machine virtuelle :

Remarque : Le disque créé ne peut être monté que par une machine à la fois en écriture. Si vous voulez utiliser plus d’une instance de Traefik pour faire de la haute disponibilité, les certificats doivent être stockés dans un Key Value Store  comme Consul : https://docs.traefik.io/user-guide/cluster/.

Création d’une ip statique

Avant de déployer Traefik je vais créer une adresse ip statique à lui assigner. La seconde commande affiche l’ip qui a été générée et qui devra être mise dans le fichier de service.

Déploiement de Traefik

Je crée un déploiement pour Traefik qui utilise le compte de service créé précédemment. Le fichier de configuration traefik.toml et le disque persistent sont montés via des volumes.

07_traefik_deployment.yml :

Je crée également un service de type LoadBalancer pour exposer Traefik vers l’extérieur via l’ip statique que j’ai créé. Ce service expose également l’interface d’administration de Traefik sur le port 8080.

08_traefik_service.yml :

Attention : Si le nom de domaine (ici traefik-gke-demo.zenika.com) n’existe pas lors du déploiement de Traefik ou qu’il ne pointe pas sur la bonne ip, la génération du certificat https échouera. Si cela arrive, il faut supprimer le pod et une nouvelle génération sera effectuée lors de la création d’un nouveau pod par Kubernetes.

Définition des règles de routage

Maintenant que les services back et front sont déployés, ainsi que Traefik, je dois indiquer à ce dernier les règles de routage à appliquer. Je veux que toutes les requêtes qui arrivent sur /api soient envoyées sur le back et toutes les requêtes qui arrivent sur / partent sur le front.

Pour cela je déclare deux ressources ingress qui configurent les règles à appliquer. Je leur précise une priorité pour que le chemin /api soit traité avant /, sinon toutes les requêtes seront envoyées sur le front.

09_ingress_controller.yml :

Test de l’application

J’accède à l’application via l’url https://traefik-gke-demo.zenika.com/. Chaque click sur le bouton “Say hello” incrémente le compteur sur un des services back et nous renvoie son nom.

 

Pour vérifier que Traefik met sa configuration à jour dynamiquement je peux détruire tous les pods et attendre que Kubernetes en crée de nouveaux :

Sans actualiser la page web je clique de nouveau sur le bouton “Say Hello” :

La requête a bien été redirigée vers un des nouveaux pods.

Conclusion

Vous savez désormais comment mettre en place Traefik pour gérer le trafic entrant sur un cluster Kubernetes sans vous préoccuper de la découverte des services ou du renouvellement des certificats Let’s Encrypt.

 

Partagez cet article.

A propos de l'auteur

Ajouter un commentaire