La lección anterior terminó con un diagnóstico incómodo: vm-motor-disponibilidad-dev funciona, pero es una sola máquina. Si el host físico falla, si Azure aplica mantenimiento a la plataforma o si el tráfico se multiplica por diez, no hay plan B. Y a Contoso Airlines le va a pasar lo tercero con fecha marcada en el calendario.

Cada año, a mediados de febrero, Contoso abre la venta de la temporada de verano. El primer día se concentra alrededor del 60 % del tráfico del mes, con un pico de tres horas por la mañana en el que la API de Disponibilidad recibe unas quince veces las peticiones de un día normal. Con servidores propios en Barcelona y Palma, la respuesta histórica fue comprar hardware para el pico y tenerlo al 6 % de uso los otros 364 días. Ese es, literalmente, el problema que la nube resuelve.

En esta lección aprenderás a escalar el cómputo y a darle alta disponibilidad: qué diferencia hay entre crecer hacia arriba y crecer hacia los lados, cómo funcionan los conjuntos de escalado de máquinas virtuales, cómo se reparten las instancias en zonas de disponibilidad, qué balanceador elegir entre los cuatro que ofrece Azure, y qué requisito de diseño impone todo esto a tu aplicación: no tener estado.

Aviso de coste: un conjunto de escalado con dos instancias factura dos VM, y un Load Balancer Standard tiene coste por hora y por reglas. Todo lo de esta lección se elimina al final con un único borrado del grupo de recursos de laboratorio.

Contenido

  1. Escalado vertical frente a escalado horizontal
  2. El caso de Contoso: el pico de apertura de temporada
  3. Conjuntos de escalado de máquinas virtuales (VMSS)
  4. Escalado manual, automático por métrica y programado
  5. Zonas de disponibilidad y conjuntos de disponibilidad
  6. Balanceo de carga en Azure: las cuatro opciones
  7. Sondas de estado
  8. Desplegar la API de Disponibilidad tras un Load Balancer
  9. Aplicaciones sin estado: el requisito escondido
  10. Arquitectura resultante y limpieza
  11. Errores Comunes y Consejos
  12. Ejercicios
  13. Conclusión

  1. Escalado vertical frente a escalado horizontal

Hay dos maneras de dar más capacidad a un sistema.

Aspecto Escalado vertical (scale up) Escalado horizontal (scale out)
Qué haces Cambias la máquina por otra mayor Añades más máquinas iguales
En Azure az vm resize a un tamaño superior Añadir instancias a un conjunto de escalado
Interrupción Requiere reinicio de la VM Ninguna: las nuevas instancias se suman
Límite El tamaño máximo de la familia Prácticamente el de tu cuota
Alta disponibilidad Ninguna: sigue siendo un punto único de fallo Intrínseca: si cae una instancia, quedan las demás
Reversibilidad Manual y con reinicio Automática y en minutos
Requisito de la aplicación Ninguno La aplicación no puede guardar estado local

El escalado vertical es simple y a veces la respuesta correcta: una base de datos relacional monolítica suele escalar mejor hacia arriba. Pero para el cómputo de una aplicación web, el modelo de la nube es el horizontal, por tres razones:

  1. Elasticidad real: puedes pasar de 2 a 20 instancias en minutos y volver a 2 cuando el pico termine. Pagas por lo que usas, cuando lo usas.
  2. Disponibilidad: N instancias repartidas soportan la pérdida de una sin que el servicio caiga.
  3. Sin techo abrupto: no llegas un día al tamaño máximo de la familia y te quedas sin salida.

La contrapartida es la de la última fila de la tabla, y no es menor: si tu aplicación guarda la sesión del usuario en la memoria del servidor o escribe ficheros en su disco local, el escalado horizontal la rompe. Lo tratamos en el apartado 9.

  1. El caso de Contoso: el pico de apertura de temporada

Los números que Marta Ríos ha medido en el sistema actual:

Momento Peticiones por segundo a la API de Disponibilidad CPU media del servidor actual
Día normal, madrugada 15 5 %
Día normal, hora punta 120 35 %
Apertura de temporada, primera hora 1.800 saturado (100 %, colas)
Apertura de temporada, resto del día 400 90 %

La conclusión es doble: se necesita capacidad muy superior durante unas horas al año y capacidad mínima el resto del tiempo. Dimensionar para el pico con máquinas fijas significa pagar quince veces lo necesario durante 360 días. Dimensionar para el día normal significa perder ventas el día que más se vende.

