El problema empezó así: teníamos cinco microservicios, cuatro ingenieros, y un servidor de staging que vivía en perpetuo caos. Un viernes por la tarde decidí que ya era suficiente y me puse a evaluar orquestadores de contenedores en serio. Spoiler: ese fin de semana no dormí bien.
Estuve tres semanas probando Kubernetes, Docker Swarm y Nomad en escenarios lo más parecidos posible a lo que usamos en producción — una API REST en Node.js, un par de workers de procesamiento en Python, una base de datos Postgres con réplica, y un reverse proxy con Nginx. No es el stack más glamoroso del mundo, pero es representativo de lo que maneja la mayoría de equipos pequeños o medianos.
Lo que encontré no fue lo que esperaba.
Por qué los tres siguen siendo opciones válidas (aunque uno se está quedando atrás)
La narrativa popular en 2026 es “Kubernetes ganó, los demás ya no importan”. Y entiendo de dónde viene — K8s tiene el ecosistema, el soporte empresarial, y prácticamente todos los proveedores cloud tienen su propia versión managed (EKS, GKE, AKS). Pero esa narrativa ignora que Kubernetes tiene un costo operacional real que muchos equipos pequeños no pueden asumir.
Docker Swarm sigue siendo una opción, aunque su desarrollo se ha frenado bastante. Moby Project lo mantiene vivo, pero no han salido features significativas desde hace tiempo. Si ya usas Docker Compose en desarrollo, Swarm te parecerá familiar — demasiado familiar, en el mal sentido.
Nomad es donde me llevé la mayor sorpresa. HashiCorp fue adquirida por IBM en 2024 y hubo un momento de incertidumbre, pero el producto en sí ha seguido madurando. La versión 1.7.x que usé tiene mejoras de scheduling que se notan en la práctica.
Kubernetes: Poderoso, Pero el Precio es Real
Pasé unos cinco días configurando un cluster de Kubernetes “desde cero” usando kubeadm, y otro par de días probando k3s — que es básicamente K8s pero diseñado para ser más liviano. La diferencia en fricción inicial es enorme.
Con kubeadm en tres nodos (un master, dos workers en EC2 t3.medium), el tiempo hasta tener el primer pod corriendo fue de aproximadamente 4 horas, incluyendo configurar networking con Flannel, el dashboard, y algunos namespaces básicos. Eso asumiendo que ya sabes lo que estás haciendo. Si no sabes, multiplica por tres — y eso sin contar que vas a necesitar buscar por qué el CNI no levanta en tu versión específica del kernel.
K3s fue otra historia. Una hora, más o menos, y ya tenía algo funcional.
Aquí hay un ejemplo de lo que termina siendo un Deployment sencillo en K8s. Nada especial, solo para ilustrar la verbosidad:
# deployment-api.yaml — versión mínima para una API sin estado
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api
image: myregistry/api-service:1.4.2
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "250m"
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: production
spec:
selector:
app: api-service
ports:
- port: 80
targetPort: 3000
Esto es lo básico. Ya son 40 líneas de YAML para algo que no hace nada especial. Necesitas el Deployment, el Service, probablemente un Ingress separado, quizás un ConfigMap para variables de entorno, y si eres cuidadoso, un HorizontalPodAutoscaler. Fácilmente son 150+ líneas para una sola aplicación “sencilla”. La primera vez que lo vi todo junto pensé que alguien me estaba gastando una broma.
Lo que sí me impresionó: el rollout de actualizaciones es elegante. Cambias la imagen, aplicas el deployment, y Kubernetes hace el rolling update automáticamente. Si el nuevo pod no pasa el readinessProbe, se detiene el rollout. Eso me salvó de un problema serio cuando empujé un bug un martes por la noche — el 30% del tráfico ya estaba en la nueva versión cuando me di cuenta, pero el resto nunca llegó a ver el código roto.
El ecosistema es otro punto a favor. Helm para packages, Argo CD si quieres GitOps de verdad, Prometheus + Grafana para métricas, Cert-manager para TLS automático con Let’s Encrypt. Todo existe, todo está documentado (aunque la documentación a veces asume que ya sabes mucho), y hay comunidad para casi cualquier problema.
El verdadero costo no es la complejidad técnica — es el overhead cognitivo que no desaparece nunca. Para mantener un cluster de Kubernetes en buen estado necesitas entender etcd, los controladores, el scheduler, RBAC, network policies… La lista no termina. En un equipo de 4 personas donde nadie es DevOps de tiempo completo, eso pesa. Y pesa cada sprint, no solo al principio. Cada vez que algo raro pasa en producción, la pregunta “¿es el app o es el cluster?” te roba 20 minutos antes de poder empezar a investigar de verdad.
Docker Swarm: La Opción Honesta para Equipos Pequeños
Voy a ser directo: Docker Swarm es la opción que nadie quiere recomendar porque suena a “no sabes usar Kubernetes”, pero para un equipo de menos de 5 personas con un stack moderado, funciona bien.
La configuración inicial toma 20 minutos. Sin exagerar.
# En el nodo manager
docker swarm init --advertise-addr <IP_MANAGER>
# Obtienes un token. En los workers:
docker swarm join --token <TOKEN> <IP_MANAGER>:2377
# Desplegar un stack completo desde un Compose file:
docker stack deploy -c docker-compose.prod.yml myapp
Eso es básicamente todo. Si ya tienes un docker-compose.yml que funciona en desarrollo, convertirlo en un stack de Swarm es cuestión de añadir algunas directivas deploy: para definir réplicas y políticas de restart. No necesitas aprender un nuevo sistema de abstracción desde cero.
En la práctica, Swarm maneja bien hasta ~50 contenedores en 5-6 nodos sin que la gestión se vuelva dolorosa. El overlay networking funciona sin configuración adicional. Los secrets se integran de forma nativa con docker secret. Y si un nodo muere, Swarm redistribuye los containers automáticamente — sin que nadie tenga que hacer nada.
Pero hay límites claros. No hay autoscaling horizontal nativo basado en métricas. El rollout de updates es básico comparado con K8s. El soporte para stateful workloads es limitado. Y el mayor problema en 2026 es que la comunidad se está yendo — cuando busqué ayuda para un problema específico con persistent volumes, los foros estaban en silencio o te mandaban directo a K8s sin más explicación.
El desarrollo está estancado, y no de forma discreta. No está muerto, pero tampoco está vivo de forma que inspire confianza para una apuesta a largo plazo. Es como esa librería de npm que tiene 4 años sin commits pero todavía funciona — en algún momento te va a quemar.
Si tu criterio principal es “quiero algo que funcione esta semana sin contratar a alguien que sepa solo de infra”, Swarm tiene su lugar. Pero si en 6 meses necesitas escalar o añadir complejidad, probablemente vas a estar migrando.
Nomad: Lo Que No Esperaba
Honestamente, entré al test de Nomad con expectativas bajas. Lo había visto mencionado en algunos threads de Hacker News como “la opción para los que odian Kubernetes pero necesitan más que Swarm”, y eso no suena muy convincente.
Cambié de opinión a los dos días.
La arquitectura de Nomad es distinta. No es solo un orquestador de contenedores — puede correr binarios directos, JVM apps, Python scripts, y sí, también contenedores Docker o Podman. Para nosotros eso era irrelevante porque todo está containerizado, pero conceptualmente es más flexible.
El archivo de job en Nomad (HCL, igual que Terraform) es más verboso que un Compose file pero mucho menos que Kubernetes YAML en la práctica:
# api-service.nomad
job "api-service" {
datacenters = ["dc1"]
type = "service"
group "api" {
count = 3
network {
port "http" {
to = 3000
}
}
service {
name = "api-service"
port = "http"
check {
type = "http"
path = "/health"
interval = "10s"
timeout = "2s"
}
}
task "api" {
driver = "docker"
config {
image = "myregistry/api-service:1.4.2"
ports = ["http"]
}
resources {
cpu = 250 # MHz
memory = 256 # MB
}
}
}
}
La integración con Consul para service discovery es natural — si ya usas HashiCorp stack, todo encaja. Vault para secrets también. Yo no tenía ninguno de los dos antes, así que tuve que configurarlos desde cero, y eso añadió un par de horas.
El momento que me sorprendió fue el canary deployment. Nomad tiene soporte nativo para canary releases y el syntax es directo:
update {
canary = 1 # un solo canary antes del rollout completo
auto_promote = false # no promover automáticamente, quiero confirmarlo
auto_revert = true # si el canary falla, revertir
}
En K8s eso requiere Argo Rollouts o una configuración manual con múltiples Deployments. En Nomad está en el job spec. Tres líneas. Me gustó eso más de lo que esperaba.
El gotcha que me encontré — y lo documento aquí porque perdí tres horas por esto — la observabilidad out-of-the-box es limitada. La UI es decente, puedes ver el estado de los jobs y los logs de los tasks, pero para métricas serias necesitas integrar Prometheus con el endpoint de Nomad. Hasta ahí bien. El problema era un error de configuración en el bloque telemetry que nadie había documentado claramente, y que hacía que las métricas de jobs específicos simplemente no aparecieran. Ningún error visible. Solo ausencia de datos — el tipo de bug que te hace cuestionar si estás configurando mal o si el software está fallando callado. Al final era un campo mal puesto en el stanza de telemetry del config de Nomad. Lo encontré por accidente comparando dos configs de Stack Overflow que tampoco explicaban por qué funcionaban.
Además — y esto es relevante en 2026 — el futuro de Nomad bajo IBM/HashiCorp no está 100% claro para mí. El enterprise tier se ha vuelto más caro. La versión open source sigue siendo capaz, pero hay features que antes eran gratis y ahora están en el tier de pago. No es un problema hoy, pero es algo que hay que tener en mente.
Cómo Lo Evalué en Números Reales
Para comparar operativamente, usé el mismo stack en los tres orquestadores durante aproximadamente una semana cada uno, y medí:
- Tiempo hasta primer deploy funcional: Swarm 25 min, Nomad 1.5h (con Consul), K8s con k3s 1h, K8s con kubeadm 4h
- Tiempo de recovery después de kill de un nodo: Los tres se comportaron bien, Kubernetes fue el más predecible (~90s), Nomad fue comparable (~100s), Swarm fue el más rápido en este test (~70s) aunque con menos garantías
- Overhead de RAM en los nodos por el orquestador mismo: Swarm ~50MB, Nomad ~80MB, K8s (k3s) ~400MB, K8s (kubeadm) ~1.2GB
- Curva de aprendizaje para alguien nuevo en el equipo: Swarm menos de un día para estar productivo, Nomad 2-3 días, Kubernetes semanas
El overhead de K8s en términos de recursos es real. En instancias pequeñas (t3.small, t3.medium) el cluster de Kubernetes consume una porción no trivial de los recursos disponibles solo para mantenerse funcionando.
Mi Recomendación Real
No me voy a esconder detrás de un “depende de tu caso”:
Equipo grande o en crecimiento (8+ personas): Kubernetes, pero con k3s o una solución managed (EKS/GKE). El costo de aprendizaje se amortiza, el ecosistema es demasiado bueno para ignorarlo, y eventualmente vas a necesitar lo que ofrece. Solo no instales kubeadm en bare metal en 2026 a menos que tengas un buen motivo.
Equipo de 2-5 personas con stack relativamente simple: empieza con Docker Swarm. Sí, el desarrollo está estancado. Pero funciona, es predecible, y no te va a robar tiempo que necesitas para construir tu producto. Puedes migrar después cuando realmente lo necesites — y “cuando realmente lo necesites” es clave, porque muchos equipos migran antes de llegar a ese punto y pagan el costo dos veces.
Si ya estás en el ecosistema HashiCorp — Terraform, Vault, lo que sea — dale una oportunidad seria a Nomad. Es el punto medio más honesto de los tres. No tan simple como Swarm, no tan complejo como Kubernetes, y el HCL es cómodo si ya estás en ese mundo.
Lo que yo no haría: instalar Kubernetes completo en un equipo de tres personas que está tratando de hacer su primer deploy. He visto esto — y lo he vivido — y el resultado es dos semanas perdidas configurando infra en lugar de construir el producto. El orquestador correcto es el que no ocupa la mayor parte de tu energía operacional.
Si tienes preguntas sobre alguno de los tres en tu contexto particular, deja un comentario. Cada stack tiene sus rarezas y con gusto cuento lo que encontré en más detalle.