Email copiado — support@tuurt.com
Cargando experiencia
devops · 13 de octubre de 2026 · 7 min

Blue-green vs canary en GKE: cómo decidimos cuál estrategia de despliegue usar según el tipo de release

Blue-green y canary resuelven el mismo problema de formas muy distintas. Vemos qué señales de un release y qué tooling instalado en el clúster deciden cuál usar en GKE.

Por Equipo Tuurt

Blue-green vs canary en GKE: cómo decidimos cuál estrategia de despliegue usar según el tipo de release

Blue-green y canary resuelven el mismo problema de fondo -desplegar una versión nueva sin tumbar el servicio- pero lo resuelven con mecanismos tan distintos que tratarlos como intercambiables es el error más común que vemos en pipelines de GKE. La pregunta que de verdad importa no es "¿cuál es mejor?" sino "¿qué tipo de release es este, y qué mecanismo de rollback necesita?". La respuesta cambia según el release, y una parte nada despreciable de esa respuesta depende de qué tooling tenemos instalado en el clúster, no solo de la teoría del libro.

Qué hace cada una, sin simplificar de más

Blue-green mantiene dos entornos completos corriendo en paralelo: el que recibe tráfico de producción ("blue") y el que tiene la versión nueva ya desplegada pero todavía sin tráfico real ("green"). El corte es binario: en el momento del switch, el Service deja de apuntar a los pods de blue y empieza a apuntar a los de green. No hay estado intermedio donde un porcentaje de usuarios vea una versión y el resto otra.

# El Service solo cambia su selector, no su definición
apiVersion: v1
kind: Service
metadata:
  name: checkout
spec:
  selector:
    app: checkout
    version: green   # antes: blue
  ports:
    - port: 80
      targetPort: 8080

Canary hace lo opuesto: despliega la versión nueva junto a la vieja y desvía una fracción del tráfico real hacia ella, incrementando esa fracción en pasos mientras observa métricas. No hay un momento de corte; hay una rampa.

# Argo Rollouts: canary con pasos explícitos y pausa para observar
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: checkout
spec:
  replicas: 10
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: { duration: 5m }
        - setWeight: 50
        - pause: { duration: 10m }
        - setWeight: 100

La diferencia no es de preferencia estética. Es una diferencia en qué clase de problema cada mecanismo puede detectar antes de que afecte a todos los usuarios, y en qué infraestructura hace falta para sostenerlo.

El costo que blue-green no esconde: infraestructura duplicada

Blue-green necesita capacidad para correr dos réplicas completas del servicio al mismo tiempo durante la ventana del despliegue: misma cantidad de pods, mismos recursos reservados, mismas dependencias calientes (conexiones a base de datos, pools, cachés tibios). Esa duplicación no es un detalle menor en GKE cuando el Horizontal Pod Autoscaler ya tiene al servicio corriendo cerca del límite superior de su rango: desplegar green exige que el clúster tenga margen para absorber, de golpe, el doble de pods del servicio, aunque sea por minutos.

Esto empuja a blue-green hacia dos escenarios donde tiene sentido pagar ese costo: servicios con tráfico predecible donde la ventana de despliegue es corta y planificada, o releases donde el riesgo real no está en el comportamiento del código bajo carga sino en algo binario -una migración de esquema que ya corrió, una variable de entorno que cambió, una versión de imagen base- que o funciona desde el primer request o no funciona en ninguno. Ahí la rampa gradual de canary no aporta nada: si el problema es binario, observarlo con el 10% del tráfico durante cinco minutos antes de llegar al 100% solo pospone un fallo que de todas formas se manifiesta igual en el primer request que lo toque.

Dónde canary gana: releases con riesgo de comportamiento bajo carga

Canary tiene sentido cuando el riesgo del release no es "funciona o no funciona" sino "se comporta distinto bajo ciertas condiciones de tráfico real": un cambio en una query que es rápido con datos de prueba pero se vuelve costoso con la distribución real de producción, un ajuste de timeout que puede generar reintentos en cascada, un cambio de librería que altera el uso de memoria de forma que solo aparece después de procesar un volumen de requests real. Ninguno de esos problemas se ve en un entorno de staging con tráfico sintético; se ven cuando una fracción pequeña pero real de usuarios pasa por el código nuevo mientras el resto sigue en la versión conocida como punto de comparación.