La solución que construimos en esta lección: la API de Disponibilidad se despliega en un conjunto de escalado con un mínimo de 2 instancias repartidas en dos zonas, una regla de escalado automático por CPU y una regla programada que eleva el mínimo la mañana de la apertura, todo detrás de un Load Balancer.

  1. Conjuntos de escalado de máquinas virtuales (VMSS)

Un conjunto de escalado de máquinas virtuales (Virtual Machine Scale Set, VMSS) es un recurso que gestiona un grupo de VM idénticas como una sola unidad: se crean a partir del mismo modelo, se actualizan juntas y crecen o menguan según reglas.

Qué te da un VMSS que no te da crear VM a mano:

  • Un solo modelo: cambias la imagen o el tamaño en el modelo y se aplica a todas.
  • Escalado automático por métrica, por horario o manual.
  • Reparación automática de instancias: si una instancia falla la sonda de estado durante un tiempo, el conjunto la reemplaza.
  • Distribución automática entre zonas y dominios de error.
  • Actualizaciones por lotes (rolling upgrades) sin caída del servicio.

Modelo de orquestación: uniforme frente a flexible

Aspecto Orquestación Uniform Orquestación Flexible
Instancias Idénticas, gestionadas como conjunto VM normales, individualmente visibles
Acceso a cada instancia Limitado, a través del conjunto Igual que a cualquier VM (az vm show)
Mezcla de tamaños o de VM al contado y esporádicas No Sí
Zonas de disponibilidad Sí Sí, con reparto explícito
Recomendación actual de Azure Cargas homogéneas muy grandes Predeterminada para casi todo lo nuevo

Flexible es hoy el modo recomendado por defecto: te da la gestión del conjunto sin perder el control individual de cada VM, y permite mezclar instancias de precio esporádico (spot) con instancias normales para abaratar los picos. Es el que usaremos.

  1. Escalado manual, automático por métrica y programado

Escalado manual

# Fijar el número de instancias a mano. Útil para pruebas y respuestas puntuales.
az vmss scale \
  --resource-group rg-contoso-reservas-pro \
  --name vmss-api-disponibilidad-pro \
  --new-capacity 4

Escalado automático por métrica

El escalado automático observa una métrica y actúa. Una regla completa tiene siempre estas piezas:

Pieza Qué define Ejemplo
Métrica Qué se observa Percentage CPU del conjunto
Agregación y ventana Cómo se resume y en cuánto tiempo Media de los últimos 5 minutos
Umbral y operador Cuándo se dispara Mayor que 70 %
Acción Qué se hace Aumentar en 2 instancias
Enfriamiento (cooldown) Cuánto se espera antes de volver a actuar 5 minutos
Límites Mínimo, máximo y predeterminado 2 / 20 / 2
GRUPO="rg-contoso-reservas-pro"
VMSS="vmss-api-disponibilidad-pro"

# 1. Perfil de escalado automático: mínimo 2, máximo 20, valor por defecto 2.
az monitor autoscale create \
  --resource-group "${GRUPO}" \
  --resource "${VMSS}" \
  --resource-type Microsoft.Compute/virtualMachineScaleSets \
  --name autoescala-api-disponibilidad \
  --min-count 2 --max-count 20 --count 2 \
  --output none

# 2. Regla de aumento: si la CPU media supera el 70 % durante 5 minutos, +2 instancias.
az monitor autoscale rule create \
  --resource-group "${GRUPO}" \
  --autoscale-name autoescala-api-disponibilidad \
  --condition "Percentage CPU > 70 avg 5m" \
  --scale out 2 \
  --cooldown 5 \
  --output none

# 3. Regla de reducción: si baja del 30 % durante 10 minutos, -1 instancia.
az monitor autoscale rule create \
  --resource-group "${GRUPO}" \
  --autoscale-name autoescala-api-disponibilidad \
  --condition "Percentage CPU < 30 avg 10m" \
  --scale in 1 \
  --cooldown 10 \
  --output none

Fíjate en la asimetría deliberada entre las dos reglas, que es una buena práctica y no un descuido:

  • Se sube rápido y en bloques grandes (+2 con ventana de 5 minutos): quedarse corto cuesta ventas.
  • Se baja despacio y de una en una (−1 con ventana de 10 minutos): reducir demasiado pronto provoca el efecto sierra, en el que el sistema añade y quita instancias sin parar, y cada arranque tarda minutos y cuesta dinero.

