Saltar al contenido principal

Estrategias de despliegue

Desplegar no es "subir el código". Es sustituir algo que está funcionando y que la gente está usando ahora mismo, sin que se note.

La estrategia que elijamos determina cuánto riesgo asumimos en cada release, cuánto tardamos en volver atrás si algo va mal y cuánta infraestructura necesitamos.

Las cinco estrategias​

Recreate​

Paramos la versión antigua, arrancamos la nueva. Hay corte de servicio.

Parece primitivo, pero es la opción correcta en más casos de los que la gente admite: aplicaciones internas, procesos por lotes, o cuando dos versiones no pueden convivir contra la misma base de datos. Si podemos permitirnos dos minutos de corte a las tres de la mañana, es la estrategia más simple y la que menos cosas puede romper.

Rolling update​

Sustituimos las instancias poco a poco. En ningún momento se para el servicio.

Es la opción por defecto en Kubernetes y la que cubre la mayoría de los casos. Dos parámetros la definen:

  • maxUnavailable — cuántas instancias podemos tener caídas a la vez
  • maxSurge — cuántas de más podemos levantar durante la transición

La consecuencia importante: durante la transición conviven las dos versiones. Nuestra aplicación tiene que aguantarlo, y nuestra API tiene que ser compatible en ambos sentidos.

Blue-green​

Mantenemos dos entornos completos. Desplegamos en el inactivo, lo verificamos con calma y luego cambiamos el tráfico de golpe.

Su gran virtud es el rollback: volver atrás es cambiar el enrutado otra vez, y tarda segundos. Su gran defecto es el coste: necesitamos el doble de infraestructura, aunque sea solo durante el despliegue.

Canary​

Enviamos la versión nueva a un porcentaje pequeño de usuarios, miramos las métricas, y vamos subiendo si todo va bien.

5% → observar → 25% → observar → 50% → observar → 100%

Es la estrategia que menos riesgo asume, porque un fallo afecta al 5% de los usuarios y no al 100%. A cambio necesitamos dos cosas que no todo el mundo tiene: enrutado por porcentaje y, sobre todo, métricas fiables para decidir si promocionar o abortar.

Sin métricas automáticas, un canary es un rolling update más lento y con más pasos manuales.

A/B testing​

Técnicamente se parece al canary, pero la pregunta es distinta. El canary pregunta "¿esto funciona?"; el A/B testing pregunta "¿esto vende más?".

El reparto no es aleatorio sino por segmento de usuario, y quien decide no es el equipo de operaciones sino el de producto. La decisión se basa en significancia estadística, no en tasa de error.

Cuál elegir​

EstrategiaCorteCoste extraRollbackComplejidad
RecreateSíNingunoRedesplegarMuy baja
RollingNoBajoLentoBaja
Blue-greenNoDobleInstantáneoMedia
CanaryNoBajoRápidoAlta
A/B testingNoBajoRápidoAlta

Una guía honesta:

  • Empecemos por rolling. Cubre la mayoría de los casos y viene de serie.
  • Blue-green si necesitamos rollback inmediato y podemos pagar el doble de infraestructura un rato.
  • Canary solo si ya tenemos buena observabilidad. Sin métricas fiables, no aporta.
  • Recreate si el corte es asumible. No nos compliquemos por gusto.

Los health checks son la clave​

Ninguna estrategia funciona si el sistema no sabe cuándo una instancia está lista de verdad. Tres sondas distintas, y confundirlas es el fallo más común:

  • Liveness — ¿sigue viva? Si no, reiniciémosla.
  • Readiness — ¿puede recibir tráfico ya? Si no, saquémosla del balanceador pero no la reiniciemos.
  • Startup — ¿ha terminado de arrancar? Protege a las aplicaciones lentas de que liveness las mate durante el arranque.

El error clásico es usar el mismo endpoint para liveness y readiness. Si ese endpoint comprueba la base de datos, una caída de la base de datos hace que liveness falle y el orquestador reinicie todas nuestras instancias en bucle — convirtiendo una degradación en una caída total.

La parte difícil: la base de datos​

Aquí es donde se rompen los despliegues bonitos. Podemos revertir el código en segundos; una migración que borró una columna, no.

La regla: durante un despliegue conviven dos versiones del código contra una sola base de datos. Así que todo cambio de esquema tiene que ser compatible con la versión anterior.

SeguroPeligroso
Añadir columnas con valor por defectoBorrar columnas
Añadir tablasRenombrar columnas
Añadir índices sin bloquearCambiar tipos de datos
Añadir NOT NULL a lo existente

Renombrar una columna no es una operación, son cuatro despliegues:

  1. Añadir la columna nueva
  2. Escribir en las dos, leer de la vieja
  3. Copiar los datos y leer de la nueva
  4. Borrar la vieja, cuando ya nadie la usa

Es tedioso, y es la diferencia entre poder hacer rollback y no poder.

Rollback​

Antes de desplegar, tengamos respondidas tres preguntas:

  1. ¿Cómo vuelvo atrás? El comando exacto, escrito.
  2. ¿Cuánto tarda?
  3. ¿Qué pasa con los datos que se escribieron con la versión nueva?

En Kubernetes el rollback del código es directo:

kubectl rollout undo deployment/mi-app
kubectl rollout status deployment/mi-app

Lo automático es mejor: si las métricas se degradan por encima de un umbral durante los primeros minutos, revierte solo. Es exactamente lo que hacen herramientas como Argo Rollouts o Flagger, que analizan las métricas entre paso y paso del canary.

Feature flags​

Una alternativa que cambia el problema de sitio: desplegamos el código con la funcionalidad apagada y la encendemos después.

Despliegue ≠ Activación

Separar ambas cosas tiene dos ventajas grandes: podemos desplegar a media mañana sin miedo, y "revertir" es apagar un interruptor en lugar de volver a desplegar.

El precio es que el código acumula ramas condicionales. Un flag que lleva un año encendido ya no es un flag, es deuda técnica — pongámosle fecha de caducidad.

En Kubernetes​

La implementación concreta de canary y blue-green en Kubernetes, con enrutado de tráfico y análisis de métricas, la tenemos en el curso de Kubernetes:

Resumen​

  • Rolling cubre la mayoría de los casos y viene de serie: empieza ahí
  • Blue-green compra rollback instantáneo a cambio del doble de infraestructura
  • Canary solo aporta si ya tenemos métricas fiables
  • Recreate sigue siendo válido si el corte es asumible
  • No usemos el mismo endpoint para liveness y readiness
  • Las migraciones de base de datos tienen que ser compatibles hacia atrás
  • Ten el comando de rollback escrito antes de desplegar

Recursos adicionales​


💡 Recordemos: la estrategia de despliegue debe ajustarse a nuestra tolerancia al riesgo, no a lo que esté de moda.

En el próximo capítulo vemos qué aportan los contenedores a todo este flujo.