Despliegues sin Tiempo de Inactividad con Blue-Green: Guía de Estrategia de Entrega Continua

Introducción

El despliegue sin tiempo de inactividad representa una capacidad crítica para organizaciones que entregan actualizaciones continuas a sistemas de producción mientras mantienen la disponibilidad del servicio. El despliegue blue-green—una de las estrategias sin tiempo de inactividad más confiables—implica mantener dos entornos de producción idénticos ("blue" y "green"), enrutar tráfico a uno mientras se actualiza el otro, y luego cambiar instantáneamente el tráfico al entorno actualizado.

Los enfoques de despliegue tradicionales que requieren ventanas de mantenimiento, despliegues escalonados durante horas o actualizaciones complejas in situ introducen riesgo y limitan la frecuencia de despliegue. Las organizaciones que practican entrega continua pueden desplegar docenas o cientos de veces diariamente—haciendo que la velocidad de despliegue, confiabilidad y capacidades de rollback instantáneo sean ventajas competitivas esenciales.

Empresas incluyendo Amazon, Netflix, Facebook y Google despliegan miles de veces diariamente usando estrategias sofisticadas de despliegue que minimizan el riesgo mientras maximizan la velocidad. Los despliegues blue-green proporcionan capacidad de rollback inmediata—si surgen problemas, el tráfico cambia de vuelta al entorno anterior instantáneamente sin requerir rollbacks de código, migraciones de base de datos o procedimientos de recuperación prolongados.

Este patrón de despliegue se adapta a varias cargas de trabajo: aplicaciones web sin estado, microservicios, gateways de API, sistemas de entrega de contenido y pipelines de procesamiento por lotes. Aunque las bases de datos y sistemas con estado requieren consideraciones adicionales, la arquitectura apropiada permite que incluso aplicaciones complejas se beneficien de estrategias blue-green sin tiempo de inactividad.

Esta guía completa explora implementaciones de despliegue blue-green de nivel empresarial, cubriendo patrones arquitectónicos, aprovisionamiento de infraestructura, mecanismos de cambio de tráfico, estrategias de migración de bases de datos, monitoreo, procedimientos de rollback y enfoques de automatización esenciales para pipelines de entrega continua listos para producción.

Teoría y Conceptos Fundamentales

Fundamentos del Despliegue Blue-Green

El despliegue blue-green mantiene dos entornos equivalentes a producción:

Entorno Blue: Actualmente sirviendo tráfico de producción. Representa la versión estable y probada ejecutándose en producción.

Entorno Green: Recibe nuevo despliegue. Se somete a pruebas y validación mientras blue sirve tráfico.

Flujo de Despliegue:

  1. El entorno blue sirve tráfico de producción
  2. Desplegar nueva versión al entorno green inactivo
  3. Probar entorno green exhaustivamente (pruebas de humo, pruebas de integración, tráfico limitado)
  4. Cambiar tráfico de blue a green instantáneamente
  5. Monitorear entorno green con carga de producción completa
  6. El entorno blue queda inactivo, listo para el siguiente despliegue

Ventajas Clave:

  • Rollback Instantáneo: Cambiar de vuelta a blue si se detectan problemas
  • Reducción de Riesgo: Probar en entorno de producción antes del cambio completo
  • Cero Tiempo de Inactividad: El cambio de tráfico ocurre instantáneamente sin interrupción del servicio
  • Pruebas Simplificadas: Entorno de producción disponible para pruebas completas

Mecanismos de Cambio de Tráfico

Múltiples enfoques permiten cambio de tráfico instantáneo:

Cambio DNS: Actualizar registros DNS apuntando al nuevo entorno. Simple pero retrasos de propagación (TTL) previenen cambio instantáneo. Adecuado para actualizaciones no críticas.

Cambio de Load Balancer: Reconfigurar load balancer para enrutar tráfico al nuevo entorno. Cambio instantáneo, requiere infraestructura de load balancer.

Cambio de Reverse Proxy: Actualizar configuración de reverse proxy (Nginx, HAProxy) dirigiendo tráfico a nuevo backend. Rápido, flexible, requiere capa de proxy.

Cambio de Service Mesh: Service mesh moderno (Istio, Linkerd) habilita enrutamiento de tráfico sofisticado con capacidades de despliegue gradual.

Cambio de Proveedor Cloud: AWS ALB, Google Cloud Load Balancing, Azure Traffic Manager proporcionan soporte nativo blue-green.

