Traefik afin d’éviter les bouchons

modifié le : 31 mai 2024,
par Theo BOISGARD
 

Présentation de Traefik

Traefik est un ingress controller pour k8s. Le rôle d'un ingress controller est de faire en sorte que les ressources Ingress fonctionnent bien.

Une ressource Ingress elle, sert à faire sortir les applications sur un ip publique. Ici Traefik sert donc à manager les accès aux services.

L'exemple ci-dessous montre un ingress qui fait ressortir un Apache superset qui dans le réseau privée de k8s est sur le port 8088.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
  namespace: s7-2
spec:
  rules:
  - host: monsite.fr
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: s2-superset
            port:
              number: 8088

Si votre Traefik est installé et à une ip publique, cette configuration fera que vous pourez accéder à votre service depuis monsite.fr.

Cependant cette configuration ne fait pas d'https et votre site ne sera donc accéssible que en http.

Le but de cet article est donc de montrer comment déployer sur k8s un ingress controller (ici traefik) qui gère la partie https.

Pour pouvoir avoir un accès sécuriser, nous allons utiliser let's encrypt.

pré-requis

  • un cluster kubernetes

installation

Pour l'installation on va utiliser beaucoup de fichier pour mieux s'y retrouver mais on peut évidemment tout faire dans un seul.

On va utiliser un namespace propre pour avoir bien "ranger" notre installation, c'est toujours plus facile pour s'y retrouver ensuite. On appelle notre namespace "traefik" (attention à bien le changer partout si le nom ne convient pas).


account.yml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-account
  namespace: traefik


role.yml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik-role
  namespace: traefik
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
      - ingressclasses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses/status
    verbs:
      - update


role-binding

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: traefik-role-binding
  namespace: traefik
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: traefik-role
subjects:
  - kind: ServiceAccount
    name: traefik-account
    namespace: traefik


Nous arrivons au fichier principal qui contient le gros de l'application, vous pouvez complètement modifier les "args".
Ici on force par exemple la redirection http vers https (ce qui n'est pas obligatoire). Pensez donc à modifier ces arguments en fonction de ce dont vous avez besoin.

traefik.yml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: traefik-deployment
  namespace: traefik
  labels:
    app: traefik

spec:
  replicas: 1
  selector:
    matchLabels:
      app: traefik
  template:
    metadata:
      labels:
        app: traefik
    spec:
      serviceAccountName: traefik-account
      containers:
        - name: traefik
          image: traefik:v3.0
          args:
            - --api.insecure
            - --providers.kubernetesingress
            - --entrypoints.web.address=:80
            - --entrypoints.websecure.address=:443
            - --entrypoints.web.http.redirections.entryPoint.to=websecure
            - --entrypoints.web.http.redirections.entryPoint.scheme=https
            - --entrypoints.web.http.redirections.entrypoint.permanent=true
            - --entryPoints.websecure.http.tls
            - --certificatesresolvers.myresolver.acme.tlschallenge=true
            - --certificatesresolvers.myresolver.acme.email=[EMAIL]
            - --entryPoints.websecure.http.tls.certResolver=myresolver
          ports:
            - name: dashboard
              containerPort: 8080


traefik-service.yml

apiVersion: v1
kind: Service
metadata:
  name: traefik-dashboard-service
  namespace: traefik
spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: dashboard
  selector:
    app: traefik
---
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-service
  namespace: traefik
spec:
  type: LoadBalancer
  ports:
    - targetPort: web
      port: 80
  selector:
    app: traefik


Maintenant tous ces beaux petits fichiers de configurations crées il ne reste plus qu'à taper la commande magique :

kubectl apply -f role.yml \
            -f account.yml \
            -f role-binding.yml \
            -f traefik.yml \
            -f traefik-services.yml


⚠️⚠️⚠️

Attention à bien être connecté au cluster via la commande export !

Sinon évidemment on va avoir du mal à intéragir avec l'API du cluster manager.

Une fois l'application déployée, il y aura deux services dans le namespace traefik.

  • Le premier, "traefik-dashboard-service", servira à se connecter au dashboard sur le port 8080 de l'ip publique du service.

  • Le deuxième, "traefik-web-service", servira pour vos enregistrement dns, dans notre cas tout les enregistrements dns seront fait vers cette ip et c'est ensuite traefik qui redirige vers le bon service du cluster.

On a donc un super dashboard
traefik dashboard.png

Connecter mon application au traefik

prérequis

  • avoir un enregistrement dns

Le plus simple c'est d'avoir une application qui a déjà une partie ingress dans sa charts (dans le cadre de helm)

Par exemple dans superset on ira modifier cette valeur :

ingress:
  enabled: true
  ingressClassName: traefik
  annotations: {
      traefik.enable=true
      traefik.http.routers.superset.rule=Host(`[enregistrement dns]`)
      traefik.http.routers.superset.entrypoints=websecure
      traefik.http.routers.superset.tls.certresolver=myresolver
  }

  path: /
  pathType: Prefix
  hosts:
    - monsite.fr
  tls: [
    certResolver: myresolver
  ]

A noter que cette installation permet d'avoir plusieurs services qui seront alors connecté sur un traefik qui n'aura qu'une seule adresse ip publique.

Les services seront tagger en fonction de leur enregistrement dns (à prévoir avant de faire l'installation donc)

Comme il existe approximativement une façon de faire par service, à vous de l'adapter mais les grandes lignes sont là !



Article réalisé par Ian BELLAY et Théo BOISGARD