Aller au contenu

Infrastructure

KanjiIQ s'exécute sur un cluster Kubernetes auto-hébergé chez Hetzner, utilisant Traefik pour l'ingress et cert-manager pour le TLS automatique.

Hébergement : Serveur dédié Hetzner

L'intégralité de l'environnement de production s'exécute sur un seul serveur dédié Hetzner :

  • Distribution Kubernetes : k3s (Kubernetes léger, binaire unique)
  • OS : Linux
  • Réseau : IPv4 publique avec Cloudflare DNS

Pourquoi Hetzner ?

  • Tarification mensuelle prévisible (pas de frais par requête ou par heure)
  • Centres de données européens (compatible GDPR)
  • Excellent rapport qualité-prix
  • Accès root complet pour l'installation de k3s

Kubernetes : k3s

k3s est une distribution Kubernetes légère certifiée CNCF qui inclut :

  • Runtime de conteneurs : containerd
  • Contrôleur d'ingress : Traefik (pré-installé)
  • Load balancer de service : Klipper
  • Stockage : Local path provisioner
  • DNS : CoreDNS

k3s exécute Kubernetes avec un seul binaire (~100 Mo) au lieu de l'installation multi-composants kubeadm. Il est entièrement compatible avec les API Kubernetes standard — toutes les commandes kubectl et tous les manifestes fonctionnent de manière identique.

Ingress : Traefik

Traefik sert de contrôleur d'ingress du cluster, gérant :

  • Terminaison TLS : HTTPS automatique pour tous les domaines
  • Routage : Routage basé sur l'hôte vers les services (kanjiiq.com vers le frontend, api.kanjiiq.com vers le backend)
  • Limitation de débit : Limitation par IP via les middlewares CRD
  • En-têtes de sécurité : HSTS, X-Frame-Options, CSP via la chaîne de middlewares

Configuration des middlewares

# Public traffic: rate limit + security headers
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: public-security-chain
spec:
  chain:
    middlewares:
      - name: rate-limit        # 100 req/min, burst 50
      - name: security-headers  # HSTS, X-Frame-Options, etc.
# Admin traffic: stricter rate limit + auth
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: admin-security-chain
spec:
  chain:
    middlewares:
      - name: api-rate-limit    # 50 req/min, burst 25
      - name: security-headers
      - name: admin-auth

TLS : cert-manager + Let's Encrypt

Gestion automatique des certificats TLS :

graph LR
    I[Ingress with<br/>cert-manager annotation] --> CM[cert-manager]
    CM --> LE[Let's Encrypt<br/>ACME challenge]
    LE --> C[TLS Certificate]
    C --> S[Kubernetes Secret]
    S --> T[Traefik uses cert<br/>for HTTPS]
  • ClusterIssuer : letsencrypt-prod (autorité de certification à l'échelle du cluster)
  • Type de challenge : HTTP-01 via Traefik
  • Renouvellement : Automatique avant expiration
  • Stockage : Certificats stockés en tant que Kubernetes Secrets

Les ressources Ingress demandent des certificats avec une seule annotation :

annotations:
  cert-manager.io/cluster-issuer: letsencrypt-prod

DNS : Cloudflare

Le DNS des domaines est géré via Cloudflare :

  • Enregistrements A : Pointent vers l'IP du serveur Hetzner
  • Proxy : Couche CDN/WAF Cloudflare optionnelle
  • En-tête CF-IPCountry : Utilisé par le backend pour la géolocalisation sans bases de données IP

Registre de conteneurs : Forgejo

Les images Docker sont stockées dans le Forgejo Container Registry sur <registry> :

  • Co-localisé avec le code source (plateforme unique)
  • Secrets de pull d'images configurés dans Kubernetes (forgejo-registry)
  • Tags : :latest + :COMMIT_SHA pour chaque build
  • Aucune dépendance à un registre externe (Docker Hub, GHCR, etc.)

Allocation des ressources

Composant CPU Request CPU Limit Memory Request Memory Limit
Backend 250m 500m 256Mi 512Mi
Frontend 100m 200m 128Mi 256Mi
PostgreSQL 250m 500m 256Mi 512Mi
Docs 10m 100m 32Mi 64Mi