Consideraciones de Bases de Datos

Las bases de datos introducen complejidad a los despliegues blue-green:

Migraciones Compatibles hacia Atrás: Los cambios de esquema deben soportar versiones antiguas y nuevas de aplicación durante el período de cambio. Agregar nuevas columnas/tablas sin eliminar estructuras antiguas inmediatamente.

Replicación de Datos: Mantener datos sincronizados entre entornos o usar base de datos compartida accesible desde ambos.

Estrategias de Migración:

  • Base de Datos Compartida: Ambos entornos acceden a la misma base de datos (más simple, requiere planificación cuidadosa de migración)
  • Base de Datos Replicada: Bases de datos separadas con replicación (complejo, habilita aislamiento completo)
  • Consistencia Eventual: Diseñar aplicaciones tolerantes a inconsistencia temporal de datos

Desafíos de Servicios con Estado

Los despliegues blue-green tradicionalmente se adaptan a aplicaciones sin estado, pero existen estrategias para servicios con estado:

Persistencia de Sesión: Usar almacenes de sesión externos (Redis, Memcached) accesibles desde ambos entornos.

Drenaje de Conexiones: Permitir que conexiones existentes se completen antes de eliminar entorno blue de rotación.

Migración de Estado: Transferir estado entre entornos durante el cambio (complejo, específico de la aplicación).

Prerequisitos

Requisitos de Infraestructura

Infraestructura Mínima:

  • Dos entornos completos equivalentes a producción
  • Load balancer o mecanismo de enrutamiento de tráfico
  • Pipeline de despliegue automatizado
  • Infraestructura de monitoreo y alertas
  • Capacidades de automatización de rollback

Consideraciones de Recursos:

  • Costo de infraestructura doble (dos entornos completos)
  • Capacidad suficiente para manejar carga de producción completa en entorno único
  • Ancho de banda de red para sincronización de entornos
  • Almacenamiento para múltiples configuraciones de entorno

Prerequisitos de Software

Automatización de Despliegue:

  • Plataforma CI/CD (Jenkins, GitLab CI, GitHub Actions, CircleCI)
  • Gestión de configuración (Ansible, Terraform, Helm)
  • Orquestación de contenedores (Kubernetes) o gestión de VM
  • Herramientas de Infrastructure as Code

Stack de Monitoreo:

  • Monitoreo de rendimiento de aplicaciones (APM)
  • Monitoreo de infraestructura (Prometheus, Datadog, New Relic)
  • Agregación de logs (ELK, Splunk, Loki)
  • Sistema de alertas (PagerDuty, Opsgenie)

Configuración Avanzada

Despliegue Blue-Green Basado en HAProxy

Configuración de HAProxy:

# /etc/haproxy/haproxy.cfg

global
    log /dev/log local0
    maxconn 100000
    daemon

defaults
    log global
    mode http
    option httplog
    timeout connect 5000
    timeout client 50000
    timeout server 50000

# Frontend recibiendo tráfico
frontend http-in
    bind *:80
    bind *:443 ssl crt /etc/haproxy/certs/site.pem

    # Redirigir HTTP a HTTPS
    http-request redirect scheme https unless { ssl_fc }

    # Usar backend blue o green basado en archivo map
    use_backend %[path,map(/etc/haproxy/backend.map,blue-backend)]

# Entorno blue (producción actual)
backend blue-backend
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200

    server blue1 192.168.1.101:8080 check
    server blue2 192.168.1.102:8080 check
    server blue3 192.168.1.103:8080 check

# Entorno green (nuevo despliegue)
backend green-backend
    balance roundrobin
    option httpchk GET /health
    http-check expect status 200

    server green1 192.168.2.101:8080 check
    server green2 192.168.2.102:8080 check
    server green3 192.168.2.103:8080 check

# Interfaz de estadísticas
listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 30s
    stats auth admin:SecurePassword123!

Archivo Map de Backend (/etc/haproxy/backend.map):

# Mapeo de backend predeterminado
/ blue-backend

Script de Despliegue:

#!/bin/bash
# deploy-bluegreen.sh - Automatización de despliegue Blue-Green

set -e

HAPROXY_MAP="/etc/haproxy/backend.map"
CURRENT_ENV=$(grep "^/" $HAPROXY_MAP | awk '{print $2}')

if [ "$CURRENT_ENV" == "blue-backend" ]; then
    TARGET_ENV="green"
    TARGET_BACKEND="green-backend"
    DEPLOY_HOSTS="192.168.2.101 192.168.2.102 192.168.2.103"
