En vm-motor-disponibilidad-dev vive el componente más incómodo de Contoso Airlines. El motor de disponibilidad calcula, para un origen, un destino y una fecha, qué plazas quedan libres y a qué tarifa; es un servicio pequeño, sin estado, que la API de Disponibilidad invoca miles de veces al día. Pero está desplegado a mano sobre una máquina virtual que Marta Ríos parchea cada mes, que nadie sabe recrear desde cero y cuya versión de tiempo de ejecución nadie se atreve a tocar porque «funciona». En producción el problema se tapó multiplicando instancias en vmss-api-disponibilidad-pro, lo que no lo resuelve: solo lo multiplica.

Esta lección convierte ese motor en un contenedor: una unidad autocontenida que incluye el código y todo lo que necesita para ejecutarse, que se construye una vez, se guarda con versión en un registro y se ejecuta igual en el portátil de Diego Salas, en el agente del pipeline y en producción. Después lo publicarás en Azure Container Registry y lo llevarás a Azure Container Apps, la opción que da a Contoso la mayor parte del valor de la orquestación sin el coste de operar un clúster.

Contenido

  1. Contenedor frente a máquina virtual
  2. Imagen, capas, contenedor y registro
  3. El Dockerfile del motor de disponibilidad
  4. Construir y probar en local
  5. Azure Container Registry
  6. El panorama de servicios de contenedores de Azure
  7. Azure Container Apps en detalle
  8. Desplegar ca-motor-disponibilidad
  9. Azure Container Instances para tareas puntuales
  10. Errores Comunes y Consejos
  11. Ejercicios
  12. Conclusión

  1. Contenedor frente a máquina virtual

Una máquina virtual virtualiza hardware: cada una lleva su propio sistema operativo completo. Un contenedor virtualiza el sistema operativo: comparte el núcleo del anfitrión y aísla solo el sistema de ficheros, la red y los procesos. La diferencia de peso no es un detalle técnico, es lo que cambia la forma de trabajar.

Máquina virtual Contenedor
Contiene SO completo + aplicación Aplicación + sus dependencias
Tamaño típico 10-30 GB 80-300 MB
Arranque Minutos Segundos o menos
Parcheo del SO Tuyo, mensual, en caliente Reconstruyes la imagen y redespliegas
Densidad por servidor Decenas Cientos
Aislamiento Fuerte (hipervisor) Bueno (núcleo compartido)
«Funciona en mi máquina» Sigue pasando Se acaba: el entorno viaja dentro

El motor de disponibilidad es el candidato perfecto por cuatro razones concretas: no tiene estado (cada petición se resuelve con la base de datos y una caché reconstruible), arranca rápido, su carga es muy irregular —picos al abrir la venta de plazas, casi nada de madrugada— y su dependencia problemática es el tiempo de ejecución, exactamente lo que un contenedor congela. Lo que no migrarías así de alegremente son las bases de datos con estado o el sistema heredado de tripulaciones que exige acceso a hardware específico.

  1. Imagen, capas, contenedor y registro

Cuatro conceptos y la relación entre ellos:

  • Imagen: plantilla inmutable de solo lectura con el sistema de ficheros y los metadatos de arranque. No se ejecuta; es el molde.
  • Capa: cada instrucción del Dockerfile produce una capa apilada sobre la anterior. Las capas se almacenan en caché y se comparten: si diez imágenes parten de la misma base, esa base se descarga una vez.
  • Contenedor: una instancia en ejecución de una imagen, con una capa de escritura efímera encima. Al eliminarlo, esa capa desaparece.
  • Registro: el almacén de imágenes. Docker Hub es el público; acrcontosopro.azurecr.io es el privado de Contoso, que ya conoces del módulo 5 como registro de módulos Bicep.

Que las capas se cacheen tiene una consecuencia práctica enorme: ordena el Dockerfile de lo que menos cambia a lo que más cambia. Si copias el código fuente antes de restaurar las dependencias, cualquier cambio de una línea invalida la caché de la restauración y cada compilación tarda minutos de más.

  1. El Dockerfile del motor de disponibilidad

Un Dockerfile es la receta declarativa de la imagen. Esta es la del motor, con construcción en varias etapas, usuario no root e imagen base pequeña:

# ---------- Etapa 1: compilacion ----------
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS compilacion
WORKDIR /origen

