Aller au contenu

Traefik

Introduction

Dans un cluster Kubernetes, les applications tournent généralement à l’intérieur du cluster et ne sont pas directement accessibles depuis Internet.

Traefik agit comme une porte d’entrée entre les utilisateurs externes et les applications Kubernetes.

Il permet notamment de :

  • exposer des applications web
  • gérer le routage HTTP/HTTPS
  • équilibrer la charge entre plusieurs pods
  • gérer les certificats TLS
  • sécuriser les accès
  • simplifier l’accès aux applications Kubernetes
flowchart TB INTERNET("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Internet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;") subgraph TRAEFIK["Traefik (Edge Router)"] direction LR ENTRYPOINT("Entrypoint<br>:80 / :443") ROUTER("Routers<br>Matching") MIDDLEWARE("Middlewares<br>Transform") ENTRYPOINT --> ROUTER ROUTER --> MIDDLEWARE end subgraph SERVICES["Services"] direction LR %% horizontal API("api:3000") WEB("web:80") AUTH("auth:8080") %% La directive direction LR n'est pas forcément prise en compte, donc il faut %% créer un lien invisible (~~~) pour assuré l'affichage des boxs horizontalement API ~~~ WEB WEB ~~~ AUTH %% les ~ sont sensés être transparent. Comme cela ne semble pas le cas on cache %% les liens en leurs mettant 0px d'épaisseur (on pourrait également mettre la %% la même couleur que le fond linkStyle 2,3 stroke-width:0px end %% Liason INTERNET --> TRAEFIK TRAEFIK --> SERVICES %% Class %% color: couleur du texte %% fill: La couleur du fond %% strocke: La couleur de la bordure %% strocke-width: Largeur de la bordure %% rx,ry rayon plius le chiffre est grand plus plus rond sera le coin %% font-weight:bold %% font-family:cursive (ou arial, times, etc.) : Pour changer le style de la police. %% font-style:italic : Pour mettre le texte en italique. %% font-size: taille de la police classDef lblueStyle fill:#e6f3ff,stroke:#000000,stroke-width:2px,rx:12,ry:12,color:#1a1a1a classDef greenStyle fill:#dfeee3,stroke:#2f855a,stroke-width:2px,rx:12,ry:12,color:#1a1a1a classDef blueStyle fill:#cfe2f3,stroke:#2b6cb0,stroke-width:2px,rx:12,ry:12,color:#1a1a1a classDef orangeStyle fill:#f9dec9,stroke:#dd6b20,stroke-width:2px,rx:12,ry:12,color:#1a1a1a classDef mauveStyle fill:#e9d8f3,stroke:#9b2c9b,stroke-width:2px,rx:12,ry:12,color:#1a1a1a classDef container fill:#f0f0f0,stroke:#4a5568,stroke-width:2px,rx:12,ry:12,color:#1a1a1a %% Style des liens (flèches) linkStyle default stroke:#000000,stroke-width:1px,fill:none %% Attribution groupée ici class INTERNET lblueStyle class TRAEFIK,WEB greenStyle class ENTRYPOINT,API blueStyle class ROUTER,AUTH orangeStyle class MIDDLEWARE mauveStyle class SERVICES container

A savoir

Terme Définition simple
Reverse proxy Serveur qui reçoit les requêtes et les transmet aux services backend
Load balancer Répartiteur de charge entre plusieurs instances d'un même service
Edge router Point d'entrée unique pour tout le trafic vers votre infrastructure
Cloud-native Conçu pour les environnements conteneurisés (Docker, Kubernetes)
Provider Source de configuration (Docker, Kubernetes, fichier, etc.)

Intallation de Traefik

  • Installation de Traefik en haute disponibilité (HA)
  • Mise en place du HTTPS obligatoire
  • Sécurisation du dashboard Traefik
  • Configuration du TLS interne (avec CA personel)
  • Intégration avec MetalLB
  • Séparation des namespaces
  • Exposition sécurisée des applications

Fichier values.yaml

Créer le fichier values.yaml

cat << 'EOF' > /tmp/values.yaml
# -----------------------------------------------------------------------------
# Déploiement Traefik v3.6
# -----------------------------------------------------------------------------
deployment:
  enabled: true
  replicas: 2

image:
  tag: v3.6

ingressClass:
  enabled: true
  isDefaultClass: true
  name: traefik-system

# -----------------------------------------------------------------------------
# Logs
# -----------------------------------------------------------------------------
logs:
  general:
    level: INFO

# -----------------------------------------------------------------------------
# Providers Kubernetes
# -----------------------------------------------------------------------------
providers:
  kubernetesCRD:
    enabled: true
    allowCrossNamespace: false

  kubernetesIngress:
    enabled: true
    publishedService:
      enabled: true

# -----------------------------------------------------------------------------
# API / Dashboard
# -----------------------------------------------------------------------------
api:
  dashboard: true
  insecure: false

