Guía Completa de Kubernetes en producción
Desplegar un cluster de Kubernetes en un entorno de laboratorio es relativamente sencillo. Operarlo en producción con cargas reales, requisitos de disponibilidad y presion del negocio es un desafio completamente diferente. Un cluster productivo exige configuraciones especificas de recursos, autoescalado, health checks, políticas de red, seguridad y estrategias de actualización que no son necesarias en desarrollo. Esta guía cubre los aspectos críticos que separan un cluster de pruebas de uno listo para producción.
Diseño de un cluster production-ready
Alta disponibilidad del control plane
Un cluster productivo requiere un control plane redundante. Esto significa ejecutar multiples replicas de los componentes críticos:
- API Server: Minimo 3 instancias detras de un load balancer. Cada instancia debe estar en una zona de disponibilidad diferente.
- etcd: Cluster de 3 o 5 nodos (siempre impar para mantener quorum). Usa SSDs dedicadas para etcd, ya que es sensible a la latencia de disco.
- Scheduler y Controller Manager: Corren en modo active-standby con leader election automático.
En servicios gestionados como EKS, AKS o GKE, el control plane es administrado por el proveedor. Aun así, debes configurar correctamente los node groups distribuidos en multiples zonas.
Configuración de node groups
Separa los nodos segun tipo de carga:
# Node group para workloads generales
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: produccion-cluster
region: us-east-1
managedNodeGroups:
- name: general
instanceType: m6i.xlarge
minSize: 3
maxSize: 10
desiredCapacity: 5
availabilityZones: ["us-east-1a", "us-east-1b", "us-east-1c"]
labels:
workload-type: general
- name: compute-intensive
instanceType: c6i.2xlarge
minSize: 0
maxSize: 8
labels:
workload-type: compute
taints:
- key: dedicated
value: compute
effect: NoSchedule
Resource requests y limits
Uno de los errores mas comunes en producción es no configurar correctamente los recursos. Sin requests, el scheduler no puede tomar decisiones informadas. Sin limits, un pod puede consumir todos los recursos del nodo y afectar a los demas.
Configuración recomendada
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-pedidos
spec:
replicas: 3
template:
spec:
containers:
- name: api
image: mi-api:v2.1.0
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
La regla general es: establece requests basandote en el consumo real observado (percentil 95) y limits como el doble de los requests o segun el máximo aceptable. Usa herramientas como Vertical Pod Autoscaler en modo recomendación para obtener datos reales.
LimitRange por namespace
Aplica valores por defecto para prevenir deployments sin recursos configurados:
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container
Autoescalado: HPA, VPA y Cluster Autoscaler
Horizontal Pod Autoscaler (HPA)
HPA ajusta el número de replicas basandose en métricas observadas:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-pedidos-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-pedidos
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
El campo behavior es clave en producción: evita scale-down agresivos que pueden causar inestabilidad durante fluctuaciones de tráfico.
Vertical Pod Autoscaler (VPA)
VPA ajusta requests y limits automáticamente. En producción, usalo en modo Off (solo recomendaciones) inicialmente:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-pedidos-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-pedidos
updatePolicy:
updateMode: "Off"
Revisa las recomendaciones periódicamente y aplica los ajustes manualmente hasta tener confianza en el componente.
Cluster Autoscaler
Escala los nodos del cluster cuando hay pods pendientes por falta de capacidad. Asegurate de configurar los límites del node group y los priority expanders si tienes multiples node groups.
Health checks: liveness, readiness y startup probes
Los probes son fundamentales para que Kubernetes sepa el estado real de tus aplicaciones:
containers:
- name: api
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
- livenessProbe: Reinicia el contenedor si falla. Usalo para detectar deadlocks.
- readinessProbe: Remueve el pod del servicio si falla. Usalo durante cargas elevadas o inicialización.
- startupProbe: Protege contenedores con arranque lento. Mientras esta activo, los otros probes se desactivan.
Network policies
Por defecto, todos los pods pueden comunicarse entre si. En producción, aplica el principio de mínimo privilegio:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432
Comienza con una política deny-all y luego abre solo las comunicaciones necesarias.
RBAC: control de acceso basado en roles
Nunca uses el usuario admin del cluster para operaciones regulares. Crea roles específicos:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: deployment-manager
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-team-binding
namespace: production
subjects:
- kind: Group
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: deployment-manager
apiGroup: rbac.authorization.k8s.io
Monitoreo y observabilidad
Un cluster sin monitoreo es un cluster a ciegas. La stack mínima recomendada:
- Prometheus: Métricas del cluster, nodos, pods y aplicaciones. Usa kube-prometheus-stack que incluye alertas preconfiguradas.
- Grafana: Dashboards para visualizar métricas. Los dashboards de la comunidad para Kubernetes son un buen punto de partida.
- Alertmanager: Notificaciones cuando métricas criticas cruzan umbrales. Configura alertas para CPU, memoria, pods en CrashLoopBackOff y certificados proximos a expirar.
- Logs centralizados: Loki o ELK stack para agregar logs de todos los pods en un solo lugar.
Backup, disaster recovery y estrategias de upgrade
Backup de etcd
etcd contiene todo el estado del cluster. Automatiza snapshots periodicos:
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Almacena los snapshots en un bucket S3 con versionado habilitado.
Estrategias de upgrade del cluster
Actualiza siempre primero el control plane y luego los nodos worker. Sigue estos pasos:
- Lee las release notes de la versión destino para identificar breaking changes.
- Actualiza un cluster de staging primero y ejecuta pruebas.
- Actualiza el control plane (en EKS/GKE esto se hace desde la consola o API).
- Actualiza los nodos worker con rolling update: cordon, drain, upgrade, uncordon.
- Verifica que todos los workloads estan corriendo correctamente post-upgrade.
PodDisruptionBudgets
Protege tus aplicaciones durante mantenimiento de nodos:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pedidos-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api-pedidos
Conclusion
Llevar Kubernetes a producción requiere atención deliberada a cada capa: desde la arquitectura del cluster y la gestión de recursos, hasta el autoescalado, los health checks, la seguridad de red y las estrategias de recuperación. Ninguno de estos componentes es opcional en un entorno productivo real. La clave esta en implementar cada práctica de forma incremental, validar con monitoreo y mantener la disciplina operativa que un orquestador tan potente como Kubernetes demanda.