Read in English · Lire en français · Auf Deutsch lesen
Sección 10.5 de 10.8 · Intermedio · 22 min de lectura
Pipelines de CI/CD y estrategias de despliegue
Videolección
5 min · narrado en inglés, con subtítulosSolo escuchar (audio)
Leer la transcripción
¿Con qué rapidez y seguridad puede tu equipo cambiar cualquier cosa? Lo decide el pipeline de despliegue. En esta lección seguirás un cambio desde el commit hasta producción y aprenderás las estrategias que limitan el daño que puede hacer una versión defectuosa.
Piensa en una cadena de panaderías que lanza un pan nuevo. Hornea un lote de prueba y lo comprueba en su propio obrador. Luego lo vende en una sola tienda durante una mañana, antes de enviarlo a todas las tiendas. Si los clientes se quejan, solo se ha visto afectada una tienda, y el pan de siempre sigue en los estantes. Un pipeline es esa rutina, automatizada: cada cambio se compila una vez, se comprueba por etapas, se prueba con unos pocos usuarios y solo se extiende cuando las pruebas son buenas. Y un interruptor aparte decide cuándo ven los clientes una nueva funcionalidad.
El pipeline de despliegue, descrito por Jez Humble y David Farley en 2010, hace pasar cada commit por etapas automatizadas, las más rápidas primero. La etapa de commit compila, ejecuta las pruebas unitarias y las comprobaciones, y debería tardar menos de diez minutos. La etapa de empaquetado construye una imagen de contenedor, con una lista de materiales de software, la firma y la sube al repositorio de artefactos, una sola vez. Después, las pruebas de aceptación, staging y producción despliegan exactamente esa misma imagen. Un cambio avanza a la derecha solo si la etapa anterior se superó. Esto es build once, deploy many: compilar una vez, desplegar muchas. Entre entornos solo cambia la configuración. Si recompilas para producción, lo que probaste no es lo que entregas. Y cualquier fallo detiene la línea y vuelve directamente al autor, mientras aún tiene el cambio fresco en la mente.
Una estrategia de despliegue decide a cuántos usuarios puede perjudicar una versión defectuosa antes de que se detenga. La recreación detiene todas las instancias antiguas y luego arranca las nuevas: es sencilla, pero tiene tiempo de inactividad, y todos se encuentran a la vez con una versión defectuosa. El despliegue gradual sustituye las instancias unas pocas a la vez, y es la opción por defecto de Kubernetes. Revertir tarda tanto como el despliegue. El azul-verde ejecuta un entorno nuevo completo junto al que está en producción, lo prueba y luego cambia todo el tráfico en el router. Revertir es rápido, pero necesitas hasta el doble de capacidad durante el cambio. Un canario envía una pequeña parte del tráfico, por ejemplo del uno al cinco por ciento, a la nueva versión, compara sus métricas y luego amplía por pasos. Un despliegue en sombra copia solicitudes reales a la nueva versión, pero nunca devuelve sus respuestas, así que hay que suprimir los efectos secundarios, como los pagos. Siempre que se ejecutan dos versiones a la vez, deben ser compatibles con los datos y los mensajes de la otra.
Aquí tienes un canario con análisis automatizado. Los usuarios llegan a un router de tráfico: un balanceador de carga o un service mesh. El noventa por ciento del tráfico va a la flota de producción, que ejecuta la versión uno. El cinco por ciento va a una línea base nueva de la versión uno, y otro cinco por ciento al canario, la versión dos. Comparar con una línea base nueva elimina las diferencias causadas solo por las cachés calientes y el largo tiempo de actividad. Un paso de análisis compara errores, latencia y saturación, y luego amplía el canario al veinticinco por ciento o lo revierte. Decide el sistema, no una persona que mira paneles. Eso es la entrega progresiva.
El despliegue instala una nueva versión en un entorno. El lanzamiento pone un comportamiento a disposición de los usuarios. Los feature flags los separan: el código se despliega desactivado y se lanza más tarde, de forma gradual y reversible. Cada flag tiene un costo de mantenimiento, así que da a los flags fechas de caducidad y elimínalos una vez decididos. Y como los datos no se pueden revertir como el código, los cambios de esquema deben ser compatibles hacia atrás: primero se expande, y solo se contrae en un lanzamiento posterior.
Juntémoslo todo. El servicio de pedidos va a cambiar la forma de calcular las tarifas de envío. El nuevo calculador está detrás de un flag de lanzamiento, desactivado, y una migración solo de expansión añade una columna nueva. El cambio se fusiona a las diez y dos minutos. Lint, pruebas unitarias y escaneos tardan seis minutos, y una imagen firmada se sube a las diez y nueve. La migración aditiva se ejecuta como paso propio a las diez y cuarto. La versión en ejecución ignora la nueva columna, así que nada se rompe. Después, la misma imagen supera las pruebas de staging. A las diez y treinta y cinco, el cinco por ciento del tráfico de producción va a la nueva versión, con el flag todavía desactivado. Veinte minutos de análisis frente a una línea base nueva: pasa. El tráfico pasa al veinticinco, al cincuenta y al cien por ciento en pasos de quince minutos, y termina a las once y cuarenta. El despliegue está completo y, sin embargo, ningún cliente ha visto la nueva tarifa. Al día siguiente, el responsable de producto activa el flag para el diez por ciento de los clientes de una ciudad y luego lo amplía a todas las ciudades a lo largo de una semana. El riesgo del despliegue y el del lanzamiento se gestionaron por separado, cada uno con un radio de impacto reducido.
La sección completa trata el desarrollo basado en trunk, los cuatro tipos de feature flag y cuándo revertir o corregir hacia adelante. A continuación, en la Sección diez punto seis, veremos cómo operar en varias regiones. Nos vemos allí.
Lo que necesitas saber
- Un pipeline de despliegue (Humble y Farley, 2010) hace pasar cada commit por etapas automatizadas, las más rápidas primero, y un fallo en cualquier etapa detiene ese cambio y avisa a su autor.
- Build once, deploy many (compilar una vez, desplegar muchas): empaqueta cada cambio en un único artefacto inmutable, guárdalo en un repositorio de artefactos y promueve ese mismo artefacto por todos los entornos, cambiando solo la configuración.
- El desarrollo basado en trunk (trunk-based development) mantiene las ramas de corta duración y los cambios pequeños, lo que hace real la integración continua y facilita revisar, probar y deshacer cada cambio.
- Los despliegues por recreación (recreate), graduales (rolling), azul-verde (blue-green), canario (canary) y en sombra (shadow) cambian infraestructura y complejidad adicionales por una menor exposición de los usuarios y un rollback más rápido; todos salvo la recreación exigen que las versiones antigua y nueva sean compatibles.
- Los feature flags separan el despliegue del lanzamiento; las categorías de Hodgson son toggles de lanzamiento, de experimento, de operaciones y de permisos, y cada flag tiene un costo hasta que se elimina.
- Los cambios de base de datos deben ser compatibles hacia atrás (expandir y contraer) y ejecutarse como pasos separados del pipeline, porque los datos no se pueden revertir como el código.
- La entrega progresiva automatiza las decisiones sobre el canario comparándolo estadísticamente con una línea base recién creada; la respuesta por defecto ante un mal lanzamiento es revertir primero y diagnosticar después.
Del commit a producción: para qué sirve un pipeline
La Sección 0.8 (cómo se hace el software) presentó la integración continua (cada cambio se fusiona y se verifica automáticamente), la entrega continua (la rama principal está siempre lista para lanzarse) y el despliegue continuo (cada cambio que supera las comprobaciones pasa a producción sin una decisión humana). Esta sección los trata como arquitectura: el diseño del camino que sigue un cambio y las estrategias que lo llevan a producción sin perjudicar a los usuarios.
La idea central es el pipeline de despliegue, descrito por Jez Humble y David Farley en Continuous Delivery (2010). Cada commit desencadena una secuencia automatizada de etapas. Las primeras etapas son rápidas y baratas y detectan la mayoría de los problemas; las posteriores son más lentas, más realistas y más caras. Un cambio pasa a la siguiente etapa solo si la anterior se superó, de modo que cuanto más avanza una compilación, más confianza se ha ganado. Un fallo en cualquier punto detiene esa compilación y vuelve directamente a la persona que hizo el cambio, mientras aún lo tiene fresco en la mente.
El pipeline importa a los arquitectos por tres razones. Primero, es donde la desplegabilidad, un atributo de calidad de la sección 2.6, se logra o se pierde de verdad. Segundo, su velocidad limita la rapidez con la que la organización puede responder a un cambio del mercado o a una vulnerabilidad de seguridad: si una corrección de una línea tarda dos días en llegar a producción, la arquitectura tiene dos días de lentitud, se vea como se vea el código. Tercero, la forma del sistema condiciona la forma del pipeline: los servicios desplegables de forma independiente pueden tener pipelines independientes, pero un monolito distribuido obliga a lanzamientos coordinados por muy ingeniosas que sean las herramientas.
Las etapas de un pipeline típico
Qué hace cada etapa y cuánto debería tardar
- Etapa de commit (objetivo: menos de 10 minutos)Compila, ejecuta las pruebas unitarias, los linters, el análisis estático y los escaneos de vulnerabilidades de las dependencias. Es la etapa que esperan los desarrolladores, así que debe ser rápida; las pruebas lentas van después.
- EmpaquetadoConstruye el artefacto desplegable (normalmente una imagen de contenedor), genera una lista de materiales de software (SBOM), fírmalo y súbelo al repositorio de artefactos. Los controles de la cadena de suministro se tratan en la sección 8.6.
- Aceptación e integraciónDespliega el artefacto en un entorno de pruebas temporal o compartido y ejecuta pruebas de API, pruebas de contrato dirigidas por el consumidor y unos pocos recorridos de extremo a extremo. Las pruebas de rendimiento y de seguridad pueden ejecutarse aquí en paralelo o de forma programada.
- StagingDespliega en un entorno configurado como producción, aplica las migraciones de base de datos y ejecuta pruebas de humo. Su valor depende de lo mucho que se parezca a producción en configuración, forma de los datos y dependencias.
- ProducciónDespliega con una estrategia que limite la exposición (gradual, azul-verde o canario), verifica con métricas reales frente a los objetivos de nivel de servicio y luego completa o revierte automáticamente.
Build once, deploy many y el repositorio de artefactos
Una regla de Continuous Delivery que se sigue incumpliendo con sorprendente frecuencia es build once, deploy many (compilar una vez, desplegar muchas): compila y empaqueta cada cambio exactamente una vez y luego promueve ese mismo artefacto por todos los entornos. Si un equipo recompila para staging y otra vez para producción, lo que probó no es lo que entregó. Un parche distinto del compilador, una dependencia resuelta durante la noche a una versión más reciente o una imagen base cambiada pueden hacer que las dos compilaciones difieran, y las pruebas no demuestran nada sobre la segunda.
Lo que cambia entre entornos es la configuración, proporcionada en el momento del despliegue o del arranque (direcciones de bases de datos, credenciales, ajustes de los feature flags), nunca incorporada al artefacto. Es el factor de configuración de la aplicación de doce factores. Una imagen de contenedor etiquetada orders:4f1c2ab (el hash del commit) se despliega en pruebas, staging y producción; solo cambian sus variables de entorno y los secretos montados.
El repositorio de artefactos es el almacén entre la compilación y el despliegue: un registro de contenedores (Amazon ECR, Azure Container Registry, Google Artifact Registry, GitHub Container Registry, Harbor) o un repositorio universal como JFrog Artifactory o Sonatype Nexus para paquetes y binarios. Trátalo como infraestructura crítica. Despliega por digest inmutable (sha256:...) en lugar de por una etiqueta mutable como latest, que puede moverse para apuntar a otra imagen; conserva los artefactos que están o estuvieron en producción durante todo el tiempo que puedas necesitar volver a ellos o investigarlos; y registra la procedencia, es decir, qué commit, qué ejecución del pipeline y qué dependencias produjeron cada artefacto.
Desarrollo basado en trunk y lotes pequeños
La forma de usar las ramas decide con qué frecuencia se integra realmente el código. En el desarrollo basado en trunk (trunk-based development) todos integran cambios pequeños en una única rama principal (el trunk) al menos una vez al día, ya sea haciendo commit directamente o mediante ramas de corta duración y pull requests que viven horas, no semanas. El programa de investigación DORA ha asociado repetidamente las ramas de corta duración y las fusiones frecuentes con un mayor rendimiento de entrega, y es una condición previa para la integración continua en sentido literal: el código que pasa tres semanas en una rama no se está integrando de forma continua.
Las ramas de funcionalidad de larga duración parecen más seguras porque el trabajo sin terminar se mantiene aparte, pero el riesgo solo se aplaza: cuanto más divergen dos ramas, mayor y más arriesgada es la fusión final, y más tiempo ve el pipeline un código que no es el que se va a entregar. GitFlow, un modelo de ramas con ramas develop y release de larga duración publicado por Vincent Driessen en 2010, se adoptó ampliamente; en 2020 Driessen añadió una nota según la cual los equipos que entregan de forma continua, como los de aplicaciones web, deberían considerar un flujo de trabajo más sencillo. Los equipos que sí necesitan trabajar en cambios grandes en el trunk usan dos técnicas: los feature flags, que ocultan el comportamiento sin terminar, y branch by abstraction, que introduce una interfaz delante de la implementación antigua, construye la nueva detrás de ella y hace el cambio cuando está lista.
Los profesionales discrepan de verdad en los extremos. Los proyectos de código abierto con muchos colaboradores no fiables dependen de pull requests más largos y de la revisión, y los equipos regulados a veces necesitan ramas de lanzamiento explícitas para la auditoría. El principio que sobrevive al desacuerdo es el tamaño del lote: cuanto más pequeño es cada cambio, más fácil es revisarlo, probarlo, desplegarlo, diagnosticarlo y deshacerlo.
name: delivery
on:
push:
branches: [main]
env:
IMAGE: registry.example.com/food/orders:${{ github.sha }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make lint test # fast feedback first
- run: docker build -t "$IMAGE" . && docker push "$IMAGE"
staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh staging "$IMAGE" && ./smoke-test.sh staging
production:
needs: staging
runs-on: ubuntu-latest
environment: production # can require an approval
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh production "$IMAGE" --canary 5Estrategias de despliegue
Una estrategia de despliegue decide cómo sustituye la nueva versión a la antigua en producción y, por tanto, a cuántos usuarios puede perjudicar una versión defectuosa antes de que se detenga. Las estrategias difieren en la infraestructura adicional que necesitan, en la rapidez del rollback y en si se ejecutan dos versiones a la vez. Siempre que se ejecutan dos versiones a la vez, deben ser compatibles con los datos y los mensajes de la otra, y ese es el precio de todas las estrategias salvo la recreación.
Comparación de las estrategias de despliegue
| Estrategia | Cómo funciona | Riesgo para los usuarios | Rollback | Costo y complejidad adicionales |
|---|---|---|---|---|
| Recreación (recreate) | Detener todas las instancias antiguas y luego arrancar las nuevas. | Tiempo de inactividad durante el cambio; todos los usuarios se encuentran a la vez con una versión defectuosa. | Volver a desplegar la versión antigua, con más tiempo de inactividad. | Ninguno. Aceptable para herramientas internas, trabajos por lotes y ventanas de mantenimiento. |
| Gradual (rolling) | Sustituir las instancias unas pocas a la vez (la opción por defecto de Kubernetes para los Deployments, con maxSurge y maxUnavailable ambos en un 25% por defecto). | La exposición crece a medida que avanza el despliegue; las comprobaciones de estado detectan las caídas, pero no los errores sutiles. | Se revierte desplegando de nuevo gradualmente la versión antigua, lo que tarda tanto como el despliegue. | Bajo. Las versiones antigua y nueva se ejecutan en paralelo, así que deben ser compatibles. |
| Azul-verde (blue-green) | Ejecutar un entorno nuevo completo (verde) junto al que está en producción (azul), probarlo y luego cambiar todo el tráfico en el router. | Todos los usuarios pasan a la vez, pero el entorno nuevo se verificó antes del cambio. | Rápido: volver a cambiar el router mientras el azul sigue en marcha. | Hasta el doble de capacidad durante el cambio; las bases de datos compartidas deben funcionar con ambas versiones. |
| Canario (canary) | Enviar una pequeña parte del tráfico (por ejemplo, un 1-5%) a la nueva versión, comparar sus métricas y luego ampliar por pasos. | Solo la parte de usuarios del canario se encuentra con una versión defectuosa, y solo hasta que el análisis la detiene. | Rápido: poner a cero el peso del canario. | Necesita enrutamiento ponderado, buenas métricas y suficiente tráfico para que la comparación tenga sentido. |
| En sombra (dark launch) | Copiar solicitudes reales a la nueva versión; sus respuestas se comparan o se descartan, nunca se devuelven. | Ninguno directamente, siempre que los efectos secundarios (pagos, correos electrónicos, escrituras) se supriman o se simulen. | No hay nada que revertir; los usuarios nunca dependieron de ella. | El doble de carga en la ruta en sombra y un manejo cuidadoso de los efectos secundarios; ideal para rutas de lectura y reescrituras. |
Martin Fowler describió el despliegue azul-verde en 2010, atribuyéndolo a Dan North y Jez Humble; el lanzamiento canario, llamado así por los canarios que llevaban los mineros para detectar gas, lo documentó Danilo Sato en el mismo sitio en 2014. En Kubernetes, las actualizaciones graduales vienen integradas; los lanzamientos azul-verde y canario suelen venir de un controlador de entrega progresiva (Argo Rollouts, Flagger) o de un service mesh y del enrutamiento ponderado de la Gateway API. En las plataformas gestionadas, las funciones equivalentes se llaman división del tráfico (traffic splitting) o ranuras de despliegue (deployment slots).
Lanzamiento canario con análisis automatizado
Separar el despliegue del lanzamiento con feature flags
El despliegue instala una nueva versión del software en un entorno; el lanzamiento pone un comportamiento a disposición de los usuarios. Tratarlos como un solo acontecimiento convierte cada despliegue en un acontecimiento de negocio, con todo el nerviosismo que eso conlleva. Los feature flags (feature toggles) los separan: el código nuevo se despliega desactivado, y el comportamiento se lanza más tarde, de forma gradual y reversible, cambiando la configuración. El artículo de Pete Hodgson Feature Toggles (aka Feature Flags) en martinfowler.com (2017) distingue cuatro categorías según cuánto tiempo viven y con qué dinamismo deciden.
Las cuatro categorías de feature toggle de Hodgson
| Categoría | Propósito | Vida típica | Grado de dinamismo |
|---|---|---|---|
| Toggles de lanzamiento | Entregar en el trunk funcionalidades incompletas o no lanzadas, desactivadas. | De días a unas pocas semanas; se eliminan tras el lanzamiento. | Mayormente estáticos en cada versión. |
| Toggles de experimento | Pruebas A/B o multivariantes que dirigen a cada usuario a una cohorte. | El tiempo suficiente para obtener resultados estadísticamente sólidos; luego se eliminan. | Por solicitud, según la cohorte del usuario. |
| Toggles de operaciones | Controles operativos, como desactivar un costoso panel de recomendaciones cuando hay mucha carga (interruptores de emergencia o kill switches). | Mayormente cortos; unos pocos interruptores de emergencia se mantienen a largo plazo. | Se cambian en tiempo de ejecución, a menudo durante un incidente. |
| Toggles de permisos | Funcionalidades para usuarios concretos: niveles premium, probadores beta, personal interno. | Pueden vivir años. | Por solicitud, según el usuario. |
Los flags tienen un costo de mantenimiento. Cada flag duplica los caminos por el código que protege, añade combinaciones de prueba y deja código muerto una vez que su decisión está tomada. Hodgson recomienda tratar los flags como un inventario: añadir una tarea de eliminación cuando se crea un toggle de lanzamiento, dar a los flags fechas de caducidad, añadir pruebas que fallen cuando un flag ha pasado su fecha y limitar cuántos pueden existir a la vez. La pérdida de Knight Capital en 2012, descrita en la sección 1.3, tuvo que ver con un flag reutilizado que reactivó código antiguo en un servidor que se había saltado un despliegue manual: un recordatorio de no reutilizar nunca los nombres de los flags y de borrar el código muerto que hay detrás de los flags ya decididos. A escala, los flags los sirve un servicio dedicado (opciones de código abierto como Unleash y Flagsmith, comerciales como LaunchDarkly, o la API neutral respecto al proveedor OpenFeature) para que un cambio se propague en segundos y quede auditado.
Cambios de base de datos en el pipeline
El código se puede revertir en segundos; los datos, no. Un despliegue que renombra una columna y luego se revierte deja al código antiguo frente a un esquema que no entiende. La solución, tratada en profundidad en evolución de esquemas, es hacer que cada cambio de esquema sea compatible hacia atrás con la versión del código que se está ejecutando, usando expandir y contraer: añade primero la nueva estructura, despliega código que escriba en ambas y lea de cualquiera, rellena los datos (backfill), cambia los lectores y elimina la estructura antigua solo en un lanzamiento posterior, cuando ya nada la use.
En el pipeline, esto significa que las migraciones son artefactos versionados que se ejecutan como un paso propio, antes de desplegar el código que las necesita, y que se prueban con una copia de los datos del tamaño de producción, para que un bloqueo en una tabla grande se descubra en staging y no a la hora de comer. Los pasos destructivos (eliminar columnas o tablas) se retrasan y se ejecutan por separado, porque son el único tipo de cambio que un rollback no puede deshacer. Una comprobación útil del pipeline hace fallar la compilación cuando una migración no es aditiva, salvo que esté marcada explícitamente como paso de contracción.
Entrega progresiva y análisis canario automatizado
La entrega progresiva, un término popularizado por James Governor, de la firma de análisis RedMonk, en 2018, combina canarios, feature flags y verificación automatizada: un cambio llega a públicos cada vez mayores y, en cada paso, es el sistema, no una persona que mira paneles, quien decide si continuar. La decisión usa el análisis canario automatizado: las métricas del canario (tasa de errores, percentiles de latencia, saturación, señales de negocio como los pedidos realizados) se comparan estadísticamente con una línea base. Netflix y Google publicaron como código abierto su motor de análisis, Kayenta, en 2018; Argo Rollouts y Flagger ofrecen pasos de análisis similares en Kubernetes.
Tres detalles deciden si se puede confiar en el análisis. Compara lo comparable: una línea base nueva de la versión antigua que recibe la misma parte del tráfico evita culpar a la nueva versión de diferencias causadas por cachés frías o reinicios recientes. Ten suficiente tráfico: con el 5% de un servicio que atiende diez solicitudes por minuto, una hora de canario ve treinta solicitudes, demasiado pocas para detectar una tasa de errores del 1%, así que los servicios con poco tráfico necesitan pasos más largos, carga sintética o una estrategia distinta. Elige métricas ligadas a los objetivos de nivel de servicio y a los resultados de negocio, porque una versión puede ser rápida y no tener errores mientras cobra en silencio una tarifa de envío incorrecta.
Rollback o roll forward
Cuando un lanzamiento sale mal, hay dos salidas. El rollback vuelve al artefacto anterior, lo que es rápido y no necesita código nuevo, siempre que la versión anterior siga funcionando con los datos actuales y con las versiones de los demás servicios. El roll forward (corrección hacia adelante) entrega una corrección a través del pipeline, lo que es más lento, pero a veces es la única opción, por ejemplo tras una migración de datos que no se puede revertir o un cambio del que ya dependen otros servicios.
Un buen criterio por defecto es revertir primero, diagnosticar después
: restablece el servicio con la acción segura más rápida y luego investiga sin presión. Corregir hacia adelante bajo presión tiende a saltarse las comprobaciones del pipeline, y una corrección precipitada de un incidente en producción es una fuente clásica del siguiente incidente. El rollback solo es una opción real si se diseña desde el principio: conservar los artefactos anteriores, hacer que los cambios de esquema sean compatibles en ambas direcciones durante al menos una versión, que los mensajes los puedan leer consumidores antiguos y nuevos, y ejercitar con regularidad el propio camino de rollback. Un equipo que nunca ha hecho un rollback debería suponer que no puede hacerlo.
Ejemplo práctico
Ejemplo práctico: lanzar una nueva regla de tarifa de envío
El servicio de pedidos de la plataforma de reparto de comida va a cambiar la forma de calcular las tarifas de envío, usando la distancia y la demanda en lugar de una tarifa fija. El equipo usa desarrollo basado en trunk, un despliegue canario y un flag de lanzamiento.
| Cambio | Nuevo calculador de tarifas detrás de un flag de lanzamiento dynamic-delivery-fee, desactivado por defecto; una migración solo de expansión añade una columna que admite nulos, fee_rule_version. |
|---|---|
| Del commit al artefacto | Se fusiona en main a las 10:02. Lint, pruebas unitarias y escaneos tardan 6 minutos; la imagen orders:4f1c2ab, con su SBOM y su firma, se sube a las 10:09. |
| Migración | La migración aditiva se ejecuta a las 10:15 como paso propio del pipeline. La versión en ejecución ignora la nueva columna, así que nada se rompe. |
| Staging | La misma imagen se despliega a las 10:16; las pruebas de contrato con los servicios de pagos y de restaurantes y las pruebas de humo pasan a las 10:31. |
| Canario | A las 10:35, el 5% del tráfico de producción va a la nueva versión, todavía con el flag desactivado. El análisis durante 20 minutos compara la latencia p99, la tasa de 5xx y el éxito de los pedidos con una línea base nueva: pasa. |
| Despliegue progresivo | Los pesos pasan al 25%, al 50% y al 100% en pasos de 15 minutos; termina a las 11:40. El despliegue está completo y, sin embargo, ningún cliente ha visto la nueva tarifa. |
| Lanzamiento | Al día siguiente, el responsable de producto activa el flag para el 10% de los clientes de una ciudad y vigila la conversión de pedidos y las quejas; luego lo amplía a todas las ciudades a lo largo de una semana. |
| Limpieza | El flag y el código de la tarifa fija se eliminan en el sprint siguiente; una migración de contracción posterior hace obligatoria la columna. |
El riesgo del despliegue (¿funciona el código?) y el riesgo del lanzamiento (¿les gustan a los clientes las nuevas tarifas?) se gestionaron por separado, cada uno con su propio radio de impacto reducido.
En cada paso hasta la migración de contracción, la recuperación era un cambio de configuración o de peso en el router, no una corrección de emergencia. Del commit al despliegue completo en producción pasaron alrededor de 1 hora y 40 minutos.
Medir el pipeline
Las métricas DORA de entrega de software presentadas en la sección 2.6 (tiempo de entrega de los cambios, frecuencia de despliegue, tasa de fallos de los cambios, tiempo de recuperación de un despliegue fallido y tasa de retrabajo de despliegues) son en gran medida propiedades del pipeline y de la arquitectura en conjunto. Los lotes pequeños y el desarrollo basado en trunk acortan el tiempo de entrega y aumentan la frecuencia; las pruebas automatizadas y el análisis canario reducen la tasa de fallos de los cambios; el rollback rápido y los flags acortan el tiempo de recuperación. Mídelas por servicio, observa las tendencias en lugar de valores aislados y nunca las conviertas en objetivos individuales, lo que solo invita a manipularlas.
Comprueba lo que has entendido
¿Por qué es un problema recompilar el artefacto por separado para producción aunque el código fuente sea idéntico?
Las dependencias, las imágenes base o las herramientas de compilación pueden haber cambiado entre compilaciones, así que el artefacto de producción no es el que se probó; compila una vez y promueve el mismo artefacto.
¿Cuál es la diferencia entre desplegar una funcionalidad y lanzarla?
El despliegue instala el código en un entorno; el lanzamiento pone el comportamiento a disposición de los usuarios. Los feature flags permiten desplegar el código desactivado y lanzarlo más tarde, de forma gradual y reversible.
¿Por qué un canario en un servicio con poco tráfico da a menudo resultados poco fiables?
Una pequeña parte de poco tráfico produce demasiado pocas solicitudes para detectar diferencias en la tasa de errores o en la latencia con confianza estadística, así que hay que alargar los pasos, usar tráfico sintético o elegir otra estrategia.
¿Cuándo puede ser corregir hacia adelante la única opción?
Cuando el lanzamiento incluyó un cambio irreversible, como una migración destructiva, o cuando otros servicios ya dependen del nuevo comportamiento, de modo que la versión anterior ya no puede funcionar correctamente.
Fuentes y lecturas recomendadas
¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.
Pregunta: “Nuestro equipo despliega cada dos semanas con una lista de comprobación manual. ¿Qué cambios en el pipeline y en el despliegue deberíamos hacer primero para desplegar de forma segura varias veces al día?”