# -----------------------------------------------------------------------------
# Ports / Entrypoints
# -----------------------------------------------------------------------------
ports:
  web:
    port: 80
    expose:
      default: true
    exposedPort: 80
    protocol: TCP

  websecure:
    port: 443
    expose:
      default: true
    exposedPort: 443
    protocol: TCP
    #tls:
    #  enabled: true

# -----------------------------------------------------------------------------
# Service LoadBalancer via MetalLB
# -----------------------------------------------------------------------------
service:
  enabled: true
  type: LoadBalancer

  annotations:
    metallb.universe.tf/address-pool: default

  spec:
    externalTrafficPolicy: Local

# -----------------------------------------------------------------------------
# Sécurité
# -----------------------------------------------------------------------------
securityContext:
  capabilities:
    drop:
      - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 65532
  runAsGroup: 65532

podSecurityContext:
  fsGroup: 65532

# -----------------------------------------------------------------------------
# Resources
# -----------------------------------------------------------------------------
resources:
  requests:
    cpu: 100m
    memory: 128Mi

  limits:
    cpu: 500m
    memory: 512Mi

# -----------------------------------------------------------------------------
# Metrics Prometheus
# -----------------------------------------------------------------------------
metrics:
  prometheus:
    enabled: true

# -----------------------------------------------------------------------------
# TLS par défaut
# -----------------------------------------------------------------------------
additionalArguments:
  - "--serversTransport.insecureSkipVerify=false"
  - "--entrypoints.websecure.http.tls=true"
  - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
  - "--entrypoints.web.http.redirections.entrypoint.scheme=https"

# -----------------------------------------------------------------------------
# Persistence facultative pour ACME
# (désactivée ici car vous utilisez une CA interne)
# -----------------------------------------------------------------------------
persistence:
  enabled: false

# -----------------------------------------------------------------------------
# Désactivation des fonctionnalités inutiles
# -----------------------------------------------------------------------------
ingressRoute:
  dashboard:
    enabled: false

experimental:
  plugins: {}
EOF

Déployer Traefik

Installer le dépôt helm pour Traefik

helm repo add traefik https://traefik.github.io/charts
helm repo update

Déployer Traefik

helm upgrade traefik-system traefik/traefik \
--install \
--atomic \
--cleanup-on-fail \
--values=/tmp/values.yaml \
--namespace traefik-system \
--create-namespace

Configuration du dashboard

Créer le fichier dashboard.yaml

cat << 'EOF' > /tmp/dashboard.yaml
# -----------------------------------------------------------------------------
# Namespace
# -----------------------------------------------------------------------------
apiVersion: v1
kind: Namespace
metadata:
  name: traefik-dashboard
---
# -----------------------------------------------------------------------------
# Middleware pour l'authentification
# -----------------------------------------------------------------------------
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: dashboard-auth
  namespace: traefik-dashboard
spec:
  basicAuth:
    secret: traefik-dashboard-auth
---
# -----------------------------------------------------------------------------
# Route Ingress
# -----------------------------------------------------------------------------
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard
  namespace: traefik-dashboard
spec:
  entryPoints:
    - websecure

  routes:
    - match: Host(`DASHBOARD_URL`)
      kind: Rule

      middlewares:
        - name: dashboard-auth

      services:
        - name: api@internal
          kind: TraefikService

  tls:
    secretName: dashboard-tls
EOF

Définir l'url d'accès

Dans cet exemple j'utilise traefik.gmolab.net pour accéder au dashboard

sed -i "s|DASHBOARD_URL|traefik.gmolab.net|" /tmp/dashboard.yaml

Entrée DNS

Récupérer l'adresse IP public (EXTERNAL-IP)

kubectl get svc -n traefik-system
NAME             TYPE           CLUSTER-IP      --> EXTERNAL-IP     PORT(S)                      AGE
traefik-system   LoadBalancer   10.100.154.90   --> 172.31.10.200   80:30336/TCP,443:31639/TCP   64m

J'ai créé l'entrée suivante dans mon DNS

172.31.10.200 traefik.gmolab.net
kubectl apply -f /tmp/dashboard.yaml

Secrets

Authentification pour le dashboard

Installer l'utilitaire htpasswd

sudo dnf install httpd-tools -y

Changer monMotDePasseSecret par un mot de passe de votre choix

kubectl create secret generic traefik-dashboard-auth \
  -n traefik-dashboard \
  --from-literal=users="$(htpasswd -nb admin 'monMotDePasseSecret')" \
  --dry-run=client -o yaml | kubectl apply -f -

Certificats

Copier vos fichiers de certificats dans le dossier /tmp et renommer les en tls.crt et tls.key

Créer le secret contenant les certificat

kubectl create secret tls dashboard-tls \
  --namespace traefik-dashboard \
  --cert=/tmp/tls.crt \
  --key=/tmp/tls.key

Accès au dashboard

https://traefik.gmolab.net

Sources


Version Date Change Auteur
1.0 14.05.2026 Création GMo