Si las reglas de subida y bajada tienen el mismo umbral, tendrás oscilación garantizada. Deja siempre una banda muerta amplia entre ambas (aquí, entre 30 % y 70 %).

Escalado programado

Cuando sabes cuándo llega el pico, no esperes a que la CPU lo demuestre: la reacción por métrica siempre llega tarde, porque una instancia nueva tarda unos minutos en arrancar y estar lista.

# La apertura de temporada es el 12 de febrero por la mañana:
# elevamos el mínimo a 10 instancias entre las 07:00 y las 14:00.
az monitor autoscale profile create \
  --resource-group "${GRUPO}" \
  --autoscale-name autoescala-api-disponibilidad \
  --name apertura-temporada-verano \
  --min-count 10 --max-count 30 --count 12 \
  --timezone "W. Europe Standard Time" \
  --start 2026-02-12T07:00 \
  --end 2026-02-12T14:00 \
  --output none

Durante ese perfil, el conjunto nunca baja de 10 instancias y puede llegar a 30 si la CPU lo pide. Fuera de la ventana, vuelve al perfil normal (2–20). Esta combinación —programado para lo previsible, por métrica para lo imprevisible— es el patrón que usan la mayoría de plataformas de venta con estacionalidad.

  1. Zonas de disponibilidad y conjuntos de disponibilidad

Tener varias instancias no sirve de nada si están todas en el mismo bastidor y ese bastidor se queda sin corriente. Azure ofrece dos mecanismos de reparto, y protegen de cosas distintas.

Conjunto de disponibilidad (dentro de un mismo centro de datos)

Reparte las VM entre:

  • Dominios de error (fault domains): grupos de servidores que comparten alimentación eléctrica y conmutador de red. Si falla el bastidor, cae un dominio de error. Hasta 3 por región.
  • Dominios de actualización (update domains): grupos que Azure reinicia por separado durante el mantenimiento de la plataforma. Hasta 20.
graph TB
    subgraph AS["Conjunto de disponibilidad (un centro de datos)"]
        subgraph FD0["Dominio de error 0"]
            V1["Instancia 1"]
        end
        subgraph FD1["Dominio de error 1"]
            V2["Instancia 2"]
        end
        subgraph FD2["Dominio de error 2"]
            V3["Instancia 3"]
        end
    end

Protege de: fallo de bastidor y reinicios de mantenimiento. No protege de la caída completa del centro de datos.

Zonas de disponibilidad (centros de datos distintos)

Como viste en 01-02, una zona es un centro de datos físicamente separado dentro de la misma región, con alimentación, refrigeración y red independientes. Repartir instancias entre zonas protege del fallo de un centro de datos entero.

Mecanismo Protege de SLA de disponibilidad
Instancia única con discos Premium Nada, más allá del hardware local 99,9 %
Conjunto de disponibilidad (2+ instancias) Fallo de bastidor y mantenimiento 99,95 %
Zonas de disponibilidad (2+ instancias en 2+ zonas) Caída de un centro de datos 99,99 %

Decisión de Contoso, coherente con la del módulo 1: componentes críticos en al menos dos zonas de West Europe, sin activo-activo multirregión (decisión consciente por coste). La API de Disponibilidad se despliega en las zonas 1 y 2.

# Conjunto de escalado con reparto explícito en dos zonas.
az vmss create \
  --resource-group rg-contoso-reservas-pro \
  --name vmss-api-disponibilidad-pro \
  --orchestration-mode Flexible \
  --zones 1 2 \
  --instance-count 2 \
  --vm-sku Standard_B2s \
  --image Canonical:ubuntu-24_04-lts:server:latest \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/contoso_motor.pub \
  --custom-data init-api.yaml \
  --tags entorno=produccion proyecto=contoso-reservas \
         centro-coste=CC-1042 [email protected] \
         criticidad=alta \
  --output none

Con --zones 1 2, Azure reparte las instancias de forma equilibrada entre ambas zonas y mantiene ese equilibrio al escalar. Importante: las zonas se eligen al crear el conjunto y no se pueden añadir después. Si crees que algún día lo necesitarás, créalo con zonas desde el principio.

  1. Balanceo de carga en Azure: las cuatro opciones

Tener varias instancias exige algo delante que reparta el tráfico. Azure ofrece cuatro servicios y la confusión entre ellos es uno de los temas favoritos de los exámenes de certificación (y de las arquitecturas mal hechas).