# Primero solo los ficheros de proyecto: cambian poco y la restauracion se cachea
COPY MotorDisponibilidad.sln .
COPY src/MotorDisponibilidad/*.csproj src/MotorDisponibilidad/
RUN dotnet restore

# Ahora si, el codigo fuente completo
COPY . .
RUN dotnet publish src/MotorDisponibilidad/MotorDisponibilidad.csproj \
    -c Release -o /publicado --no-restore

# ---------- Etapa 2: ejecucion ----------
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS final
WORKDIR /app

# Usuario sin privilegios: nunca ejecutes como root
RUN adduser --disabled-password --home /app --gecos "" motor && chown -R motor /app
USER motor

COPY --from=compilacion /publicado .

ENV ASPNETCORE_URLS=http://+:8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "MotorDisponibilidad.dll"]

Línea a línea, lo que importa:

  • FROM ... AS compilacion abre la primera etapa con el SDK completo (unos 800 MB): compiladores, herramientas y todo lo necesario para construir. Nada de esto llegará a producción.
  • COPY de los .csproj antes que del código es la optimización de caché de la que hablaba el apartado anterior. Mientras no cambien las dependencias, dotnet restore se salta.
  • FROM ... AS final abre la segunda etapa partiendo de cero: solo el tiempo de ejecución de ASP.NET sobre Alpine, unos 110 MB. La variante alpine usa una distribución mínima; si tu código depende de bibliotecas nativas de glibc, usa -jammy en su lugar.
  • adduser + USER motor es la línea que más veces falta en los Dockerfile reales. Por defecto un contenedor ejecuta como root, y una vulnerabilidad de la aplicación se convierte en root dentro del contenedor. Defender for Cloud lo marcará; hazlo desde el principio.
  • COPY --from=compilacion trae solo el resultado publicado de la primera etapa. El código fuente, el SDK y las dependencias de compilación se quedan fuera: menos peso y muchísima menos superficie de ataque.
  • ENTRYPOINT define el proceso principal. Cuando ese proceso termina, el contenedor termina.

Junto al Dockerfile va un .dockerignore con bin/, obj/, .git/ y **/appsettings.Development.json. Esa última línea no es cosmética: impide que un fichero de configuración local con credenciales acabe dentro de la imagen.

  1. Construir y probar en local

# Construir, etiquetando con nombre y version
docker build -t motor-disponibilidad:1.0.0 .

# Ejecutar mapeando el puerto 8080 del contenedor al 5080 del portatil
docker run --rm -p 5080:8080 \
  -e ConexionReservas="Server=localhost;Database=reservas-local;..." \
  --name motor-local motor-disponibilidad:1.0.0

# Comprobar el punto de salud, entrar dentro y ver los registros
curl http://localhost:5080/salud
docker exec -it motor-local sh
docker logs motor-local

--rm elimina el contenedor al pararlo, para no acumular restos. -e inyecta configuración por variable de entorno, que es como se configura un contenedor: nunca metas la configuración dentro de la imagen, porque entonces necesitarías una imagen distinta por entorno y perderías la garantía de «construir una vez, desplegar muchas» del módulo 5.

  1. Azure Container Registry

Un registro privado es obligatorio en cuanto la imagen contiene código propio. Contoso ya tiene acrcontosopro:

az acr create \
  --resource-group rg-contoso-reservas-pro \
  --name acrcontosopro \
  --sku Premium --location westeurope \
  --tags entorno=produccion proyecto=contoso-reservas \
         centro-coste=CC-1042 [email protected]
Característica Básico Estándar Premium
Almacenamiento incluido 10 GB 100 GB 500 GB
Rendimiento Bajo Medio Alto
Replicación geográfica No No Sí
Private Link / puntos privados No No Sí
Directivas de retención y confianza de contenido No No Sí
Ámbito recomendado Pruebas Equipos pequeños Producción

Contoso elige Premium por dos motivos que no son de capacidad: el punto privado, para que las imágenes no viajen por Internet, y la replicación geográfica hacia North Europe, para que el plan de recuperación no dependa de una sola región.

Construir en la nube con az acr build

az acr build sube el contexto, construye en Azure y deja la imagen en el registro. No hace falta Docker instalado, lo que resuelve de golpe el problema de los agentes de pipeline:

az acr build \
  --registry acrcontosopro \
  --image motor-disponibilidad:1.0.0 \
  --image motor-disponibilidad:latest \
  --file Dockerfile .