else
    TARGET_ENV="blue"
    TARGET_BACKEND="blue-backend"
    DEPLOY_HOSTS="192.168.1.101 192.168.1.102 192.168.1.103"
fi

echo "Entorno actual: $CURRENT_ENV"
echo "Desplegando a: $TARGET_ENV"

# Desplegar nueva versión al entorno objetivo
for host in $DEPLOY_HOSTS; do
    echo "Desplegando a $host..."
    ssh deploy@$host << 'EOF'
        cd /opt/application
        git pull origin main
        ./build.sh
        ./deploy.sh
        systemctl restart application
EOF
done

# Health check del entorno objetivo
echo "Realizando health checks en entorno $TARGET_ENV..."
sleep 10

for host in $DEPLOY_HOSTS; do
    if ! curl -f http://$host:8080/health; then
        echo "Health check falló para $host"
        exit 1
    fi
done

echo "Health checks pasados. Listo para cambiar tráfico."
read -p "¿Cambiar tráfico al entorno $TARGET_ENV? (yes/no): " CONFIRM

if [ "$CONFIRM" != "yes" ]; then
    echo "Despliegue cancelado."
    exit 0
fi

# Cambiar tráfico
echo "Cambiando tráfico al entorno $TARGET_ENV..."
echo "/ $TARGET_BACKEND" > $HAPROXY_MAP

# Recargar configuración de HAProxy
systemctl reload haproxy

echo "Tráfico cambiado al entorno $TARGET_ENV."
echo "Monitoreando durante 5 minutos..."

# Monitorear problemas
for i in {1..30}; do
    ERROR_RATE=$(echo "show stat" | socat stdio /var/run/haproxy/admin.sock | \
        grep "$TARGET_BACKEND" | awk -F',' '{print $14}')

    if [ "$ERROR_RATE" -gt 10 ]; then
        echo "¡Tasa de error alta detectada! Revirtiendo..."
        echo "/ $CURRENT_ENV-backend" > $HAPROXY_MAP
        systemctl reload haproxy
        echo "Rollback completado."
        exit 1
    fi

    sleep 10
done

echo "¡Despliegue exitoso!"
echo "El entorno anterior ($CURRENT_ENV) ahora está inactivo y listo para el siguiente despliegue."

Despliegue Blue-Green Basado en Nginx

Configuración de Nginx:

# /etc/nginx/nginx.conf

http {
    # Definiciones de upstream
    upstream blue_backend {
        least_conn;
        server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
        server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
        server 192.168.1.103:8080 max_fails=3 fail_timeout=30s;
    }

    upstream green_backend {
        least_conn;
        server 192.168.2.101:8080 max_fails=3 fail_timeout=30s;
        server 192.168.2.102:8080 max_fails=3 fail_timeout=30s;
        server 192.168.2.103:8080 max_fails=3 fail_timeout=30s;
    }

    # Map para determinar backend activo
    map $http_host $backend {
        default blue_backend;
        include /etc/nginx/backend.map;
    }

    server {
        listen 80;
        listen 443 ssl http2;
        server_name example.com;

        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        location / {
            proxy_pass http://$backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            # Health check
            proxy_next_upstream error timeout http_500 http_502 http_503;
            proxy_connect_timeout 5s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
        }

        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }
    }
}

Map de Backend (/etc/nginx/backend.map):

# Backend activo (blue o green)
"" blue_backend;

Automatización de Despliegue:

#!/bin/bash
# nginx-bluegreen-deploy.sh

set -e

NGINX_MAP="/etc/nginx/backend.map"
CURRENT_BACKEND=$(grep '""' $NGINX_MAP | awk '{print $2}' | tr -d ';')

if [ "$CURRENT_BACKEND" == "blue_backend" ]; then
    TARGET="green"
    TARGET_BACKEND="green_backend"
else
    TARGET="blue"
    TARGET_BACKEND="blue_backend"
fi

echo "Desplegando al entorno $TARGET..."

# Desplegar aplicación (ejemplo usando Ansible)
ansible-playbook -i inventory/${TARGET}.ini deploy.yml

# Pruebas de humo
echo "Ejecutando pruebas de humo en $TARGET..."
./smoke-tests.sh $TARGET

