Aller au contenu

Manifestes Kubernetes

Toutes les ressources Kubernetes sont définies dans le répertoire k8s/ et appliquées dans l'ordre numéroté.

Vue d'ensemble des manifestes

Fichier Ressource Fonction
00-namespace.yaml Namespace Crée le namespace jlpt-kanji
01-secrets.yaml Secret URL de la base de données, secret JWT, clé OpenAI
02-postgres-pvc.yaml PersistentVolumeClaim Stockage de 10Gi pour PostgreSQL
03-postgres-deployment.yaml Deployment + Service Base de données PostgreSQL 15
04-libretranslate-deployment.yaml Deployment + Service Traduction auto-hébergée (optionnel)
05-deployment.yaml Deployment Application principale (conteneurs frontend + backend)
06-service.yaml Service (x2) Services Frontend (:80) et Backend (:8080)
07-ingress.yaml Ingress Routage Traefik pour jlpt.iqquest.app
08-security-middlewares.yaml Middleware (CRD) Limitation de débit et en-têtes de sécurité
ingress-kanjiiq.yaml Ingress Routage pour les domaines kanjiiq.com
ingress-docs.yaml Ingress Routage pour docs.kanjiiq.app
docs-deployment.yaml Deployment Site de documentation
docs-service.yaml Service Service de documentation

Déploiement initial

Appliquer les manifestes dans l'ordre :

# Create namespace and secrets
kubectl apply -f k8s/00-namespace.yaml
kubectl apply -f k8s/01-secrets.yaml

# Database
kubectl apply -f k8s/02-postgres-pvc.yaml
kubectl apply -f k8s/03-postgres-deployment.yaml

# Application
kubectl apply -f k8s/05-deployment.yaml
kubectl apply -f k8s/06-service.yaml

# Networking
kubectl apply -f k8s/07-ingress.yaml
kubectl apply -f k8s/08-security-middlewares.yaml
kubectl apply -f k8s/ingress-kanjiiq.yaml

Namespace : jlpt-kanji

Toutes les ressources résident dans un seul namespace :

apiVersion: v1
kind: Namespace
metadata:
  name: jlpt-kanji

Cela fournit :

  • L'isolation des ressources par rapport aux autres charges de travail
  • Un RBAC ciblé (si nécessaire)
  • Un nettoyage facile (kubectl delete namespace jlpt-kanji)
  • L'application de quotas de ressources (si nécessaire)

Gestion des secrets

Les valeurs sensibles sont stockées dans des Kubernetes Secrets (non committés dans Git) :

apiVersion: v1
kind: Secret
metadata:
  name: jlpt-kanji-secrets
  namespace: jlpt-kanji
type: Opaque
stringData:
  database-url: "postgresql://user:pass@jlpt-postgres:5432/jlpt_flashcard"
  jwt-secret: "random-secret-string"
  openai-api-key: "sk-..."

Le fichier 01-secrets.yaml dans le dépôt est un modèle — les valeurs réelles sont appliquées manuellement sur le serveur.

Conception du pod

Le pod de l'application principale exécute deux conteneurs côte à côte :

spec:
  replicas: 2
  template:
    spec:
      imagePullSecrets:
        - name: forgejo-registry
      containers:
        - name: backend
          image: <registry>/jlpt-kanji-backend:latest
          ports:
            - containerPort: 8080
          resources:
            requests: { memory: "256Mi", cpu: "250m" }
            limits: { memory: "512Mi", cpu: "500m" }

        - name: frontend
          image: <registry>/jlpt-kanji-frontend:latest
          ports:
            - containerPort: 80
          resources:
            requests: { memory: "128Mi", cpu: "100m" }
            limits: { memory: "256Mi", cpu: "200m" }

Vérifications de santé

Les deux conteneurs disposent de sondes de liveness et de readiness :

  • Liveness : Redémarre le conteneur s'il ne répond plus (toutes les 10 s, 3 échecs)
  • Readiness : Retire le pod des endpoints du Service jusqu'à ce qu'il soit prêt (toutes les 5 s, 2 échecs)

Contexte de sécurité

Tous les conteneurs s'exécutent en tant que non-root (UID 1000) :

securityContext:
  runAsUser: 1000
  runAsGroup: 1000
  runAsNonRoot: true

Services

Deux services ClusterIP exposent les conteneurs du pod au cluster :

# Frontend service (port 80 → 80)
name: jlpt-kanji-frontend
ports:
  - port: 80
    targetPort: 80

# Backend service (port 80 → 8080)
name: jlpt-kanji-backend
ports:
  - port: 80
    targetPort: 8080

Le service backend mappe le port externe 80 vers le port interne 8080, de sorte que Traefik route vers tous les services sur le même port.

Ingress

Routage basé sur l'hôte via Traefik :

spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - kanjiiq.com
        - api.kanjiiq.com
        - admin.kanjiiq.com
      secretName: kanjiiq-tls
  rules:
    - host: kanjiiq.com       → jlpt-kanji-frontend:80
    - host: api.kanjiiq.com   → jlpt-kanji-backend:80
    - host: admin.kanjiiq.com → jlpt-kanji-backend:80

Les certificats TLS sont automatiquement provisionnés par cert-manager lors de la création de l'Ingress.