Etiquetado y versionado

La etiqueta latest es una comodidad peligrosa: es mutable, así que dos despliegues «de latest» pueden ser cosas distintas y la reversión deja de ser reproducible. La convención de Contoso: etiquetar siempre con el identificador de la compilación (motor-disponibilidad:$(Build.BuildId)), que es inmutable y rastreable hasta la confirmación exacta, y añadir latest solo como comodidad para el desarrollo local.

Autenticación: identidad administrada, nunca el usuario administrador

ACR trae un admin user deshabilitado por defecto. Déjalo deshabilitado. Es una credencial compartida, no trazable y no rotable en la práctica. Lo correcto es asignar el rol AcrPull a la identidad administrada que consume las imágenes y AcrPush a la conexión de servicio que las publica:

idAcr=$(az acr show --name acrcontosopro --query id -o tsv)

# La identidad de la aplicacion solo puede descargar
az role assignment create \
  --assignee-object-id $(az identity show -g rg-contoso-seguridad-pro \
      -n id-contoso-api-pro --query principalId -o tsv) \
  --assignee-principal-type ServicePrincipal \
  --role AcrPull --scope $idAcr

Vulnerabilidades, replicación y retención

  • Defender for Cloud (04-05) analiza cada imagen al publicarla y de forma continua las que están en ejecución, con su plan de contenedores. Encuentra bases desactualizadas y paquetes vulnerables; su salida es una lista de trabajo real, no un adorno.
  • Replicación geográfica: az acr replication create --registry acrcontosopro --location northeurope. La imagen se descarga desde la réplica más cercana con el mismo nombre de host.
  • Retención: sin política, el registro crece sin freno y se paga por GB. az acr config retention update --registry acrcontosopro --status enabled --days 30 --type UntaggedManifests limpia los manifiestos sin etiqueta. Complétalo con una tarea programada que purgue etiquetas antiguas, protegiendo siempre las de producción.

  1. El panorama de servicios de contenedores de Azure

Esta es la pregunta que todo el mundo hace y que conviene contestar antes de elegir:

Servicio Qué es Escala a cero Complejidad Cuándo elegirlo
Container Instances (ACI) Un contenedor suelto, sin orquestador Manual Mínima Tareas puntuales, trabajos por lotes, desbordamiento
Container Apps (ACA) Plataforma gestionada sobre Kubernetes, sin exponerlo Sí Baja Microservicios y APIs con carga irregular
App Service para contenedores Tu imagen dentro de App Service No Baja Ya usas App Service y solo quieres cambiar el empaquetado
Kubernetes Service (AKS) Kubernetes gestionado, con acceso total Con esfuerzo Alta Necesitas el ecosistema completo y tienes equipo para operarlo

El criterio en una frase: empieza por Container Apps y sube a AKS solo cuando tengas una necesidad concreta que Container Apps no cubra, no por si acaso. Contoso lleva el motor a Container Apps y reservará AKS para la plataforma de operaciones de vuelo (06-02), que sí la tiene.

  1. Azure Container Apps en detalle

Container Apps es Kubernetes por debajo, pero no lo ves: no hay nodos que dimensionar ni versiones de clúster que actualizar.

  • Entorno (cae-contoso-pro): el límite de aislamiento. Todas las aplicaciones de un entorno comparten red virtual y espacio de trabajo de Log Analytics, y se llaman entre ellas por nombre interno.
  • Aplicación: un microservicio, con su imagen, sus recursos y sus reglas de escalado.
  • Revisión: cada cambio de la imagen o de la configuración crea una revisión inmutable. Puedes mantener varias activas a la vez.
  • División del tráfico: reparte porcentajes entre revisiones. Aquí está el despliegue canario, y es la versión de grano fino de las ranuras que usaste en 05-04.

Escalado con KEDA y el escalado a cero

El escalado se define con reglas KEDA, que miden algo real —peticiones por segundo, longitud de una cola, una métrica personalizada— en lugar de solo la CPU:

# Escalar por peticiones concurrentes HTTP
az containerapp update --name ca-motor-disponibilidad -g rg-contoso-reservas-pro \
  --min-replicas 1 --max-replicas 20 \
  --scale-rule-name http-concurrencia --scale-rule-type http \
  --scale-rule-http-concurrency 50