# Opción de despliegue gradual
echo "Iniciando despliegue canary (10% tráfico a $TARGET)..."
cat > $NGINX_MAP << EOF
# Despliegue canary - 10% a $TARGET
"" $CURRENT_BACKEND 90;
"" $TARGET_BACKEND 10;
EOF

nginx -s reload

# Monitorear canary durante 5 minutos
sleep 300

# Cambio completo
echo "Cambio completo al entorno $TARGET..."
cat > $NGINX_MAP << EOF
# Backend activo
"" $TARGET_BACKEND;
EOF

nginx -s reload

echo "Despliegue completo. $TARGET ahora está sirviendo 100% de tráfico."

Despliegue Blue-Green en Kubernetes

Configuración de Service:

# service.yaml - Service apuntando a blue o green
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
    version: blue  # Cambiar entre blue/green
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

Despliegue Blue:

# deployment-blue.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
  labels:
    app: myapp
    version: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: blue
  template:
    metadata:
      labels:
        app: myapp
        version: blue
    spec:
      containers:
      - name: app
        image: myapp:v1.0.0
        ports:
        - containerPort: 8080
        env:
        - name: ENVIRONMENT
          value: "blue"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"

Despliegue Green:

# deployment-green.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
  labels:
    app: myapp
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: app
        image: myapp:v2.0.0  # Nueva versión
        ports:
        - containerPort: 8080
        env:
        - name: ENVIRONMENT
          value: "green"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"

Script de Despliegue:

#!/bin/bash
# k8s-bluegreen-deploy.sh

set -e

NAMESPACE="production"
NEW_VERSION="v2.0.0"

# Determinar entorno actual
CURRENT_ENV=$(kubectl get service app-service -n $NAMESPACE \
    -o jsonpath='{.spec.selector.version}')

if [ "$CURRENT_ENV" == "blue" ]; then
    TARGET_ENV="green"
else
    TARGET_ENV="blue"
fi

echo "Entorno actual: $CURRENT_ENV"
echo "Desplegando a: $TARGET_ENV"

# Actualizar imagen de deployment
kubectl set image deployment/app-$TARGET_ENV \
    app=myapp:$NEW_VERSION \
    -n $NAMESPACE

# Esperar rollout
kubectl rollout status deployment/app-$TARGET_ENV -n $NAMESPACE

# Verificar que pods están listos
kubectl wait --for=condition=ready pod \
    -l app=myapp,version=$TARGET_ENV \
    -n $NAMESPACE \
    --timeout=300s

# Ejecutar pruebas de humo
echo "Ejecutando pruebas de humo..."
TARGET_POD=$(kubectl get pod -n $NAMESPACE \
    -l app=myapp,version=$TARGET_ENV \
    -o jsonpath='{.items[0].metadata.name}')

kubectl exec -n $NAMESPACE $TARGET_POD -- /app/smoke-tests.sh

# Cambiar service al entorno objetivo
echo "Cambiando service al entorno $TARGET_ENV..."
kubectl patch service app-service -n $NAMESPACE \
    -p "{\"spec\":{\"selector\":{\"version\":\"$TARGET_ENV\"}}}"

echo "Tráfico cambiado al entorno $TARGET_ENV."
echo "Monitoreando durante 5 minutos..."

# Monitorear métricas
for i in {1..30}; do
    ERROR_RATE=$(kubectl top pod -n $NAMESPACE \
        -l app=myapp,version=$TARGET_ENV 2>&1 | grep -c Error || true)

    if [ $ERROR_RATE -gt 5 ]; then
        echo "¡Tasa de error alta detectada! Revirtiendo..."
        kubectl patch service app-service -n $NAMESPACE \
            -p "{\"spec\":{\"selector\":{\"version\":\"$CURRENT_ENV\"}}}"
        echo "Rollback completado."
        exit 1
    fi

    sleep 10
done

echo "¡Despliegue exitoso!"
echo "Ahora puedes escalar el deployment $CURRENT_ENV a 0 réplicas."

Estrategia de Migración de Base de Datos

Cambios de Esquema Compatibles hacia Atrás:

-- Migración 1: Agregar nueva columna (compatible con código antiguo)
ALTER TABLE users ADD COLUMN email_verified BOOLEAN DEFAULT FALSE;

-- Desplegar nueva versión de aplicación al entorno green
-- Aplicación v2 usa columna email_verified

-- Después de despliegue exitoso y verificación:
-- Migración 2: Eliminar columnas antiguas no usadas
-- (Solo después de que el entorno blue sea decomisionado)

