Estrategias de Reversión
No todos los despliegues erróneos se pueden revertir. Los equipos de entrega eligen entre revertir la imagen anterior, corregir hacia adelante con un parche o desactivar una feature flag, basándose en la compatibilidad de las migraciones y el tiempo para mitigar.
Receta
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
## Decisión de reversión (2 minutos)
1. ¿Impacto en el cliente activo? → mitigar primero
2. ¿Despliegue < 2h y existe sha-prev de imagen? → candidata a reversión
3. ¿Migración destructiva o de contrato? → solo corrección hacia adelante
4. ¿Error aislado detrás de una flag? → desactivar flag, luego planificar corrección
5. Registrar decisión + comandos en el hilo de #incidenteCuándo usar esto:
- Definir el "go/no-go" de la lista de verificación de lanzamiento.
- Capacitar al personal de guardia sobre las opciones de mitigación.
- Diseñar migraciones para que sean reversibles.
- Revisión post-incidente de reversiones lentas.
Ejemplo de Trabajo
"""rollback_decision.py - codificar la política del equipo como helpers testeables."""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
class Mitigation(str, Enum):
FLAG_OFF = "flag_off"
ROLLBACK_IMAGE = "rollback_image"
FORWARD_FIX = "forward_fix"
@dataclass(frozen=True)
class DeployState:
minutes_since_deploy: int
migration_contract: bool # columna eliminada o destructiva
migration_expand: bool
flag_isolates_bug: bool
previous_image_available: bool
def choose_mitigation(state: DeployState) -> Mitigation:
if state.flag_isolates_bug:
return Mitigation.FLAG_OFF
if state.migration_contract:
return Mitigation.FORWARD_FIX
if state.previous_image_available and state.minutes_since_deploy < 120:
return Mitigation.ROLLBACK_IMAGE
return Mitigation.FORWARD_FIX
if __name__ == "__main__":
s = DeployState(25, migration_contract=False, migration_expand=True, flag_isolates_bug=False, previous_image_available=True)
print(choose_mitigation(s))Lo que esto demuestra:
- El árbol de decisiones es explícito y se puede enseñar al personal de guardia.
- Las migraciones de contrato bloquean automáticamente la reversión de la imagen.
- La desactivación de la flag gana cuando el radio de explosión está aislado.
- La política se puede probar unitariamente como código de aplicación.
Inmersión Profunda
Cómo Funciona
- Reversión de imagen - Rápida cuando el esquema y la configuración son compatibles hacia atrás.
- Corrección hacia adelante - Parche hacia adelante cuando la reversión rompería las suposiciones de la base de datos.
- Desactivar flag - Cambio de configuración sin reconstrucción; el runbook documenta la clave del entorno.
- Reversión de datos - PITR es raro; separado de la reversión de la aplicación.
- Retención - El registro mantiene las últimas N SHAs para
rollout undo.
Matriz de Estrategias
| Situación | Estrategia preferida |
|---|---|
| Lógica errónea, migración de expansión | Desactivar flag o reversión de imagen |
| Bloqueo de índice erróneo | Migración de corrección hacia adelante + quizás reversión |
| Columna eliminada en producción | Solo corrección hacia adelante |
| Error tipográfico en la configuración | Revertir configuración + reiniciar |
| Trabajador incompatible | Pausar trabajadores, revertir API |
Notas de Python
# Mantener la imagen anterior de Gunicorn a mano
docker pull $REGISTRY/orders-api:sha-prev
kubectl set image deploy/orders-api api=$REGISTRY/orders-api:sha-prevTrampas Comunes
- Asumir que la reversión es siempre un solo comando - Los trabajadores y las migraciones lo bloquean. Solución: Lista de verificación previa al vuelo en la plantilla de lanzamiento.
- Corrección hacia adelante bajo presión sin pruebas - Segundo incidente. Solución: Rama de parche mínima con una sola prueba de integración del caso de producción.
- Eliminar imágenes antiguas - Imposible deshacer. Solución: Política de retención mínima de 10 etiquetas de producción.
- Reversión sin prueba de humo - Interrupción parcial oculta. Solución: Prueba de escritura+lectura en un inquilino canario antes de la promoción completa.
- Ignorar la cola de Celery - Mensajes envenenados después de la reversión. Solución: Pausar la cola según el runbook.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Reversión automática ante fallo de canario | Métricas maduras | Esquema no compatible |
| Intercambio Blue-green | Pila anterior precalentada | Flota pequeña sensible al costo |
| Drenaje de tráfico | Solicitudes de larga duración | Necesidad de corrección instantánea |
| Desactivar función en LB | Enrutamiento basado en ruta | Error en middleware compartido |
Preguntas Frecuentes
¿Qué tan rápido debe completarse la reversión?
Objetivo de menos de 10 minutos desde la decisión; practicar en un "game day" trimestral.
¿Reversión vs. revertir commit?
La reversión es el artefacto anterior promovido; revertir commit es el siguiente despliegue hacia adelante, más lento.
¿Cuándo es obligatoria la corrección hacia adelante?
Migraciones destructivas, migraciones de datos ya aplicadas o imagen de reversión no disponible.
¿Las funciones serverless se revierten?
Desplazar el peso de la alias a la versión anterior; el mismo árbol de decisiones sobre el esquema.
¿Cómo probar la reversión en CI?
Desplegar en un entorno efímero, ejecutar prueba de humo, rollout undo, volver a ejecutar prueba de humo - opcionalmente nocturno.
¿Qué pasa con la reversión de la base de datos?
La reversión de la aplicación no deshace DDL; usar expandir-contrato y PITR para desastres.
¿Quién decide la reversión vs. corrección hacia adelante?
Ingeniero individual durante un incidente; capitán de lanzamiento pre-producción. Documentar en el hilo.
¿Se pueden revertir los modelos de ML?
Revertir la versión del artefacto del modelo en el registro; puede requerir validación en sombra primero.
¿Cómo alinearse con DORA?
Seguir la tasa de fallo de cambios y el MTTR; la reversión rápida mejora ambos.
¿Afecta el archivo de bloqueo uv a la reversión?
La imagen incrusta el hash del bloqueo; la reversión restaura automáticamente las dependencias anteriores.
Relacionado
- Runbooks de Reversión y Recuperación - pasos de ejecución
- Feature Flags y Entrega Progresiva - desactivación de flag
- Gestión de Lanzamientos - proceso de entrenamiento
- Entornos y Promoción de Configuración - promoción de artefactos
- Despliegues sin Tiempo de Inactividad - mecánica de despliegue
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.