Con --min-replicas 0 la aplicación escala a cero y deja de facturar cuando no hay tráfico: ideal para ca-motor-disponibilidad en desarrollo. El precio es el arranque en frío de unos segundos en la primera petición, inaceptable en la ruta de compra de producción. Por eso Contoso deja min-replicas 1 en producción y 0 en desarrollo.

Red, ingreso, secretos e identidad

  • Red virtual: el entorno se integra en snet-integracion-app (10.20.5.0/24), y desde ahí las aplicaciones alcanzan pe-sql-reservas y pe-kv-contoso sin salir a Internet.
  • Ingreso: --ingress external publica un nombre con certificado TLS gestionado y renovado solo; --ingress internal deja la aplicación accesible solo dentro del entorno, que es lo correcto para el motor, cuyo único cliente es la API de Disponibilidad. Para un dominio propio, az containerapp hostname add más un certificado gestionado.
  • Secretos: se declaran a nivel de aplicación y pueden referenciar kv-contoso-pro, resolviéndose con la identidad administrada. Nada de cadenas de conexión en variables de entorno planas.
  • Identidad administrada: se asigna id-contoso-api-pro y con ella se descarga la imagen de ACR y se accede a db-reservas, sin ninguna clave. Es exactamente el patrón de 04-02.

  1. Desplegar ca-motor-disponibilidad

idIdentidad=$(az identity show -g rg-contoso-seguridad-pro -n id-contoso-api-pro --query id -o tsv)
idSubred=$(az network vnet subnet show -g rg-contoso-red-pro \
  --vnet-name vnet-contoso-pro -n snet-integracion-app --query id -o tsv)

# 1. Entorno, integrado en la red virtual y enlazado a Log Analytics
az containerapp env create \
  --name cae-contoso-pro --resource-group rg-contoso-reservas-pro \
  --location westeurope --infrastructure-subnet-resource-id $idSubred \
  --logs-workspace-id $(az monitor log-analytics workspace show \
      -g rg-contoso-seguridad-pro -n log-contoso-pro --query customerId -o tsv)

# 2. La aplicacion, con identidad administrada e ingreso interno
az containerapp create \
  --name ca-motor-disponibilidad --resource-group rg-contoso-reservas-pro \
  --environment cae-contoso-pro \
  --image acrcontosopro.azurecr.io/motor-disponibilidad:1.0.0 \
  --registry-server acrcontosopro.azurecr.io \
  --registry-identity $idIdentidad --user-assigned $idIdentidad \
  --ingress internal --target-port 8080 \
  --cpu 0.5 --memory 1.0Gi --min-replicas 1 --max-replicas 20 \
  --secrets conexion-reservas=keyvaultref:https://kv-contoso-pro.vault.azure.net/secrets/conexion-reservas,identityref:$idIdentidad \
  --env-vars ConexionReservas=secretref:conexion-reservas \
  --tags entorno=produccion proyecto=contoso-reservas \
         centro-coste=CC-1042 [email protected]

Fíjate en --registry-identity: la descarga de la imagen la autoriza la identidad, no una contraseña. Y en keyvaultref:, que hace que el secreto nunca esté escrito en el recurso, solo la referencia.

Actualizar desde el pipeline de 05-04 es una etapa más, con su aprobación de entorno:

- stage: DesplegarMotor
  jobs:
    - deployment: Motor
      environment: produccion
      strategy:
        runOnce:
          deploy:
            steps:
              - task: AzureCLI@2
                inputs:
                  azureSubscription: sc-contoso-pro
                  scriptType: bash
                  scriptLocation: inlineScript
                  inlineScript: |
                    az containerapp update \
                      --name ca-motor-disponibilidad \
                      --resource-group rg-contoso-reservas-pro \
                      --image acrcontosopro.azurecr.io/motor-disponibilidad:$(Build.BuildId) \
                      --revision-suffix b$(Build.BuildId)
                    # Canario: 10% del trafico a la revision nueva
                    az containerapp ingress traffic set \
                      --name ca-motor-disponibilidad -g rg-contoso-reservas-pro \
                      --revision-weight latest=10 $(revisionAnterior)=90

La conexión de servicio sc-contoso-pro con federación de identidad no lleva secretos, y el sufijo de revisión hace que cada compilación sea identificable y reversible: devolver el 100 % a la revisión anterior es un único comando.

  1. Azure Container Instances para tareas puntuales