Estrategia de Escritura Dual:

# Código de aplicación soportando esquema antiguo y nuevo

def update_user(user_id, data):
    # Escribir a estructura antigua y nueva
    # Esquema antiguo
    db.execute("UPDATE users SET full_name = ? WHERE id = ?",
               (data['name'], user_id))

    # Esquema nuevo (si existen columnas)
    if 'first_name' in get_table_columns('users'):
        first_name, last_name = data['name'].split(' ', 1)
        db.execute("UPDATE users SET first_name = ?, last_name = ? WHERE id = ?",
                   (first_name, last_name, user_id))

Optimización de Rendimiento

División de Tráfico para Despliegue Gradual

Implementar despliegue canary dentro de blue-green:

# Configuración canary de HAProxy
backend blue-backend
    balance roundrobin
    option httpchk
    server blue1 192.168.1.101:8080 check weight 90
    server green1 192.168.2.101:8080 check weight 10  # 10% tráfico canary

Drenaje de Conexiones

Manejar conexiones existentes con elegancia:

# Configuración de Nginx para drenaje de conexiones
upstream blue_backend {
    server 192.168.1.101:8080 max_conns=0 weight=0;  # Drenar
    keepalive 32;
    keepalive_timeout 60s;
}

Pre-calentamiento

Preparar nuevo entorno antes del cambio:

#!/bin/bash
# prewarm-environment.sh

TARGET_ENV=$1
PREWARM_ENDPOINTS=(
    "/api/products"
    "/api/users"
    "/api/categories"
)

echo "Pre-calentando entorno $TARGET_ENV..."

for endpoint in "${PREWARM_ENDPOINTS[@]}"; do
    for i in {1..100}; do
        curl -s "http://$TARGET_ENV-lb$endpoint" > /dev/null &
    done
done

wait
echo "Pre-calentamiento completado."

Monitoreo y Observabilidad

Dashboard de Monitoreo de Despliegue

Consultas de Prometheus:

# Tasa de peticiones por entorno
rate(http_requests_total{environment=~"blue|green"}[5m])

# Tasa de error por entorno
rate(http_requests_total{environment=~"blue|green",status=~"5.."}[5m])

# Tiempo de respuesta por entorno
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket{environment=~"blue|green"}[5m]))

# Conexiones activas por entorno
haproxy_backend_current_sessions{backend=~"blue|green"}

Configuración de Dashboard de Grafana:

{
  "dashboard": {
    "title": "Monitor de Despliegue Blue-Green",
    "panels": [
      {
        "title": "Tasa de Peticiones por Entorno",
        "targets": [
          {
            "expr": "rate(http_requests_total{environment='blue'}[5m])",
            "legendFormat": "Blue"
          },
          {
            "expr": "rate(http_requests_total{environment='green'}[5m])",
            "legendFormat": "Green"
          }
        ]
      },
      {
        "title": "Tasa de Error %",
        "targets": [
          {
            "expr": "(rate(http_requests_total{environment='blue',status=~'5..'}[5m]) / rate(http_requests_total{environment='blue'}[5m])) * 100",
            "legendFormat": "Blue Error %"
          },
          {
            "expr": "(rate(http_requests_total{environment='green',status=~'5..'}[5m]) / rate(http_requests_total{environment='green'}[5m])) * 100",
            "legendFormat": "Green Error %"
          }
        ]
      }
    ]
  }
}

Disparadores de Rollback Automatizado

#!/usr/bin/env python3
# automated_rollback.py - Monitorear métricas y disparar rollback

import time
import requests
import subprocess

PROMETHEUS_URL = "http://prometheus:9090"
ERROR_THRESHOLD = 5.0  # 5% tasa de error
LATENCY_THRESHOLD = 1000  # 1 segundo

def get_metric(query):
    response = requests.get(f"{PROMETHEUS_URL}/api/v1/query", params={'query': query})
    return float(response.json()['data']['result'][0]['value'][1])

def rollback():
    print("Disparando rollback...")
    subprocess.run(["/usr/local/bin/rollback.sh"])
    # Enviar alerta
    send_alert("Rollback automático disparado debido a alta tasa de error")

