Kubernetes se convirtió en el estándar de facto para orquestación de contenedores. En conferencias, en ofertas de trabajo, en arquitecturas de referencia. Si no lo estás usando, parece que estás haciendo algo mal. Pero la realidad de operarlo en producción es bastante distinta a lo que muestran los tutoriales de minikube.
He trabajado con clusters de K8s en entornos enterprise donde la complejidad operativa superó con creces el valor que aportaba la plataforma. También he visto implementaciones donde Kubernetes fue exactamente la herramienta correcta. La diferencia entre ambos escenarios no es técnica. Es de contexto.
Cuándo NO usar Kubernetes
Esta es la pregunta que nadie hace en la fase de diseño, y la que todo el mundo se hace seis meses después cuando el cluster necesita un equipo dedicado solo para mantenerse vivo.
No uses Kubernetes si:
- Tu equipo es de menos de 5 personas. K8s requiere conocimiento especializado en networking, storage, RBAC, upgrades y debugging. Si tu equipo ya lucha por entregar features, agregarle la carga operativa de un cluster es un error.
- Tu aplicación es un monolito simple. Un monolito bien desplegado en un par de VMs con un load balancer es más fácil de operar, más barato y más predecible que meterlo en K8s solo porque es lo que se usa ahora.
- El overhead operativo supera el valor. Si pasas más tiempo depurando el cluster que desarrollando producto, la herramienta dejó de ser una herramienta y se convirtió en el proyecto.
Alternativas como ECS, Cloud Run, Nomad o incluso docker-compose en máquinas dedicadas pueden resolver el problema con una fracción de la complejidad. La pregunta correcta no es "cómo uso Kubernetes" sino "qué problema estoy resolviendo y cuál es la forma más simple de resolverlo".
Decisiones que la documentación no cubre
Resource requests vs. limits
La documentación te explica la diferencia. Lo que no te dice es cómo establecer los valores correctos. He visto dos extremos igual de dañinos:
- No definir requests ni limits: los pods compiten por recursos sin control, un pod hambriento puede matar al nodo entero.
- Poner limits iguales a requests: suena conservador, pero elimina la posibilidad de bursting. En workloads con picos temporales, esto genera throttling innecesario y degrada la experiencia del usuario.
La estrategia que funciona: requests basados en el consumo real del percentil 95 (no el promedio), limits con un margen de 1.5x-2x sobre el request, y monitoreo constante para ajustar. Las métricas de VPA (Vertical Pod Autoscaler) en modo recommendation son una buena base para empezar.
Networking: service mesh, ingress y DNS interno
Instalar Istio porque "es la forma correcta de hacer service mesh" sin tener un problema que lo justifique es una receta para el desastre. Un service mesh agrega una capa de proxy a cada pod, consume recursos, aumenta la latencia y complejiza el debugging.
Antes de Istio, pregúntate: ¿Necesito mTLS entre servicios? ¿Necesito traffic splitting avanzado? ¿Tengo más de 20 servicios que se comunican entre sí? Si la respuesta es no a las tres, un ingress controller estándar (nginx o Traefik) con network policies de Kubernetes es suficiente.
Un problema que aparece tarde y duele mucho: DNS interno. CoreDNS funciona bien hasta que no lo hace. Cuando tienes cientos de pods haciendo resoluciones constantes, el throughput de CoreDNS puede ser un cuello de botella invisible. Configura ndots correctamente en tus pods y usa FQDNs cuando puedas. Ese cambio de una línea en el dnsConfig puede reducir las queries DNS en un 80%.
Storage: el dolor de los workloads stateful
Kubernetes fue diseñado para workloads stateless. Eso no significa que no pueda manejar estado, pero sí que cada vez que metes un StatefulSet con PersistentVolumes estás nadando contra la corriente.
Bases de datos en K8s son posibles. ¿Son recomendables? Depende. Si tienes un equipo con experiencia en operadores como CloudNativePG o Vitess y un storage backend sólido (no el storage default del cloud provider), adelante. Si no, usa un servicio gestionado. RDS, Cloud SQL o cualquier DBaaS va a ser más estable que tu Postgres en un StatefulSet con un equipo que no sabe qué hacer cuando un PV se queda en estado Released.
Observabilidad en un mundo efímero
Los pods mueren y renacen constantemente. Los logs de un pod que fue evicted hace 5 minutos ya no existen si no los estás mandando a algún lado. Este es un problema básico que sorprende a muchos equipos en su primer incidente serio.
Mínimo viable: Fluentd o Fluent Bit como DaemonSet enviando logs a un agregador (Loki, Elasticsearch). Prometheus con retention adecuada para métricas. Y traces distribuidos si tienes más de 3 servicios. Sin esto, estás operando a ciegas.
Debugging en producción
kubectl exec es la primera herramienta a la que recurres, y la última en la que deberías confiar como solución. Sirve para diagnóstico puntual: verificar variables de entorno, probar conectividad de red, inspeccionar el filesystem. No sirve como estrategia de debugging.
Lo que funciona mejor: ephemeral containers (desde K8s 1.25 en GA) te permiten adjuntar un contenedor de debug a un pod en ejecución sin modificar su spec. Combínalos con herramientas como crictl para inspeccionar el runtime y kubectl debug node para problemas a nivel de nodo.
Pero el debugging más efectivo es el que no necesitas hacer. Si tu observabilidad es sólida, la mayoría de los problemas se diagnostican desde métricas y logs sin tocar el cluster.
K8s en enterprise: RBAC y multi-tenancy
En entornos enterprise, el cluster se comparte entre equipos. Y aquí es donde las decisiones de diseño se vuelven políticas además de técnicas.
Namespaces como boundaries: funcionan como separación lógica, no como aislamiento real. Un namespace no evita que un pod consuma todos los recursos del nodo. Para eso necesitas ResourceQuotas y LimitRanges por namespace, y necesitas enforcement real, no solo definiciones YAML que nadie revisa.
Multi-tenancy real vs. ficticia: si necesitas aislamiento real entre tenants (por compliance, seguridad o simplemente confianza), los namespaces no son suficientes. Necesitas clusters separados o soluciones como vCluster que crean clusters virtuales dentro de un cluster físico. La multi-tenancy soft que ofrecen los namespaces funciona para equipos dentro de la misma organización que confían entre sí. Para todo lo demás, es una ilusión.
RBAC parece sencillo hasta que tienes 15 equipos con necesidades distintas. Mi consejo: define roles a nivel de namespace (no cluster roles), usa grupos de AD/LDAP en lugar de usuarios individuales, y audita los permisos trimestralmente. Los permisos se acumulan. Nadie pide que le quiten acceso.
Kubernetes es una herramienta. No una arquitectura. No adoptes K8s porque es lo que todos usan. Adóptalo cuando el problema que resuelve sea más grande que la complejidad que introduce. Y cuando lo hagas, invierte en tu equipo antes de invertir en el cluster.