ACI ejecuta un contenedor sin orquestador ni escalado, y factura por segundo de CPU y memoria. Encaja donde Container Apps sobra: una migración de datos que se ejecuta una vez, un trabajo por lotes nocturno.

az container create \
  --resource-group rg-contoso-reservas-dev --name aci-migracion-tarifas \
  --image acrcontosopro.azurecr.io/migracion-tarifas:2.1.0 \
  --acr-identity $idIdentidad --restart-policy Never --cpu 2 --memory 4 \
  --tags entorno=desarrollo proyecto=contoso-reservas centro-coste=CC-1042

--restart-policy Never es lo que lo convierte en un trabajo: se ejecuta, termina y no vuelve a arrancar. Elimínalo después con az container delete, porque un contenedor detenido sigue reservando recursos y facturando.

Errores Comunes y Consejos

  • Ejecutar como root. Es el fallo más repetido y el que Defender for Cloud señalará. Añade siempre el usuario sin privilegios.
  • Copiar el código antes de restaurar dependencias. Invalida la caché en cada compilación y multiplica los tiempos por diez.
  • Desplegar latest en producción. Etiqueta mutable: no sabes qué hay corriendo y la reversión no es reproducible. Usa el identificador de compilación.
  • Habilitar el usuario administrador de ACR «solo para probar». Se queda para siempre. Identidad administrada desde el primer día.
  • Meter secretos en la imagen. Quedan en las capas y cualquiera con acceso al registro los extrae con docker history. Van en Key Vault.
  • No poner límites de CPU y memoria, o ponerlos al azar. En Container Apps el par CPU/memoria tiene combinaciones válidas concretas (0.5 vCPU con 1 Gi, 1 vCPU con 2 Gi); comprueba antes de desplegar.
  • Consejo: define /salud como sonda de disponibilidad y de estado. Sin ellas, la plataforma manda tráfico a réplicas que aún no están listas. Y en rg-contoso-reservas-dev, --min-replicas 0: una aplicación de desarrollo sin tráfico debe costar cero.
  • Consejo: no publiques la imagen desde el portátil. Si solo el pipeline tiene AcrPush, lo que hay en el registro es siempre trazable a una confirmación.

Ejercicios

Ejercicio 1. Diego ha escrito este Dockerfile para la API de Disponibilidad:

FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /app
COPY . .
RUN dotnet restore && dotnet publish -c Release -o /app/salida
ENV ClaveApiPagos=k7Xq92mfLp
CMD ["dotnet", "/app/salida/Api.dll"]
  1. Enumera cuatro problemas.
  2. Reescríbelo aplicando las buenas prácticas de la lección.
  3. ¿Por qué eliminar la línea ENV de una versión posterior no resuelve la filtración?

Ejercicio 2. Contoso quiere desplegar el motor en desarrollo con el mínimo coste posible, sabiendo que se usa a ráfagas durante la jornada laboral y nada por la noche.

  1. Escribe el az containerapp create para ca-motor-disponibilidad-dev en rg-contoso-reservas-dev, con las etiquetas del proyecto secundario «Contoso Millas».
  2. Justifica las réplicas mínima y máxima y explica qué contrapartida aceptas.
  3. ¿Qué regla de escalado KEDA usarías si el motor se alimentara de una cola en lugar de HTTP?

Ejercicio 3. Elige el servicio para cada caso y justifícalo en una frase: (a) un proceso que convierte a PDF los informes de puntualidad, se ejecuta a las 3:00 y tarda 20 minutos; (b) el nuevo servicio de recomendación de asientos, con tráfico impredecible y necesidad de canario; (c) app-contoso-reservas-pro, que ya funciona en App Service y solo quiere pasar a imagen; (d) la plataforma de operaciones de vuelo, con doce microservicios, mallas de servicio y operadores propios.

Soluciones

Solución 1:

  1. (a) Imagen final basada en el SDK: unos 800 MB frente a 110 MB, con compiladores y código fuente incluidos en producción. (b) Ejecuta como root. (c) Un secreto incrustado con ENV. (d) COPY . . antes de restore destruye la caché de capas, y además sin .dockerignore se copian bin/, obj/ y .git/.
  2. La solución es la estructura del apartado 3: etapa compilacion con el SDK, copia de los .csproj, dotnet restore, copia del resto y publish; etapa final sobre aspnet:8.0-alpine, creación de usuario, USER, COPY --from=compilacion y ENTRYPOINT. La clave va fuera: secreto de Container Apps con keyvaultref: a kv-contoso-pro.
  3. Porque las imágenes son capas apiladas e inmutables: la capa que contiene la clave sigue existiendo en el registro dentro de todas las etiquetas anteriores, y se lee con docker history. Hay que purgar esas etiquetas del registro y rotar la clave, dándola por comprometida.