def monitor_deployment(target_env, duration=300):
    start_time = time.time()

    while time.time() - start_time < duration:
        # Verificar tasa de error
        error_rate = get_metric(f'''
            (rate(http_requests_total{{environment="{target_env}",status=~"5.."}}[1m]) /
             rate(http_requests_total{{environment="{target_env}"}}[1m])) * 100
        ''')

        # Verificar latencia
        latency = get_metric(f'''
            histogram_quantile(0.99,
                rate(http_request_duration_seconds_bucket{{environment="{target_env}"}}[1m]))
        ''') * 1000

        print(f"Tasa de Error: {error_rate:.2f}%, Latencia P99: {latency:.0f}ms")

        if error_rate > ERROR_THRESHOLD or latency > LATENCY_THRESHOLD:
            rollback()
            return False

        time.sleep(10)

    print("Monitoreo de despliegue completado exitosamente.")
    return True

if __name__ == "__main__":
    import sys
    target_env = sys.argv[1]
    success = monitor_deployment(target_env)
    sys.exit(0 if success else 1)

Resolución de Problemas

Fallos de Despliegue

Síntoma: Nuevo entorno falla health checks.

Diagnóstico:

# Verificar logs de aplicación
kubectl logs -l version=green -n production

# Probar endpoint de health directamente
curl -v http://green-host:8080/health

# Verificar disponibilidad de recursos
kubectl top pods -n production -l version=green

Resolución:

# Escalar recursos si es necesario
kubectl scale deployment app-green --replicas=5 -n production

# Reiniciar pods problemáticos
kubectl delete pod -l version=green -n production

# Revertir a imagen anterior si hay problema de aplicación
kubectl set image deployment/app-green app=myapp:v1.9.0 -n production

El Tráfico No Cambia

Síntoma: El tráfico permanece en entorno antiguo después del cambio.

Diagnóstico:

# Verificar configuración de load balancer
curl -v http://loadbalancer/

# Verificar estado de backend
echo "show stat" | socat stdio /var/run/haproxy/admin.sock

# Verificar DNS si se usa cambio DNS
dig example.com

Resolución:

# Forzar recarga de load balancer
systemctl reload haproxy

# Verificar que map de backend se actualizó
cat /etc/haproxy/backend.map

# Limpiar caché DNS si se usa cambio DNS
systemd-resolve --flush-caches

Problemas de Migración de Base de Datos

Síntoma: Nueva versión falla debido a incompatibilidades de base de datos.

Diagnóstico:

# Verificar versión de esquema de base de datos
psql -c "SELECT version FROM schema_migrations ORDER BY version DESC LIMIT 1;"

# Verificar estado de migración
./manage.py showmigrations

# Verificar logs de aplicación para errores SQL
grep -i "SQL\|database" /var/log/application.log

Resolución:

# Revertir migración de base de datos
./manage.py migrate app_name 0042_previous_migration

# Aplicar migraciones faltantes
./manage.py migrate

# Asegurar compatibilidad hacia atrás
# Agregar nuevas columnas sin eliminar las antiguas primero

Conclusión

El despliegue blue-green proporciona una estrategia robusta y de bajo riesgo para lograr despliegues sin tiempo de inactividad esenciales para organizaciones que practican entrega continua. Al mantener dos entornos de producción completos y cambiar instantáneamente el tráfico entre ellos, los equipos ganan confianza para desplegar frecuentemente mientras mantienen la capacidad de revertir inmediatamente si surgen problemas.

Las implementaciones blue-green exitosas requieren inversión en automatización de infraestructura, monitoreo completo y herramientas de pipeline de despliegue. Aunque mantener entornos duplicados aumenta los costos de infraestructura, las organizaciones compensan estos gastos a través de mayor velocidad de despliegue, reducción de tiempo de inactividad y eliminación de ventanas de mantenimiento que de otro modo impactarían los ingresos.

La gestión de bases de datos representa la complejidad principal en despliegues blue-green—requiriendo cambios de esquema compatibles hacia atrás, secuenciación cuidadosa de migraciones y potencialmente estrategias de escritura dual durante períodos de transición. Los equipos deben invertir en pruebas de migración de bases de datos y procedimientos de rollback tan cuidadosamente como en automatización de despliegue de aplicaciones.

A medida que las arquitecturas de aplicaciones evolucionan hacia microservicios y containerización, los patrones de despliegue blue-green se integran naturalmente con plataformas de despliegue modernas como Kubernetes, service meshes y tecnologías cloud-native. Las organizaciones que dominan estas estrategias de despliegue se posicionan para entregar valor continuo a los clientes mientras mantienen la confiabilidad y disponibilidad que los sistemas de producción demandan.