Saltar a contenido

Manifiestos de Kubernetes

Todos los recursos de Kubernetes están definidos en el directorio k8s/ y se aplican en orden numérico.

Descripción general de manifiestos

Archivo Recurso Propósito
00-namespace.yaml Namespace Crea el namespace jlpt-kanji
01-secrets.yaml Secret URL de base de datos, secreto JWT, clave OpenAI
02-postgres-pvc.yaml PersistentVolumeClaim Almacenamiento de 10Gi para PostgreSQL
03-postgres-deployment.yaml Deployment + Service Base de datos PostgreSQL 15
04-libretranslate-deployment.yaml Deployment + Service Traducción autoalojada (opcional)
05-deployment.yaml Deployment Aplicación principal (contenedores frontend + backend)
06-service.yaml Service (x2) Servicios de Frontend (:80) y Backend (:8080)
07-ingress.yaml Ingress Enrutamiento Traefik para jlpt.iqquest.app
08-security-middlewares.yaml Middleware (CRD) Limitación de velocidad y cabeceras de seguridad
ingress-kanjiiq.yaml Ingress Enrutamiento para dominios kanjiiq.com
ingress-docs.yaml Ingress Enrutamiento para docs.kanjiiq.app
docs-deployment.yaml Deployment Sitio de documentación
docs-service.yaml Service Servicio de documentación

Despliegue inicial

Aplica los manifiestos en orden:

# 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

Todos los recursos viven en un único namespace:

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

Esto proporciona:

  • Aislamiento de recursos de otras cargas de trabajo
  • RBAC con alcance (si es necesario)
  • Limpieza fácil (kubectl delete namespace jlpt-kanji)
  • Aplicación de cuotas de recursos (si es necesario)

Gestión de secretos

Los valores sensibles se almacenan en Kubernetes Secrets (no se suben a 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-..."

El 01-secrets.yaml en el repositorio es una plantilla — los valores reales se aplican manualmente en el servidor.

Diseño del pod

El pod principal de la aplicación ejecuta dos contenedores en paralelo:

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" }

Health checks

Ambos contenedores tienen sondas de liveness y readiness:

  • Liveness: Reinicia el contenedor si deja de responder (cada 10s, 3 fallos)
  • Readiness: Elimina el pod de los endpoints del Service hasta que esté listo (cada 5s, 2 fallos)

Contexto de seguridad

Todos los contenedores se ejecutan como non-root (UID 1000):

securityContext:
  runAsUser: 1000
  runAsGroup: 1000
  runAsNonRoot: true

Servicios

Dos servicios ClusterIP exponen los contenedores del pod al clúster:

# 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

El servicio del backend mapea el puerto externo 80 al puerto interno 8080, para que Traefik enrute a todos los servicios en el mismo puerto.

Ingress

Enrutamiento basado en host mediante 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

Los certificados TLS son provisionados automáticamente por cert-manager cuando se crea el Ingress.