Servicio Capa Ámbito Enruta por Casos típicos Coste relativo
Azure Load Balancer 4 (TCP/UDP) Regional IP y puerto Cualquier protocolo TCP/UDP, backend de VM y VMSS €
Application Gateway 7 (HTTP/S) Regional Ruta URL, cabecera, host Web y API con enrutamiento por ruta, terminación TLS, WAF €€€
Traffic Manager DNS Global Respuesta DNS por perfil (rendimiento, prioridad, geografía) Conmutación entre regiones, cualquier protocolo €
Azure Front Door 7 Global Ruta, host, con red perimetral y caché Sitios web globales, terminación TLS en el borde, caché, WAF global €€€

Criterios de elección, en forma de preguntas:

  1. ¿Es tráfico HTTP/S? Si no lo es (por ejemplo, un protocolo propio del motor heredado), tu opción es Load Balancer o Traffic Manager.
  2. ¿Necesitas decidir por la URL (/api/* a un grupo, / a otro), reescribir cabeceras o descargar TLS? Entonces necesitas capa 7: Application Gateway o Front Door.
  3. ¿El tráfico llega de todo el mundo y quieres caché y presencia en el borde? Front Door.
  4. ¿Solo quieres conmutar entre regiones a nivel DNS, con cualquier protocolo? Traffic Manager.

Dos avisos de alcance, para no invadir otras lecciones:

  • Lo global —Front Door, Traffic Manager, CDN— se desarrolla en la lección 02-06, con el caso del cliente que compra desde Sudamérica.
  • El firewall de aplicaciones web (WAF), que se acopla a Application Gateway o a Front Door, se trata en la lección 04-04.

Aquí nos quedamos en lo regional y de capa 4: Azure Load Balancer delante del conjunto de escalado.

Componentes de un Load Balancer

Componente Qué es
IP frontal (frontend) La IP pública o privada por la que entra el tráfico
Grupo de back-end (backend pool) El conjunto de instancias que reciben el tráfico
Sonda de estado (health probe) La comprobación que decide qué instancias están sanas
Regla de balanceo Une frontal, puerto, grupo y sonda

Las SKU: Standard (la actual: admite zonas, hasta 1.000 instancias, seguro por defecto) y Basic, ya retirada. Usa siempre Standard.

  1. Sondas de estado

Una sonda de estado es lo que separa un balanceador de un repartidor ciego. Cada pocos segundos, el balanceador pregunta a cada instancia si está viva; si no responde correctamente un número de veces seguidas, deja de enviarle tráfico.

# Sonda HTTP contra el punto de salud de la API, cada 5 segundos.
az network lb probe create \
  --resource-group rg-contoso-reservas-pro \
  --lb-name lb-api-disponibilidad-pro \
  --name sonda-api-salud \
  --protocol Http \
  --port 80 \
  --path /salud.json \
  --interval 5 \
  --output none

Buenas prácticas para el punto de salud, que valen para todo el curso:

  • Que sea significativo: debe comprobar lo que hace falta para servir (¿hay conexión con la base de datos?), no devolver 200 siempre.
  • Que sea barato: se ejecuta cada pocos segundos por instancia. Nada de consultas pesadas.
  • Que no exija autenticación desde la red interna, o la sonda fallará siempre.
  • Separa vivacidad de preparación: «el proceso está vivo» no es lo mismo que «puedo atender peticiones ya».

Una sonda mal hecha causa dos averías clásicas y opuestas: instancias rotas recibiendo tráfico (sonda demasiado indulgente) o instancias sanas retiradas del servicio en cascada (sonda demasiado estricta o con tiempo de espera corto).

  1. Desplegar la API de Disponibilidad tras un Load Balancer

Montamos la pieza completa. Para no tocar producción mientras aprendes, usa el grupo de desarrollo; el ejemplo indica producción porque es la arquitectura objetivo, pero puedes sustituir pro por dev en todas las variables.

#!/usr/bin/env bash
set -euo pipefail

GRUPO="rg-contoso-reservas-pro"
REGION="westeurope"
VMSS="vmss-api-disponibilidad-pro"
LB="lb-api-disponibilidad-pro"
IP_PUB="ip-lb-api-disponibilidad-pro"

ETIQUETAS=(entorno=produccion proyecto=contoso-reservas centro-coste=CC-1042
           [email protected] criticidad=alta)

# 1. IP pública estándar y con redundancia de zona.
az network public-ip create \
  --resource-group "${GRUPO}" --name "${IP_PUB}" \
  --sku Standard --zone 1 2 3 --allocation-method Static \
  --tags "${ETIQUETAS[@]}" --output none

# 2. Load Balancer con frontal público y grupo de back-end vacío.
az network lb create \
  --resource-group "${GRUPO}" --name "${LB}" --sku Standard \
  --public-ip-address "${IP_PUB}" \
  --frontend-ip-name frontal-publico \
  --backend-pool-name pool-api-disponibilidad \
  --tags "${ETIQUETAS[@]}" --output none

# 3. Sonda de estado contra el punto de salud de la API.
az network lb probe create \
  --resource-group "${GRUPO}" --lb-name "${LB}" \
  --name sonda-api-salud --protocol Http --port 80 --path /salud.json \
  --interval 5 --output none

# 4. Regla de balanceo: puerto 80 del frontal al puerto 80 del grupo.
az network lb rule create \
  --resource-group "${GRUPO}" --lb-name "${LB}" \
  --name regla-http-api \
  --protocol Tcp --frontend-port 80 --backend-port 80 \
  --frontend-ip-name frontal-publico \
  --backend-pool-name pool-api-disponibilidad \
  --probe-name sonda-api-salud \
  --idle-timeout 10 --output none

# 5. Conjunto de escalado en dos zonas, ya conectado al grupo de back-end.
az vmss create \
  --resource-group "${GRUPO}" --name "${VMSS}" \
  --orchestration-mode Flexible \
  --zones 1 2 --instance-count 2 \
  --vm-sku Standard_B2s \
  --image Canonical:ubuntu-24_04-lts:server:latest \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/contoso_motor.pub \
  --custom-data init-api.yaml \
  --lb "${LB}" --backend-pool-name pool-api-disponibilidad \
  --upgrade-policy-mode Automatic \
  --tags "${ETIQUETAS[@]}" --output none

echo "API publicada en: http://$(az network public-ip show -g "${GRUPO}" -n "${IP_PUB}" --query ipAddress -o tsv)/salud.json"

El fichero init-api.yaml que instala la API en cada instancia (el mismo mecanismo de cloud-init de la lección anterior, ahora sirviendo la identidad de la instancia para que puedas ver el balanceo funcionando):

#cloud-config
package_update: true
packages:
  - nginx
runcmd:
  - echo "{\"servicio\":\"api-disponibilidad\",\"estado\":\"ok\",\"instancia\":\"$(hostname)\"}" > /var/www/html/salud.json
  - systemctl enable --now nginx

Comprobación del balanceo: varias llamadas seguidas deben devolver nombres de instancia distintos.

IP=$(az network public-ip show -g rg-contoso-reservas-pro -n ip-lb-api-disponibilidad-pro --query ipAddress -o tsv)
for i in {1..10}; do curl -s "http://${IP}/salud.json"; echo; done

Si siempre responde la misma instancia, revisa la persistencia de sesión de la regla: por defecto el Load Balancer usa una tupla de cinco campos (IP y puerto de origen y destino, protocolo), y como tu puerto de origen cambia en cada petición, deberías ver reparto. Si configuras persistencia por IP de origen (--load-distribution SourceIP), todas tus peticiones irán a la misma instancia, que es justo lo que no queremos por el motivo del siguiente apartado.

  1. Aplicaciones sin estado: el requisito escondido

El escalado horizontal impone una condición a la aplicación: cualquier instancia debe poder atender cualquier petición. Eso significa que la instancia no puede guardar nada que las demás necesiten.

Los tres estados que rompen el escalado y dónde deben ir en su lugar:

Estado que se guarda mal Síntoma cuando escalas Dónde debe ir
Sesión del usuario en memoria El cliente pierde el carrito de billetes al saltar de instancia Almacén externo: Azure Cache for Redis, o cookie firmada por el cliente
Ficheros subidos en el disco local La tarjeta de embarque generada "desaparece" según qué instancia responda Azure Storage (lección 02-04): las tarjetas van a sttarjetascontosopro
Datos de negocio en ficheros locales Cada instancia tiene una verdad distinta Base de datos (módulo 3): sql-contoso-reservas-pro

La tentación fácil es activar la persistencia de sesión en el balanceador para que cada cliente vaya siempre a la misma instancia. Es un parche con tres efectos secundarios serios: el reparto se desequilibra, la caída de una instancia expulsa a sus usuarios, y al reducir instancias se pierden sesiones activas. Sirve como solución temporal durante una migración, nunca como diseño.

Por eso el orden de este módulo no es casual: primero el cómputo escalable, después el almacenamiento donde vive lo que el cómputo no puede guardar (02-04) y en el módulo 3, la base de datos. La API de Disponibilidad de Contoso se diseña sin estado desde el primer día: lee de la base de datos, escribe las tarjetas en Storage y no guarda nada en local.

  1. Arquitectura resultante y limpieza

graph TD
    CLI["Clientes<br/>(web Contoso Reservas)"] --> LB["Azure Load Balancer Standard<br/>lb-api-disponibilidad-pro<br/>IP pública estática"]
    LB -->|"sonda /salud.json"| P["Grupo de back-end<br/>pool-api-disponibilidad"]
    P --> Z1["Zona 1<br/>instancia api-01"]
    P --> Z2["Zona 2<br/>instancia api-02"]
    AE["Escalado automático<br/>CPU 70% / programado apertura"] -.->|"ajusta 2 a 20"| VMSS["vmss-api-disponibilidad-pro<br/>(Flexible)"]
    VMSS --- Z1
    VMSS --- Z2
    Z1 --> SQL["db-reservas<br/>(módulo 3)"]
    Z2 --> SQL
    Z1 --> ST["sttarjetascontosopro<br/>(lección 02-04)"]
    Z2 --> ST

Limpieza (recuerda que el grupo de producción tiene el bloqueo no-borrar-produccion; en laboratorio trabaja sobre el grupo de desarrollo):

# Borrado individual, en orden inverso al de creación.
az vmss delete --resource-group rg-contoso-reservas-dev --name vmss-api-disponibilidad-dev
az network lb delete --resource-group rg-contoso-reservas-dev --name lb-api-disponibilidad-dev
az network public-ip delete --resource-group rg-contoso-reservas-dev --name ip-lb-api-disponibilidad-dev

# O, en un grupo de laboratorio dedicado, el borrado completo:
# az group delete --name rg-contoso-laboratorio --yes --no-wait

Y una comprobación que ya deberías hacer por reflejo: az disk list --query "[?diskState=='Unattached']" -o table.

Errores Comunes y Consejos

  • Poner el mismo umbral para subir y bajar. Produce el efecto sierra: el sistema añade y quita instancias sin parar. Deja una banda muerta amplia (30 %–70 %).
  • Bajar tan agresivamente como se sube. Reducir de dos en dos con ventana de 5 minutos deja el servicio corto justo cuando el pico rebota. Sube rápido, baja despacio.
  • Confiar solo en el escalado por métrica para un pico conocido. Arrancar instancias tarda minutos; el pico de la apertura llega en segundos. Usa un perfil programado.
  • Confundir conjunto de disponibilidad con zona de disponibilidad. El primero protege del fallo de bastidor dentro de un centro de datos; el segundo, de la caída del centro de datos entero.
  • Olvidar que las zonas se fijan al crear el conjunto de escalado. No se añaden después. Créalo zonal desde el principio.
  • Usar Application Gateway donde basta un Load Balancer (o al revés). Si no necesitas decisiones por URL ni terminación TLS, la capa 4 es más simple y mucho más barata.
  • Sondas que devuelven 200 pase lo que pase. Un punto de salud que no comprueba nada garantiza que el balanceador envíe tráfico a instancias rotas.
  • Escalar horizontalmente una aplicación con estado en memoria. Aparecen errores intermitentes imposibles de reproducir. Saca el estado antes de escalar.
  • Consejo de cuota: el máximo de vCPU por familia y región es una cuota, no un límite físico (lección 01-05). Si tu regla puede llegar a 20 instancias de 4 vCPU, comprueba que tienes 80 vCPU de cuota antes del día de la apertura.
  • Consejo de coste: para los picos, considera instancias de precio esporádico (spot) dentro del conjunto flexible. Son mucho más baratas a cambio de poder ser desalojadas; sirven para capacidad extra, nunca para el mínimo.

Ejercicios

Ejercicio 1: diseñar la política de escalado del pico

Con los datos medidos por Marta Ríos (15 peticiones por segundo de madrugada, 120 en hora punta normal, 1.800 en el pico de apertura), y sabiendo que una instancia Standard_B2s de la API atiende cómodamente unas 100 peticiones por segundo:

  1. ¿Cuántas instancias hacen falta como mínimo en un día normal en hora punta, con margen para perder una?
  2. ¿Cuántas en el pico de apertura?
  3. Define los valores de mínimo, máximo y perfil programado que configurarías.
  4. Explica por qué no basta con la regla por CPU para ese día.

Ejercicio 2: elegir el balanceador

Para cada necesidad de Contoso, indica qué servicio de balanceo usarías y por qué:

  1. Repartir el tráfico del protocolo binario del motor de disponibilidad heredado (TCP 8500) entre tres VM en West Europe.
  2. Enviar /api/* a la API de Disponibilidad y el resto a la web de reservas, dentro de la misma región, con terminación TLS.
  3. Servir la web pública a clientes de Sudamérica con la menor latencia posible y caché de imágenes.
  4. Conmutar a North Europe si West Europe deja de responder, para un servicio que no es HTTP.

Ejercicio 3: montar y demostrar la alta disponibilidad

En un grupo de laboratorio:

  1. Crea un conjunto de escalado flexible con 2 instancias en las zonas 1 y 2, con cloud-init que publique el nombre de la instancia en /salud.json.
  2. Ponlo detrás de un Load Balancer Standard con sonda HTTP a /salud.json.
  3. Demuestra con curl que el tráfico se reparte entre las dos instancias.
  4. Detén una instancia y demuestra que el servicio sigue respondiendo y que la sonda la ha retirado del grupo.

Soluciones

Solución 1:

  1. Hora punta normal: 120 ÷ 100 = 1,2 → 2 instancias, y con margen para perder una (patrón N+1), 3. Como el mínimo también debe cubrir la zona que pueda caer, 2 es el suelo absoluto y 3 lo prudente.
  2. Pico de apertura: 1.800 ÷ 100 = 18 → 18 instancias, más margen N+1 → 20.
  3. Configuración propuesta:
# Perfil normal.
az monitor autoscale create ... --min-count 2 --max-count 20 --count 2

# Perfil programado para la apertura (mínimo alto desde antes de que abra la venta).
az monitor autoscale profile create \
  --name apertura-temporada-verano \
  --min-count 12 --max-count 30 --count 20 \
  --timezone "W. Europe Standard Time" \
  --start 2026-02-12T07:00 --end 2026-02-12T14:00
  1. Porque el escalado por métrica es reactivo: necesita 5 minutos de CPU alta para disparar y varios minutos más para que las instancias arranquen y pasen la sonda. El pico de la apertura llega en menos de un minuto, así que durante los primeros 10 minutos —los de más ventas del año— el servicio estaría saturado. El perfil programado deja la capacidad ya caliente antes de que abra la venta.

Solución 2:

Caso Servicio Motivo
1. TCP 8500 del motor heredado Azure Load Balancer Capa 4: funciona con cualquier protocolo TCP/UDP; los de capa 7 solo entienden HTTP/S
2. /api/* frente al resto, con TLS, en una región Application Gateway Capa 7 regional: enrutamiento por ruta y terminación TLS. Además admite WAF (04-04)
3. Clientes de Sudamérica con caché Azure Front Door Global, con presencia en el borde, terminación TLS cercana al cliente y caché (detalle en 02-06)
4. Conmutación a North Europe sin HTTP Traffic Manager Trabaja a nivel DNS, es independiente del protocolo y admite perfil de prioridad para conmutación por error

Solución 3:

#!/usr/bin/env bash
set -euo pipefail
GRUPO="rg-contoso-laboratorio"
az group create --name "${GRUPO}" --location westeurope \
  --tags entorno=pruebas proyecto=contoso-reservas centro-coste=CC-1042 \
         [email protected] --output none

# 1 y 2: IP, balanceador, sonda, regla y conjunto de escalado.
az network public-ip create -g "${GRUPO}" -n ip-lb-lab --sku Standard --allocation-method Static --output none
az network lb create -g "${GRUPO}" -n lb-lab --sku Standard \
  --public-ip-address ip-lb-lab --frontend-ip-name frontal-publico \
  --backend-pool-name pool-lab --output none
az network lb probe create -g "${GRUPO}" --lb-name lb-lab -n sonda-lab \
  --protocol Http --port 80 --path /salud.json --interval 5 --output none
az network lb rule create -g "${GRUPO}" --lb-name lb-lab -n regla-http \
  --protocol Tcp --frontend-port 80 --backend-port 80 \
  --frontend-ip-name frontal-publico --backend-pool-name pool-lab \
  --probe-name sonda-lab --output none
az vmss create -g "${GRUPO}" -n vmss-lab --orchestration-mode Flexible \
  --zones 1 2 --instance-count 2 --vm-sku Standard_B1s \
  --image Canonical:ubuntu-24_04-lts:server:latest \
  --admin-username azureuser --ssh-key-values ~/.ssh/contoso_motor.pub \
  --custom-data init-api.yaml --lb lb-lab --backend-pool-name pool-lab --output none

# 3. Comprobar el reparto.
IP=$(az network public-ip show -g "${GRUPO}" -n ip-lb-lab --query ipAddress -o tsv)
for i in {1..10}; do curl -s "http://${IP}/salud.json"; echo; done

# 4. Detener una instancia (modo Flexible: son VM normales) y repetir la prueba.
INSTANCIA=$(az vm list -g "${GRUPO}" --query "[0].name" -o tsv)
az vm stop -g "${GRUPO}" -n "${INSTANCIA}"
for i in {1..10}; do curl -s "http://${IP}/salud.json"; echo; done
# Todas las respuestas deben venir ahora de la otra instancia, sin errores.

# Limpieza completa.
az group delete --name "${GRUPO}" --yes --no-wait

Tras detener la instancia, la sonda falla varias veces seguidas y el balanceador la retira del grupo: puedes tardar unos 15-20 segundos en ver el efecto (intervalo de sonda por número de fallos tolerados). Ese retardo es exactamente el tiempo de indisponibilidad parcial que sufrirían algunos clientes en un fallo real, y es el argumento para no poner intervalos de sonda largos.

Conclusión

Ya sabes escalar y dar alta disponibilidad al cómputo en Azure. Distingues el escalado vertical del horizontal y entiendes por qué la nube apuesta por el segundo: elasticidad real, disponibilidad intrínseca y ausencia de techo. Sabes qué es un conjunto de escalado de máquinas virtuales, la diferencia entre orquestación uniforme y flexible, y cómo definir escalado manual, automático por métrica —con umbrales asimétricos y banda muerta para evitar el efecto sierra— y programado, que es la única respuesta razonable a un pico con fecha conocida como la apertura de la temporada de verano de Contoso. Conoces la diferencia entre conjuntos de disponibilidad (dominios de error y actualización dentro de un centro de datos) y zonas de disponibilidad (centros de datos independientes), con su efecto directo en el SLA: 99,9 %, 99,95 % y 99,99 %. Has comparado los cuatro servicios de balanceo con criterios claros y has desplegado un Load Balancer Standard con sonda de estado sobre un conjunto de escalado repartido en dos zonas. Y has interiorizado el requisito escondido de todo esto: la aplicación no puede tener estado local.

Ahora bien, mira lo que ha costado: un conjunto de escalado, un balanceador, una sonda, reglas de autoescalado, y todavía tienes que parchear el sistema operativo de cada instancia, actualizar la imagen, gestionar certificados TLS a mano y montar tú mismo el despliegue sin caídas. Para el motor heredado no hay alternativa. Pero para una aplicación web moderna como Contoso Reservas o para la nueva API de Disponibilidad, Azure ofrece un servicio que hace todo eso por ti.

En la siguiente lección, Azure App Service, verás por qué Contoso publica ahí sus aplicaciones en lugar de mantener VM: planes y niveles con lo que desbloquea cada uno, pilas de tiempo de ejecución, despliegue del código con ZIP y Git, ajustes de aplicación y cadenas de conexión, dominios propios con certificados gestionados, escalado automático sin conjuntos que administrar y, sobre todo, ranuras de despliegue con intercambio y calentamiento previo para publicar versiones nuevas sin que ningún cliente deje de comprar su billete.

Curso de Azure

Módulo 1: Introducción a Azure

Módulo 2: Servicios principales de Azure

Módulo 3: Bases de datos de Azure

Módulo 4: Seguridad en Azure

Módulo 5: Azure DevOps

Módulo 6: Servicios avanzados de Azure

Módulo 7: Monitoreo y gestión

Módulo 8: Gestión y optimización de costos

Módulo 9: Estudios de caso y mejores prácticas

© Copyright 2026. Todos los derechos reservados