Solución 2:

  1. Mismo comando del apartado 8 sustituyendo el grupo por rg-contoso-reservas-dev, el entorno por uno de desarrollo, la imagen por la etiqueta correspondiente, --min-replicas 0 --max-replicas 3, --cpu 0.25 --memory 0.5Gi, la identidad y el almacén de desarrollo kv-contoso-dev, y las etiquetas entorno=desarrollo proyecto=contoso-millas centro-coste=CC-2077 [email protected].
  2. Mínimo 0 porque por la noche no hay tráfico y una aplicación de desarrollo parada debe costar cero; máximo 3 porque las ráfagas son de pruebas, no de producción, y un techo bajo evita que un bucle infinito en una prueba dispare la factura. La contrapartida es el arranque en frío: la primera petición tras un rato de inactividad tardará unos segundos. En desarrollo es asumible; en producción no lo sería.
  3. Una regla de tipo azure-queue apuntando a la cola de stoperacionescontosopro, con una longitud objetivo por réplica (por ejemplo 20 mensajes). Es el escalador que hace de verdad interesante a KEDA: escala por trabajo pendiente, no por CPU, que es una señal que llega tarde.

Solución 3: (a) Container Instances: tarea que empieza, termina y no necesita orquestación ni ingreso. (b) Container Apps: escalado por tráfico, escala a cero fuera de hora punta y división de tráfico entre revisiones lista para el canario. (c) App Service para contenedores: conserva ranuras, escalado y configuración conocidos cambiando solo el empaquetado, con coste de migración casi nulo. (d) AKS: solo ahí tienes operadores, mallas de servicio y control completo del plano de datos, y el equipo lo justifica.

Conclusión

Has convertido el problema heredado de Contoso en una unidad moderna. Distingues contenedor de máquina virtual y sabes por qué el motor de disponibilidad —sin estado, de arranque rápido, con carga irregular y atado a su tiempo de ejecución— era el candidato ideal. Entiendes imagen, capa, contenedor y registro, y por qué el orden de las instrucciones del Dockerfile decide el tiempo de tus compilaciones. Has escrito ese Dockerfile con varias etapas, usuario no root e imagen base pequeña, lo has probado en local y has aprendido que la configuración entra por variables de entorno para que la imagen sea la misma en todos los entornos.

En Azure Container Registry sabes elegir nivel, construir sin Docker local con az acr build, versionar con el identificador de compilación en lugar de latest, autenticar con identidad administrada dejando el usuario administrador deshabilitado, analizar vulnerabilidades con Defender for Cloud y controlar el crecimiento con replicación y retención. Tienes el mapa de los cuatro servicios de contenedores y el criterio para elegir: empezar por lo simple y subir solo con motivo. Y has desplegado ca-motor-disponibilidad en Container Apps con su entorno cae-contoso-pro integrado en snet-integracion-app, ingreso interno, secretos por referencia a kv-contoso-pro, identidad administrada, escalado KEDA y revisiones con división de tráfico actualizadas desde el pipeline del módulo 5. La máquina virtual vm-motor-disponibilidad-dev puede apagarse.

Container Apps cubre el caso de Contoso con muy poco esfuerzo, y ahí está su gracia. Pero tiene un techo: cuando necesitas controlar la programación de los pods, instalar operadores, aplicar mallas de servicio, definir políticas de red finas o llevar cargas con requisitos de hardware concretos, la abstracción se te queda pequeña. Ese es el punto donde el equipo de operaciones de vuelo de Contoso está ahora mismo. En la lección siguiente, Azure Kubernetes Service, bajarás una capa: verás qué gestiona AKS y qué sigue siendo tuyo, montarás aks-contoso-operaciones y aprenderás lo imprescindible de Kubernetes para operarlo con criterio, incluyendo lo que casi nadie cuenta al principio, que es cuánto cuesta de verdad y cómo evitar que se dispare.

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