Esa comparación en vivo es la razón por la que canary casi nunca vale la pena sin un mecanismo de rollback automático atado a métricas, porque la promesa de "detectarlo antes de que afecte a todos" se rompe si alguien tiene que estar mirando un dashboard manualmente durante cada pausa.

# Argo Rollouts con análisis automático: el avance de paso depende de una métrica, no de un humano mirando
spec:
  strategy:
    canary:
      steps:
        - setWeight: 20
        - analysis:
            templates:
              - templateName: error-rate-checkout
      analysis:
        templates:
          - templateName: error-rate-checkout
        args:
          - name: service-name
            value: checkout
---
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: error-rate-checkout
spec:
  metrics:
    - name: error-rate
      interval: 1m
      successCondition: result < 0.02
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{service="checkout",status=~"5.."}[2m]))
            /
            sum(rate(http_requests_total{service="checkout"}[2m]))

Sin este AnalysisTemplate -o su equivalente con Flagger si el clúster usa ese operador en lugar de Argo Rollouts- un canary es, en la práctica, un blue-green lento con pasos intermedios decorativos: la fracción de tráfico aumenta igual, pero nada detiene el avance si algo empieza a fallar entre una pausa y la siguiente.

Lo que decide no es solo la teoría: el tooling que ya está instalado

Aquí es donde la decisión deja de ser puramente técnica. Un canary con análisis automático de métricas requiere que el clúster tenga Argo Rollouts o Flagger instalado, un AnalysisTemplate (o su equivalente) ya definido para el servicio en cuestión, y una fuente de métricas confiable -Prometheus con las queries correctas, no solo instalado sino scrapeando lo que el análisis necesita. Si nada de eso existe todavía para un servicio dado, montar esa infraestructura de observabilidad específica para poder hacer un solo canary no es gratis, y para un release de bajo riesgo puede no justificarse frente a simplemente hacer blue-green con el Service nativo de Kubernetes, que no requiere ningún operador adicional.

Lo mismo pasa con el enrutamiento fino. Repartir tráfico por peso a nivel de Service de Kubernetes es limitado -el balanceo entre endpoints de un Service es aproximadamente uniforme, no pensado para pesos arbitrarios y estables-, así que un canary con control fino de porcentaje casi siempre termina dependiendo de un service mesh como Istio, con un VirtualService definiendo los pesos explícitamente, o directamente del controlador de Argo Rollouts gestionando dos Services (canary y stable) y ajustando cuántos pods hay detrás de cada uno para aproximar el peso deseado sin mesh. Si el clúster no tiene Istio ni Argo Rollouts, la opción realista de "canary con control de tráfico fino" deja de estar disponible, y la elección entre estrategias pasa a ser, en los hechos, una elección entre blue-green y no desplegar canary en absoluto.

Qué revisamos antes de elegir la estrategia de un release

Antes de decidir cómo desplegamos un release en GKE, primero clasificamos el tipo de riesgo: si es un riesgo binario -migración, configuración, versión de imagen- vamos a blue-green porque la rampa gradual no aporta señal; si es un riesgo de comportamiento bajo tráfico real -performance, uso de memoria, interacción con otros servicios- vamos a canary porque necesitamos comparación en vivo contra la versión estable. Después confirmamos que el canary tenga un AnalysisTemplate con una métrica y un umbral definidos de antemano, porque un canary sin análisis automático solo retrasa el mismo fallo que un blue-green expondría de inmediato. Revisamos también la capacidad disponible en el node pool antes de un blue-green, porque la duplicación temporal de pods puede empujar al HPA o al autoscaler del clúster a un límite que no habíamos considerado. Y por último, miramos qué operadores están realmente instalados en el clúster -Argo Rollouts, Flagger, Istio- antes de diseñar una estrategia de canary con control de tráfico fino, porque proponer un peso del 5% en un VirtualService que no existe no es una estrategia, es un documento.

kubernetes gke despliegues devops
← Volver al blog