Capítulo 5: ConfigMaps y Secrets

Por: Artiko
kubernetesconfigmapsecretskubectlfastapi

Configuración en Kubernetes

Nunca hardcodees configuración en tu código o imagen Docker. Kubernetes ofrece:

ConfigMap

Crear k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: fastapi-config
  namespace: dev
data:
  APP_ENV: "development"
  LOG_LEVEL: "DEBUG"
  DATABASE_HOST: "postgres-service.dev.svc.cluster.local"
  DATABASE_PORT: "5432"
  CORS_ORIGINS: "http://localhost:3000,http://localhost:5173"
kubectl apply -f k8s/configmap.yaml

# Ver contenido
kubectl get configmap fastapi-config -n dev -o yaml

# Crear desde CLI (rápido para probar)
kubectl create configmap mi-config --from-literal=KEY=value -n dev

Secret

Crear k8s/secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: fastapi-secrets
  namespace: dev
type: Opaque
stringData:
  DATABASE_PASSWORD: "mi-password-seguro"
  JWT_SECRET: "mi-jwt-secret-key"
  API_KEY: "sk-abc123"

stringData acepta texto plano (Kubernetes lo codifica en base64 automáticamente). Alternativa: usar data con valores en base64.

kubectl apply -f k8s/secret.yaml

# Ver secrets (los valores están ocultos)
kubectl get secret fastapi-secrets -n dev -o yaml

# Decodificar un valor
kubectl get secret fastapi-secrets -n dev -o jsonpath='{.data.DATABASE_PASSWORD}' | base64 -d

Inyectar en el Deployment

Actualizar k8s/deployment.yaml para usar las variables:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: fastapi-app
  namespace: dev
  labels:
    app: fastapi-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: fastapi-app
  template:
    metadata:
      labels:
        app: fastapi-app
    spec:
      containers:
        - name: fastapi
          image: fastapi-k8s:v1
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8000
          envFrom:
            - configMapRef:
                name: fastapi-config
            - secretRef:
                name: fastapi-secrets
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"

envFrom inyecta todas las keys como variables de entorno.

Leer variables en FastAPI

from fastapi import FastAPI
import os

app = FastAPI()

@app.get("/config")
def show_config():
    return {
        "env": os.getenv("APP_ENV", "unknown"),
        "log_level": os.getenv("LOG_LEVEL", "INFO"),
        "db_host": os.getenv("DATABASE_HOST", "localhost"),
    }

Variables individuales

Si solo necesitás algunas keys:

env:
  - name: DB_PASS
    valueFrom:
      secretKeyRef:
        name: fastapi-secrets
        key: DATABASE_PASSWORD
  - name: APP_ENV
    valueFrom:
      configMapKeyRef:
        name: fastapi-config
        key: APP_ENV

Actualizar configuración

# Editar configmap
kubectl edit configmap fastapi-config -n dev

# Los pods existentes NO ven los cambios automáticamente
# Reiniciar pods para que tomen la nueva config
kubectl rollout restart deployment fastapi-app -n dev

Verificar variables en un Pod

# Ver todas las env vars de un pod
kubectl exec <nombre-pod> -n dev -- env | sort

# Verificar una específica
kubectl exec <nombre-pod> -n dev -- printenv APP_ENV

En el siguiente capítulo, el más importante para desarrollo: logs y debugging.