Traefik

C'est quoi Traefik ?

Traefik (qui se prononce "traffic") est un soft open-source (github) faisant office de reverse proxy et de load balancer pour toutes les applications HTTP et TCP, il s'intègre très facilement et rapidement sur les nouvelles technologies de clustering (Kubernetes, Docker/Swarm, Rancher, Amazon ECS, ...), et se configure de manière automatique et dynamique, finalement que demander de plus ? 😎

traefik-architecture

Sachez qu'il est développé dans le language Go ce qui le rend très souple puisque toutes les dépendances nécessaires sont dans le seul fichier exécutable (à télécharger selon l'architecture).

Pourquoi j'utilise Traefik ?

A l'époque (quelques années en arrière) j'utilisais le service Nginx comme beaucoup de monde pour sa simplicité et ses performances. Puis début 2016 je suis tombé sur Traefik (un peu par hasard j'avoue) qui avait l'air d'être intéressant, j'étais surtout attiré par son fonctionnement dynamique et son intégration avec Docker. J'ai pu le tester pendant plusieurs semaines et plus le temps passait, plus je tombais amoureux (et c'est toujours le cas aujourd'hui).

Le fait qu'il soit portable (seulement un fichier à télécharger et à exécuter) est aussi quelque chose d'intéressant car c'est très facile à maintenir.

Je contribue aussi quotidiennement aux updates de Traefik dans Homebrew pour macOS.

Hetzner

Pourquoi Hetzner ?

Si j'utilise Hetzner depuis quelques années c'est pour plusieurs raisons. La première (on va pas se mentir) ce sont le prix des instances qui sont très abordables (voir ici). La seconde étant que leur infrastructure fonctionne très bien (je n'ai jamais eu de problème en particulier) et que c'est rapide, ça reste sur une base KVM, le déploiement se fait en 20 secondes. La troisième est sur le service client qui assure tout en étant rapide (dernièrement j'avais besoin d'une image ISO qui n'était pas dans la liste publique, j'ai donné une URL, et en moins de 10 minutes j'avais ça à disposition).

A côté de tout ça l'interface d'administration est plutôt cool à utiliser (et légère), pas mal d'options disponibles (backups, snapshots, upgrades, floating ip, ...) et les outils externes/tiers sont bien pratiques comme par exemple leur API pour l'automatisation, hcloud-cli pour toutes les commandes CLI ou bien le provider hcloud chez Terraform, bref tout ce qu'il faut !

2019-10-31_20h03_09

Kubernetes

J'utilise k3s car la version standard (k8s) trop gourmande en ressources à cause des nombreuses fonctionnalités pour assurer la rétrocompatibilité, gérer les services des clouds providers, des éléments en alpha/beta et des services comme etc qui a pour but de stocker les informations du cluster et qui bouffe pas mal de ram. Donc k3s c'est la version légère de k8s, qui supprime tous les éléments legacy, alpha, les plugins des clouds providers et surtout etcd est remplacé par un simple sqlite3.

Donc au final pour mes besoins (et pour mes tests) ce petit k3s est largement suffisant. A savoir que k3s fonctionne avec cette base :

  • containerd (en remplacement de docker)
  • flannel
  • coredns
  • traefik

Installation et configuration (k3s)

L'installation de k3s est vraiment très simpe ! Aussi pour installer un noeud master ou un worker. La seule particularité qu'on aura à l'installation ici c'est de ne pas installer Traefik car il se trouve dans la version 1.7, hors on souhaite une version 2.1 un peu custom.

Donc pour le noeud master :

curl -sfL https://get.k3s.io | sh -s - --no-deploy=traefik
sleep 30
k3s kubectl get node

Et pour le(s) noeud(s) worker :

k3s agent --server https://myserver:6443 --token ${NODE_TOKEN}

Le token se trouve sur le noeud master dans le fichier /var/lib/rancher/k3s/server/node-token.

Installation et configuration (traefik)

Pour ce soit plus simple et lisible, les manifests sont sur mon Github : https://github.com/djerfy/kubernetes-ingress-traefik

Je vous invite donc à faire un clone du dépôt sur le serveur :

git clone https://github.com/djerfy/kubernetes-ingress-traefik ingress-traefik

La configuration du Traefik se trouve dans le fichier ConfigMap.yaml et avant d'appliquer les fichiers vous devrez modifier l'adresse email pour l'enregistrement Let's Encrypt (lignes 58 & 66 à ce jour). Volontairement c'est un peu bourré de configuration custom, histoire de savoir comment est organisé la chose 🙂

Et donc quand la configuration est satisfaisante pour vous, suffit de l'appliquer :

kubectl apply -f ingress-traefik/

Quelques secondes après vous devriez vous retrouver avec cette vue :

kubectl-get-pods-after-apply

Gestion des certificats Let's Encrypt

Traefik permet la gestion et le renouvellement des certificats Let's Encrypt et il le fait vraiment très bien ! L'option n'est pas activée par défaut mais ça représente juste quelques lignes de configuration. Mais rassurez-vous c'est intégré dans mes manifests sous 2 environments, le staging (pour vos tests) et la production. Je vous recommande d'utiliser le staging au début et quand le fonctionnement vous semble bon, passer sur la production, ça vous évitera d'être bloqué par les limitations. N'oubliez pas de changer l'email (lignes 58 & 66) dans le fichier ConfigMap.yaml.

traefik-configmap-letsencrypt

Dashboard

Le dashboard est configuré pour écouter sur le port 8080 et par défaut (dans mes manifests) il est accessible. Je vous invite à le supprimer du Service.yaml si vous en avez pas besoin.

La vue par défaut :

traefik-ui-default

La vue HTTP Routers :

traefik-ui-http-routers

La vue HTTP Middlewares :

traefik-ui-http-middlewares

Intégration de son application

Maintenant qu'on a l'ingress controller (Traefik) de déployé et fonctionnel, on test ça ? 😅

L'idée étant de déployer un service whoami qui permettra d'avoir une vue technique d'une requête. Pour vos autres services (WordPress, API, etc) ce sera identique. Rien ne change sauf la partie IngressRoute qui devient spécifique puisqu'on utilise du CRD (Custom Resource Definitions).

Par exemple voici la configuration complète du service whoami répondant au domaine whoami.k3s.xorhak.io :

kind: Namespace
apiVersion: v1
metadata:
  name: whoami
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: whoami
  namespace: whoami
  labels:
    app: whoami
spec:
  replicas: 2
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: containous/whoami
          ports:
            - name: web
              containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: whoami
spec:
  ports:
    - protocol: TCP
      name: web
      port: 80
  selector:
    app: whoami
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-http
  namespace: whoami
spec:
  entryPoints:
    - http
  routes:
  - match: Host(`whoami.k3s.xorhak.io`)
    kind: Rule
    services:
    - name: whoami
      port: 80
    middlewares:
    - name: default-headers@file
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: whoami-https
  namespace: whoami
spec:
  entryPoints:
    - https
  routes:
  - match: Host(`whoami.k3s.xorhak.io`)
    kind: Rule
    services:
    - name: whoami
      port: 80
    middlewares:
    - name: default-headers@file
  tls:
    certResolver: letsencrypt

Copiez/collez tout ça dans un fichier (ex: whoami.yaml) et appliquez-le :

kubectl apply -f whoami.yaml

Attendez donc quelques secondes et en appelant le site https://whoami.k3s.xorhak.io vous devriez avoir votre certificat Let's Encrypt valide :

straefik-https-whoami

Conclusion

J'adore toujours autant Traefik (😍) et son intégration dans un cluster Kubernetes (via CRD) est juste une merveille. Vous retrouvrez aussi tous ces détails sur la documentation officielle (ici) et je vous invite à prendre connaissance de toutes les options et possibilités qu'il offre.

La limitation que j'ai pu trouvé jusqu'à aujourd'hui sur un cluster étant le stockage des certificats Let's Encrypt. Dans notre cas il est stocké dans un volume qui utilise le plugin local-path de k3s, donc en local sur l'instance master. Si vous avez plusieurs noeuds il sera alors obligatoire de partager ça par l'intermédiaire d'un NFS par exemple. J'attends avec impatience un support complet de Consul.

Les commentaires sont ouverts si vous avez des suggestions et les PR sur le dépôt Github sont les bienvenus 😃 🍺 🌴