GitOps y despliegue blue-green / sin tiempo de inactividad
Síntoma
Objetivo: desplegar cambios de esquema y de aplicación sin tiempo de inactividad; acercarse a cero tiempo de inactividad con migraciones expand-contract, entornos blue-green, feature flags y rollback automático.
1. GitOps: haga de Git la única fuente de verdad
Defina en Git la infraestructura, las migraciones de esquema y la versión de la aplicación; el despliegue se desencadena con un merge en el repositorio (GitOps). Un reconciliador (Argo CD/Flux o CI/CD) aplica el estado deseado al entorno real. Así cada cambio es auditable, repetible y puede revertirse a un commit anterior cuando sea necesario.
PostgreSQL
# repo/
# migrations/ (Vxxx__*.sql)
# k8s/ (Deployment, Service)
# flags/ (feature flag config)2. Cambie el esquema de forma compatible con versiones anteriores (expand-contract)
Para lograr cero tiempo de inactividad, no cambie el esquema en un único paso que rompa la compatibilidad; divídalo en dos fases. EXPAND: agregue la nueva estructura (nueva columna/tabla) de modo que el código antiguo y el nuevo puedan ejecutarse a la vez (columna nullable, con valor predeterminado, escrituras dobles). DESPUÉS de que la aplicación haya pasado a la nueva estructura, CONTRACT: elimine la columna/tabla antigua que ya no se usa en una migración aparte. Así las versiones antigua y nueva de la aplicación funcionan en paralelo sin problemas durante el despliegue.
PostgreSQL
-- EXPAND (V5): backward-compatible addition
ALTER TABLE customer ADD COLUMN email text;
-- for a while the code writes/reads both columns
-- CONTRACT (V9): drop the old column
ALTER TABLE customer DROP COLUMN mail_old;3. Ponga el comportamiento de riesgo detrás de un feature flag
Ejecute la nueva ruta de código (como leer la nueva columna) de forma condicional detrás de un feature flag; active el flag cuando el esquema esté listo y desactívelo sin tocar el despliegue si algo sale mal. Un flag separa el despliegue del código (deploy) de la activación de la funcionalidad (release). La fase expand se despliega, pero el cambio de comportamiento se habilita de forma controlada y puede revertirse rápidamente.
PostgreSQL
-- application layer (pseudocode)
-- if flag('new_email_field'):
-- SELECT email FROM customer ...
-- else:
-- SELECT mail_old FROM customer ...4. Configure el entorno blue-green
Mantenga dos entornos idénticos: 'blue' (en producción) y 'green' (nueva versión). Despliegue la nueva versión de la aplicación en green y valídela antes de que reciba tráfico real; cuando esté lista, cambie el router/el tráfico a green. Punto clave: la base de datos suele ser COMPARTIDA, por lo que el esquema debe ser compatible con ambas versiones (expand-contract lo garantiza). Aunque el destino de conexión cambie en el cutover, la compatibilidad del esquema evita el tiempo de inactividad.
PostgreSQL
# traffic is switched to green (new version)
# shared DB: schema must be compatible with both blue and green5. Valide el despliegue con monitoreo (canary/observación)
Antes de cambiar todo el tráfico, monitoree métricas como la tasa de errores, la latencia, los recuentos de errores/bloqueos de la base de datos y el retraso de replicación; opcionalmente envíe un pequeño porcentaje del tráfico (canary) a green y observe. Si los indicadores de salud son buenos, aumente el tráfico gradualmente; si son malos, no continúe. El monitoreo es la entrada para la decisión de rollback automático.
PostgreSQL
-- live health queries
SELECT count(*) FROM pg_stat_activity WHERE wait_event_type='Lock';
SELECT * FROM pg_stat_replication;6. Prepare el rollback automático
Si las métricas superan el umbral, el despliegue debe revertirse automáticamente: en blue-green, devuelva rápidamente el tráfico a blue (la versión antigua). El rollback de la aplicación es instantáneo porque blue sigue en ejecución. En el lado del esquema, el rollback normalmente NO ES NECESARIO: gracias a expand-contract, el nuevo esquema también es compatible con el código antiguo, así que basta con revertir la aplicación. Por eso los cambios de esquema deben mantenerse independientes del despliegue de la aplicación y ser siempre compatibles con versiones anteriores.
PostgreSQL
# traffic instantly returns to blue (application rollback)
# schema is not rolled back: expand-contract is compatible with old code
# if truly needed: write a new corrective migration