DevOps

Mejores Prácticas de Kubernetes para Despliegues en Producción

Resumen

Kubernetes en producción requiere límites de recursos, contextos de seguridad, health checks apropiados y observabilidad. Usa namespaces para aislamiento, implementa políticas de red y siempre ten estrategias de rollback. Empieza simple y añade complejidad solo cuando sea necesario.

10 de enero, 20265 min de lectura
KubernetesDevOpsCloudDockerInfraestructuraProducción

Ejecutar Kubernetes en producción es diferente del desarrollo. Después de administrar clústeres sirviendo millones de solicitudes, he aprendido qué prácticas realmente importan y cuáles son sobre-ingeniería. Esta guía se enfoca en lo que mantiene los sistemas confiables.

Gestión de Recursos

Configurando Requests y Limits

La configuración de recursos es la configuración de producción más impactante. Si lo haces mal, tendrás pods OOMKilled o problemas de vecino ruidoso.

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: api
        image: myapp/api:v1.2.3
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"      # 0.1 cores de CPU
          limits:
            memory: "512Mi"  # Límite duro - exceder causa OOMKill
            cpu: "500m"      # Límite suave - throttled si se excede

Estrategia de Dimensionamiento

Empieza con requests al 50-70% de tu uso promedio observado. Configura limits de memoria a 2x requests (los picos de memoria son comunes). Configura limits de CPU a 3-5x requests u omítelos (el CPU es compresible y se throttlea graciosamente).

Horizontal Pod Autoscaling

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300  # Esperar 5 min antes de escalar hacia abajo
    scaleUp:
      stabilizationWindowSeconds: 0  # Escalar hacia arriba inmediatamente

Health Checks

Liveness vs Readiness vs Startup Probes

spec:
  containers:
  - name: api
    livenessProbe:
      # "¿Está vivo este contenedor?" - reinicia si falla
      httpGet:
        path: /health/live
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
      failureThreshold: 3
 
    readinessProbe:
      # "¿Puede este contenedor manejar tráfico?" - remueve del servicio si falla
      httpGet:
        path: /health/ready
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
      failureThreshold: 3
 
    startupProbe:
      # "¿Ha iniciado este contenedor?" - para contenedores de inicio lento
      httpGet:
        path: /health/live
        port: 8080
      failureThreshold: 30  # 30 * 5s = 150s tiempo máximo de inicio

Error Común

No hagas que las probes de liveness verifiquen dependencias externas. Una caída de base de datos no debería reiniciar tus pods—eso empeora las cosas. Liveness verifica si TU contenedor está funcionando.

Endurecimiento de Seguridad

Contexto de Seguridad del Pod

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
 
  containers:
  - name: app
    image: myapp:v1.0.0
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
          - ALL

Políticas de Red

# Denegar todo el ingress por defecto
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
 
---
# Permitir tráfico específico
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-server-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 8080

Estrategias de Despliegue

Rolling Updates con Cero Downtime

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # Puede crear 2 pods extra durante actualización
      maxUnavailable: 1  # Máximo 1 pod no disponible durante actualización
  template:
    spec:
      containers:
      - name: api
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 10"]  # Apagado gracioso

Despliegues Canary

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api-server
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: {duration: 5m}
      - setWeight: 30
      - pause: {duration: 5m}
      - setWeight: 50
      - pause: {duration: 10m}
      - setWeight: 100

Observabilidad

Logging Estructurado

import structlog
 
structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.JSONRenderer()
    ]
)
 
logger = structlog.get_logger()
 
# Log con contexto
logger.info(
    "request_processed",
    request_id="abc-123",
    user_id="user-456",
    duration_ms=45,
    status_code=200
)

Checklist de Producción

CategoríaItemPrioridad
RecursosRequests de CPU/Memoria configuradosCrítico
Limits de memoria configuradosCrítico
HPA configuradoAlto
HealthProbe de liveness configuradoCrítico
Probe de readiness configuradoCrítico
SeguridadUsuario non-rootCrítico
Sistema de archivos read-onlyAlto
Políticas de redAlto
Secrets externalizadosCrítico
ObservabilidadLogging estructuradoCrítico
Métricas exportadasAlto

Conclusión

Kubernetes en producción requiere disciplina en algunas áreas clave:

  1. Gestión de recursos - Configura requests y limits basados en datos
  2. Health checks - Distingue entre liveness y readiness
  3. Seguridad - Principio de mínimo privilegio en todas partes
  4. Despliegues - Siempre ten una estrategia de rollback
  5. Observabilidad - Logs, métricas y traces son no negociables

Empieza simple, mide todo y añade complejidad solo cuando tengas evidencia de que es necesaria.


Referencias

Kubernetes Authors. (2024). Production best practices. https://kubernetes.io/docs/setup/production-environment/

Google Cloud. (2024). Best practices for running cost-optimized Kubernetes applications on GKE. https://cloud.google.com/architecture/best-practices-for-running-cost-effective-kubernetes-applications-on-gke

Burns, B., Beda, J., Hightower, K., & Evenson, L. (2022). Kubernetes: Up and running (3rd ed.). O'Reilly Media.


¿Ejecutando Kubernetes en producción? Contáctame para discutir estrategias de infraestructura.

Frequently Asked Questions

OR

Osvaldo Restrepo

Senior Full Stack AI & Software Engineer. Building production AI systems that solve real problems.