Despliegues canario que detectan problemas de verdad: Argo Rollouts y Flagger

Mandar el 10 por ciento del tráfico a una versión nueva no es un canario si nadie está mirando. Las métricas, la ventana de análisis y la regla de aborto que hacen que la entrega progresiva compense.

Una actualización progresiva ya te da un despliegue gradual: los pods se reemplazan de pocos en pocos y, si los nuevos no superan su sonda de disponibilidad, el despliegue se detiene. Eso cubre caídas y fallos de arranque, que es la mayor parte del valor, gratis.

Las herramientas de entrega progresiva se ganan su sitio por el otro modo de fallo: la versión que arranca bien, pasa las comprobaciones de salud y está devolviendo 500 en un endpoint o duplicando la latencia p99 en silencio. Una sonda de disponibilidad no ve eso. Un paso de análisis sí.

Rollouts o Flagger

Argo Rollouts sustituye el Deployment por un recurso Rollout que se queda con la estrategia. Funciona con servicios de Kubernetes normales, con un controlador de entrada o con una malla, y tiene una interfaz que muestra exactamente en qué paso va el despliegue. Si ya usas Argo CD, es la elección natural.

Flagger deja tu Deployment en paz y conduce el despliegue desde fuera, creando los objetos canario que necesita. Se apoya más en una malla de servicios o en una entrada con reparto de tráfico. Si usas Flux, es la elección natural.

La diferencia en el uso diario es menor de lo que sugiere la documentación. Elige el que encaje con tu controlador de GitOps.

El análisis es el producto

Todo lo demás es fontanería. Un canario sin análisis es un despliegue más lento con más piezas móviles.

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata: { name: success-rate }
spec:
  args: [{ name: service }]
  metrics:
    - name: success-rate
      interval: 1m
      count: 5
      successCondition: result[0] >= 0.99
      failureLimit: 1
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{service="{{args.service}}",status!~"5.."}[2m]))
            /
            sum(rate(http_requests_total{service="{{args.service}}"}[2m]))

referenciado desde la estrategia:

strategy:
  canary:
    analysis:
      templates: [{ templateName: success-rate }]
      args: [{ name: service, value: orders }]
    steps:
      - setWeight: 5
      - pause: { duration: 5m }
      - setWeight: 25
      - pause: { duration: 10m }
      - setWeight: 50
      - pause: { duration: 10m }

Tres cosas que acertar en ese fichero.

Mide el canario, no el servicio. La consulta de arriba es el error que todo el mundo comete primero: promedia el tráfico del canario con el del estable. Con un peso del 5 por ciento, un canario que devuelve errores en todas las peticiones mueve la tasa combinada de éxito del 100 al 95 por ciento, y eso pasa el umbral >= 0.99 escondiéndose bajo el volumen de la versión estable. Etiqueta tus métricas por versión o por pod y filtra al canario.

Dale tráfico suficiente para que sea significativo. Al 5 por ciento de 20 peticiones por minuto, una ventana de cinco minutos son 5 peticiones. Eso no mide nada. O empiezas con un peso mayor, o aguantas más tiempo, o asumes que para servicios de poco tráfico el canario es teatro: usa azul/verde con una prueba de humo manual.

Elige métricas que fallen cuando el usuario sufre. Tasa de éxito y latencia en p95 o p99, medidas en la entrada. Ni CPU, ni memoria, ni reinicios de pod: eso ya lo cubre la sonda de disponibilidad y no es lo que significa "mal despliegue" para un cliente.

La vuelta atrás y la base de datos

El aborto automático devuelve el tráfico al estable en segundos, la vuelta atrás más rápida que vas a tener. Solo funciona si la versión nueva puede retirarse sin consecuencias, y eso es una cuestión de esquema, no de despliegue.

Mientras corre un canario, dos versiones de tu código leen y escriben en la misma base de datos. Eso significa que toda migración debe ser compatible hacia atrás durante al menos una release: añade columnas, nunca renombres ni borres en el mismo despliegue que el cambio de código; haz las columnas nuevas nulables o con valor por defecto; escribe en el campo viejo y en el nuevo durante la transición; elimina el viejo una release después.

Los equipos que adoptan canarios sin adoptar migraciones de expansión y contracción lo descubren cuando una vuelta atrás automática restaura una versión incapaz de leer las filas que escribió la nueva. La disciplina de migración es el prerrequisito, no una optimización.

Cuándo compensa la complejidad

La entrega progresiva rinde en servicios con tráfico real, un presupuesto de error que importe y despliegues lo bastante frecuentes como para que revisarlos uno a uno haya dejado de tener sentido. Un servicio con tres despliegues al trimestre no la necesita.

Empieza con un servicio de mucho tráfico, una métrica (tasa de éxito) y una escalera de pasos conservadora. Déjalo un mes y mira cuántos despliegues se abortaron. Si la respuesta es cero y además no tuviste incidentes, probablemente la ventana de análisis sea demasiado corta o la métrica esté mal: un canario que nunca ha detectado nada es un canario sin probar. Despliega un build roto a propósito en preproducción y confirma que aborta.

Combinado con Argo CD, el estado final es que integrar en main se convierte en un despliegue que se vigila y se deshace solo, y la intervención humana pasa de aprobar despliegues a aprobar cambios.

ConsultorIA

¿Quieres esto en tu nube?

El diagnóstico de diez días en solo lectura es gratuito, y con Skyline puedes ver tu entorno en un mapa antes de escribirnos.

Artículos relacionados

Módulos que la gente reutiliza en vez de copiar

Los dos fracasos son un módulo que envuelve un recurso y no aporta nada, y un módulo que lo hace todo y que nadie se atreve a cambiar. Una interfaz mínima, valores por defecto seguros y un versionado honesto son lo que los separa.