Share via


Implementación y escalado de una aplicación de ASP.NET Core en Azure Container Apps

Las aplicaciones implementadas en Azure que experimentan una alta demanda intermitente se benefician de la escalabilidad para satisfacer la demanda. Las aplicaciones escalables se pueden escalar horizontalmente para garantizar la capacidad durante los picos de carga de trabajo y, después, reducir verticalmente automáticamente cuando los picos disminuyan, lo que puede reducir los costos. El escalado horizontal consiste en agregar nuevas instancias de un recurso, como máquinas virtuales o réplicas de base de datos. En este artículo se muestra cómo implementar una aplicación de ASP.NET Core con escalado horizontal en aplicaciones de contenedor de Azure completando las tareas siguientes:

  1. Configuración del proyecto de ejemplo
  2. Implementar la aplicación en Azure Container Apps
  3. Escalar y solucionar problemas de la aplicación
  4. Crear los servicios de Azure
  5. Conectar los servicios de Azure
  6. Configurar y volver a implementar la aplicación

En este artículo se usa Razor Pages, pero la mayor parte se aplica a otras aplicaciones de ASP.NET Core.

En algunos casos, las aplicaciones básicas de ASP.NET Core se pueden escalar sin consideraciones especiales. Pero las aplicaciones que usan determinadas características de marco o patrones arquitectónicos necesitan configuraciones adicionales, incluidas las siguientes:

  • Envíos seguros de formularios: las aplicaciones de Razor Pages, MVC y Web API suelen depender de envíos de formularios. De manera predeterminada, estas aplicaciones usan tokens de falsificación entre sitios y servicios de protección de datos internos para proteger las solicitudes. Cuando se implementan en la nube, estas aplicaciones se deben configurar para administrar los problemas del servicio de protección de datos en una ubicación centralizada y segura.

  • SignalR circuitos: las aplicaciones Blazor Server deben usar un servicio de Azure SignalR centralizado para escalarse de forma segura. Estos servicios también usan los servicios de protección de datos mencionados anteriormente.

  • Almacenamiento en caché centralizado o servicios de administración de estado: las aplicaciones escalables pueden usar Azure Cache for Redis para proporcionar almacenamiento en caché distribuido. El almacenamiento de Azure puede ser necesario para almacenar el estado de los marcos, como Microsoft Orleans, que puede ayudar a escribir aplicaciones que administran el estado en muchas instancias de aplicación diferentes.

En los pasos de este artículo se muestra cómo abordar correctamente los problemas anteriores mediante la implementación de una aplicación escalable en Azure Container Apps. La mayoría de los conceptos de este tutorial también se aplican al escalar instancias de Azure App Service.

Configuración del proyecto de ejemplo

Use la aplicación de ejemplo GitHub Explorer para seguir este tutorial. Clone la aplicación desde GitHub mediante el siguiente comando:

git clone "https://github.com/dotnet/AspNetCore.Docs.Samples.git"

Navegue hasta la carpeta /tutorials/scalable-razor-apps/start y abra el archivo ScalableRazor.csproj.

En la aplicación de ejemplo se usa un formulario de búsqueda para examinar los repositorios de GitHub por nombre. El formulario se basa en los servicios integrados de protección de datos de ASP.NET Core para controlar los problemas de antifalsificación. De manera predeterminada, cuando la aplicación se escala horizontalmente en Container Apps, el servicio de protección de datos inicia una excepción.

Prueba de la aplicación

  1. Inicie la aplicación en Visual Studio. El proyecto incluye un archivo de Docker, lo que significa que se puede seleccionar una flecha situada junto al botón Ejecutar para iniciar la aplicación mediante una configuración de Docker Desktop o el servidor web local de ASP.NET Core estándar.

Use el formulario de búsqueda para buscar repositorios de GitHub por nombre.

A screenshot showing the GitHub Explorer app.

Implementación de la aplicación en Azure Container Apps

Para implementar la aplicación en Azure Container Apps se usa Visual Studio. Las aplicaciones de contenedor proporcionan un servicio administrado diseñado para simplificar el hospedaje de aplicaciones y microservicios en contenedores.

Nota

Muchos de los recursos creados para la aplicación necesitan una ubicación. Para esta aplicación, la ubicación no es importante. Una aplicación real tendría que seleccionar una ubicación más cercana a los clientes. Es posible que quiera seleccionar una ubicación cercana a su situación.

  1. En el Explorador de soluciones de Visual Studio, haga clic con el botón derecho en el nodo del proyecto de nivel superior y seleccione Publicar.

  2. En el cuadro de diálogo de publicación, seleccione Azure como destino de implementación y, después, seleccione Siguiente.

  3. Para el destino específico, seleccione Azure Container Apps (Linux) y después Siguiente.

  4. Cree una aplicación de contenedor en la que realizar la implementación. Seleccione el icono + de color verde para abrir un cuadro de diálogo nuevo y escriba los valores siguientes:

    A screenshot showing Visual Studio deployment.

    • Nombre de la aplicación de contenedor: deje el valor predeterminado o escriba un nombre.
    • Nombre de la suscripción: seleccione la suscripción en la que se va a realizar la implementación.
    • Grupo de recursos: seleccione Nuevo y cree un grupo de recursos denominado msdocs-scalable-razor.
    • Entorno de aplicaciones de contenedor: seleccione Nuevo para abrir el cuadro de diálogo de entorno de aplicaciones de contenedor y escriba los valores siguientes:
      • Nombre del entorno: mantenga el valor predeterminado.
      • Ubicación: seleccione una ubicación cerca de usted.
      • Área de trabajo de Azure Log Analytics: seleccione Nuevo para abrir el cuadro de diálogo Área de trabajo de Log Analytics.
        • Nombre: deje el valor predeterminado.
        • Ubicación: seleccione una ubicación cercana a usted y, después, seleccione Aceptar para cerrar el cuadro de diálogo.
      • Seleccione Aceptar para cerrar el cuadro de diálogo del entorno de aplicaciones de contenedor.
    • Seleccione Crear para cerrar el cuadro de diálogo de aplicaciones de contenedor original. Visual Studio crea el recurso de aplicación de contenedor en Azure.
  5. Una vez que se crea el recurso, asegúrese de que está seleccionado en la lista de aplicaciones de contenedor y, después, seleccione Siguiente.

  6. Tendrá que crear una instancia de Azure Container Registry para almacenar el artefacto de imagen publicado para la aplicación. Seleccione el icono + de color verde en la pantalla del registro de contenedor.

    A screenshot showing how to create a new container registry.

  7. Deje los valores predeterminados y, después, seleccione Crear.

    A screenshot showing the values for a new container registry.

  8. Una vez que se crea el registro de contenedor, asegúrese de que está seleccionado y, después, seleccione Finalizar para cerrar el flujo de trabajo del cuadro de diálogo y mostrar un resumen del perfil de publicación.

    Si Visual Studio le pide que habilite el usuario administrador para acceder al contenedor de Docker publicado, seleccione .

  9. Seleccione Publicar en la esquina superior derecha del resumen del perfil de publicación para implementar la aplicación en Azure.

Cuando finalice la implementación, Visual Studio inicia el explorador para mostrar la aplicación hospedada. Busque Microsoft en el campo de formulario; se muestra una lista de repositorios.

Escala y solución de problemas de la aplicación

Actualmente la aplicación funciona sin problemas, pero le gustaría escalarla en más instancias para anticiparse a grandes volúmenes de tráfico.

  1. En Azure Portal, busque la aplicación de contenedor razorscaling-app-**** en la barra de búsqueda superior y selecciónela en los resultados.
  2. En la página de información general, seleccione Escalar en el panel de navegación de la izquierda y, después, seleccione + Editar e implementar.
  3. En la página de revisiones, cambie a la pestaña Escala.
  4. Establezca las instancias mínimas y máximas en 4 y, después, seleccione Crear. Este cambio de configuración garantiza que la aplicación se escala horizontalmente entre cuatro instancias.

Vuelva a la aplicación. Cuando se carga la página, al principio parece que todo funciona correctamente. Pero cuando se escribe un término de búsqueda y se envía, puede producirse un error. Si no se muestra un error, envíe el formulario varias veces más.

Solución del error

El motivo de los errores en las solicitudes de búsqueda no es evidente inmediatamente. Las herramientas del explorador indican que se ha devuelto una respuesta 400 Solicitud incorrecta. Pero puede usar las características de registro de las aplicaciones de contenedor para diagnosticar errores en el entorno.

  1. En la página de información general de la aplicación de contenedor, seleccione Registros en el panel de navegación de la izquierda.

  2. En la página Registros, cierre el elemento emergente que se abre y vaya a la pestaña Tablas.

  3. Expanda el elemento Registros personalizados para mostrar el nodo ContainerAppConsoleLogs_CL. Esta tabla contiene varios registros de la aplicación de contenedor que se pueden consultar para solucionar problemas.

    A screenshot showing the container app logs.

  4. En el editor de consultas, redacte una consulta básica para buscar excepciones recientes en la tabla Registros de ContainerAppConsoleLogs_CL, como el siguiente script:

    ContainerAppConsoleLogs_CL
    | where Log_s contains "exception"
    | sort by TimeGenerated desc
    | limit 500
    | project ContainerAppName_s, Log_s
    

    La consulta anterior busca en la tabla ContainerAppConsoleLogs_CL filas que contengan la palabra excepción. Los resultados se ordenan por la hora generada, se limitan a 500 y solo incluyen las columnas ContainerAppName_s y Log_s para facilitar la lectura de los resultados.

  5. Seleccione Ejecutar para mostrar una lista de resultados. Lea los registros y observe que la mayoría de ellos están relacionados con tokens antifalsificación y criptografía.

    A screenshot showing the logs query.

    Importante

    Los errores de la aplicación se deben a los servicios de protección de datos de .NET. Cuando se ejecutan varias instancias de la aplicación, no hay ninguna garantía de que la solicitud HTTP POST para enviar el formulario se enrute al mismo contenedor que ha cargado inicialmente la página desde la solicitud HTTP GET. Si las solicitudes se controlan mediante instancias diferentes, los tokens antifalsificación no se controlan correctamente y se produce una excepción.

    En los pasos siguientes, este problema se resuelve mediante la centralización de las claves de protección de datos en un servicio de almacenamiento de Azure y su protección con Key Vault.

Creación de los servicios de Azure

Para resolver los errores anteriores, se crean los siguientes servicios y se conectan a la aplicación:

  • Cuenta de Azure Storage: controla el almacenamiento de datos para los Servicios de protección de datos. Proporciona una ubicación centralizada para almacenar los datos de clave a medida que se escala la aplicación. Las cuentas de almacenamiento también se pueden usar para guardar documentos, datos de cola, recursos compartidos de archivos y casi cualquier tipo de datos de blob.
  • Azure Key Vault: este servicio almacena secretos para una aplicación y se usa para ayudar a administrar los problemas de cifrado de los servicios de protección de datos.

Creación del servicio de cuenta de almacenamiento

  1. En la barra de búsqueda de Azure Portal, escriba Storage accounts y seleccione el resultado coincidente.
  2. En la página de lista de cuentas de almacenamiento, seleccione + Crear.
  3. En la pestaña Datos básicos, escriba los valores siguientes:
    • Suscripción: seleccione la misma suscripción que haya elegido para la aplicación de contenedor.
    • Grupo de recursos: seleccione el grupo de recursos msdocs-scalable-razor que ha creado antes.
    • Nombre de la cuenta de almacenamiento: asigne el nombre scalablerazorstorageXXXX a la cuenta, donde las X son números aleatorios de su elección. Este nombre debe ser único en Azure.
    • Región: seleccione la misma región que haya seleccionado antes.
  4. Deje el resto de los valores predeterminados y seleccione Revisar. Una vez que Azure valide las entradas, seleccione Crear.

Azure aprovisiona la nueva cuenta de almacenamiento. Cuando se complete la tarea, elija Ir al recurso para ver el nuevo servicio.

Creación del contenedor de almacenamiento

Cree un contenedor para almacenar las claves de protección de datos de la aplicación.

  1. En la página de información general de la nueva cuenta de almacenamiento, seleccione Explorador de almacenamiento en el panel de navegación de la izquierda.
  2. Seleccione Contenedores de blobs.
  3. Seleccione + Agregar contenedor para abrir el menú flotante Nuevo contenedor.
  4. Escriba el nombre scalablerazorkeys, deje el resto de la configuración en sus valores predeterminados y, después, seleccione Crear.

Los nuevos contenedores aparecen en la lista de páginas.

Creación del servicio de almacén de claves

Cree un almacén de claves para almacenar las claves que protegen los datos en el contenedor de almacenamiento de blobs.

  1. En la barra de búsqueda de Azure Portal, escriba Key Vault y seleccione el resultado coincidente.
  2. En la página de lista de almacén de claves, seleccione + Crear.
  3. En la pestaña Datos básicos, escriba los valores siguientes:
    • Suscripción: seleccione la misma suscripción que ha seleccionado antes.
    • Grupo de recursos: seleccione el grupo de recursos msdocs-scalable-razor que ha creado antes.
    • Nombre del almacén de claves: escriba el nombre scalablerazorvaultXXXX.
    • Región: seleccione una región cercana a su ubicación.
  4. Deje el resto de la configuración con sus valores predeterminados y, luego, seleccione Revisar y crear. Espere a que Azure valide la configuración y, después, seleccione Crear.

Azure aprovisiona el nuevo almacén de claves. Cuando se complete la tarea, seleccione Ir al recurso para ver el nuevo servicio.

Creación de la clave

Cree una clave secreta para proteger los datos de la cuenta de almacenamiento de blobs.

  1. En la página de información general principal del almacén de claves, seleccione Claves en el panel de navegación de la izquierda.
  2. En la página Crear una clave, seleccione + Generar o importar para abrir el menú flotante Crear una clave.
  3. Escriba razorkey en el campo Nombre. Deje el resto de las opciones con sus valores predeterminados y, después, seleccione Crear. Aparece una nueva clave en la página de lista de claves.

Conexión de los servicios de Azure

La aplicación de contenedor necesita una conexión segura a la cuenta de almacenamiento y a los servicios del almacén de claves para resolver los errores de protección de datos y escalarse correctamente. Los nuevos servicios se conectan de manera conjunta mediante los pasos siguientes:

Importante

Las asignaciones de roles de seguridad mediante el conector de servicio y otras herramientas suelen tardar uno o dos minutos en propagarse y, en algunos casos poco frecuentes, hasta ocho minutos.

Conexión de la cuenta de almacenamiento

  1. En Azure Portal, navegue a la página de información general de la aplicación de contenedor.
  2. En el panel de navegación de la izquierda, seleccione Conector de servicio.
  3. En la página Conector de servicio, elija + Crear para abrir el panel flotante Conexión de creación y escriba los valores siguientes:
    • Contenedor: seleccione la aplicación de contenedor que ha creado antes.
    • Tipo de servicio: elija Blob de almacenamiento.
    • Suscripción: seleccione la suscripción que ha usado antes.
    • Nombre de conexión: deje el valor predeterminado.
    • Cuenta de almacenamiento: seleccione la cuenta de almacenamiento que ha creado antes.
    • Tipo de cliente: seleccione .NET.
  4. Seleccione Siguiente: Autenticación para avanzar al paso siguiente.
  5. Seleccione Identidad administrada asignada por el sistema y elija Siguiente: Redes.
  6. Deje las opciones de red predeterminadas seleccionadas y, después, seleccione Revisar y crear.
  7. Una vez que Azure valide la configuración, seleccione Crear.

El conector de servicio habilita una identidad administrada asignada por el sistema en la aplicación de contenedor. También asigna un rol de Colaborador de datos de Storage Blob a la identidad para que pueda realizar operaciones de datos en los contenedores de almacenamiento.

Conexión del almacén de claves

  1. En Azure Portal, navegue a la página de información general de la aplicación de contenedor.
  2. En el panel de navegación de la izquierda, seleccione Conector de servicio.
  3. En la página Conector de servicio, elija + Crear para abrir el panel flotante Conexión de creación y escriba los valores siguientes:
    • Contenedor: seleccione la aplicación de contenedor que ha creado antes.
    • Tipo de servicio: elija Key Vault.
    • Suscripción: seleccione la suscripción que ha usado antes.
    • Nombre de conexión: deje el valor predeterminado.
    • Almacén de claves: seleccione el almacén de claves que ha creado antes.
    • Tipo de cliente: seleccione .NET.
  4. Seleccione Siguiente: Autenticación para avanzar al paso siguiente.
  5. Seleccione Identidad administrada asignada por el sistema y elija Siguiente: Redes.
  6. Deje las opciones de red predeterminadas seleccionadas y, después, seleccione Revisar y crear.
  7. Una vez que Azure valide la configuración, seleccione Crear.

El conector de servicio asigna un rol a la identidad para que pueda realizar operaciones de datos en las claves del almacén de claves.

Configuración y nueva implementación de la aplicación

Se han creado los recursos de Azure necesarios. En esta sección, el código de la aplicación está configurado para usar los nuevos recursos.

  1. Instale los siguientes paquetes NuGet:

    • Azure.Identity: proporciona clases para trabajar con los servicios de administración de identidades y acceso de Azure.
    • Microsoft.Extensions.Azure: proporciona métodos de extensión útiles para realizar configuraciones básicas de Azure.
    • Azure.Extensions.AspNetCore.DataProtection.Blobs: permite almacenar claves DataProtection de ASP.NET Core en Azure Blob Storage para poder compartirlas entre varias instancias de una aplicación web.
    • Azure.Extensions.AspNetCore.DataProtection.Keys: habilita la protección de claves en reposo mediante la característica Cifrado y ajuste de claves de Azure Key Vault.
    dotnet add package Azure.Identity
    dotnet add package Microsoft.Extensions.Azure
    dotnet add package Azure.Extensions.AspNetCore.DataProtection.Blobs
    dotnet add package Azure.Extensions.AspNetCore.DataProtection.Keys
    
  2. Actualice Program.cs con el siguiente código resaltado:

    using Azure.Identity;
    using Microsoft.AspNetCore.DataProtection;
    using Microsoft.Extensions.Azure;
    
    var builder = WebApplication.CreateBuilder(args);
    var BlobStorageUri = builder.Configuration["AzureURIs:BlobStorage"];
    var KeyVaultURI = builder.Configuration["AzureURIs:KeyVault"];
    
    builder.Services.AddRazorPages();
    builder.Services.AddHttpClient();
    builder.Services.AddServerSideBlazor();
    
    builder.Services.AddAzureClientsCore();
    
    builder.Services.AddDataProtection()
                    .PersistKeysToAzureBlobStorage(new Uri(BlobStorageUri),
                                                    new DefaultAzureCredential())
                    .ProtectKeysWithAzureKeyVault(new Uri(KeyVaultURI),
                                                    new DefaultAzureCredential());
    var app = builder.Build();
    
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    

Los cambios anteriores permiten a la aplicación administrar la protección de datos mediante una arquitectura centralizada y escalable. DefaultAzureCredential descubre las configuraciones de identidad administrada habilitadas anteriormente cuando la aplicación se vuelve a implementar.

Actualice los marcadores de posición de la sección AzureURIs del archivo appsettings.json para incluir lo siguiente:

  1. Reemplace el marcador de posición <storage-account-name> por el nombre de la cuenta de almacenamiento scalablerazorstorageXXXX.

  2. Reemplace el marcador de posición <container-name> por el nombre de la cuenta del contenedor de almacenamiento scalablerazorkeys.

  3. Reemplace el marcador de posición <key-vault-name> por el nombre del almacén de claves scalablerazorvaultXXXX.

  4. Reemplace el marcador de posición <key-name> en el URI del almacén de claves por el nombre razorkey que ha creado antes.

    {
      "GitHubURL": "https://api.github.com",
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*",
      "AzureURIs": {
        "BlobStorage": "https://<storage-account-name>.blob.core.windows.net/<container-name>/keys.xml",
        "KeyVault": "https://<key-vault-name>.vault.azure.net/keys/<key-name>/"
      }
    }
    

Reimplementación de la aplicación

Ahora la aplicación está configurada correctamente para usar los servicios de Azure creados anteriormente. Vuelva a implementar la aplicación para que se apliquen los cambios de código.

  1. Haga clic con el botón derecho en el node l proyecto en el Explorador de soluciones y seleccione Publicar.
  2. En la vista de resumen del perfil de publicación, seleccione el botón Publicar en la esquina superior derecha.

Visual Studio vuelve a implementar la aplicación en el entorno de aplicaciones de contenedor creado anteriormente. Cuando finalicen los procesos, el explorador se inicia en la página principal de la aplicación.

Vuelva a probar la aplicación mediante la búsqueda de Microsoft en el campo de búsqueda. Ahora la página debería volver a cargarse con los resultados correctos cada vez que se envíe.

Configuración de roles para el desarrollo local

El código y la configuración existentes de la aplicación también pueden funcionar mientras se ejecutan localmente durante el desarrollo. La clase DefaultAzureCredential configurada anteriormente puede tomar las credenciales del entorno local para autenticarse en los servicios de Azure. Para que la autenticación funcione, tendrá que asignar a su cuenta los mismos roles que se han asignado a la identidad administrada de la aplicación. Debe ser la misma cuenta que usa para iniciar sesión en Visual Studio o en la CLI de Azure.

Inicio de sesión en el entorno de desarrollo local

Tendrá que iniciar sesión en la CLI de Azure, Visual Studio o Azure PowerShell para que DefaultAzureCredential tome las credenciales.

az login

Asignación de roles a la cuenta de desarrollador

  1. En Azure Portal, navegue hasta la cuenta de almacenamiento scalablerazor**** que ha creado antes.
  2. Seleccione Control de acceso (IAM) en el panel de navegación de la izquierda.
  3. Seleccione + Agregar y después Agregar asignación de roles en el menú desplegable.
  4. En la página Agregar asignación de roles, busque Storage blob data contributor, seleccione el resultado coincidente y, a después, seleccione Siguiente.
  5. Asegúrese de que está seleccionado Usuario, grupo o entidad de servicio y, después, seleccione + Seleccionar miembros.
  6. En el control flotante Seleccionar miembros, busque la cuenta usuario@dominio propia y selecciónela en los resultados.
  7. Seleccione Siguiente y, después Revisar y asignar. Una vez que Azure valide la configuración, vuelva a seleccionar Revisar y asignar.

Como se ha indicado antes, es posible que los permisos de asignación de roles tarden uno o dos minutos en propagarse, o en raras ocasiones hasta ocho minutos.

Repita los pasos anteriores para asignar un rol a la cuenta para que pueda acceder al servicio y el secreto del almacén de claves.

  1. En Azure Portal, navegue hasta el almacén de claves razorscalingkeys que ha creado antes.
  2. Seleccione Control de acceso (IAM) en el panel de navegación de la izquierda.
  3. Seleccione + Agregar y después Agregar asignación de roles en el menú desplegable.
  4. En la página Agregar asignación de roles, busque Key Vault Crypto Service Encryption User, seleccione el resultado coincidente y, a después, seleccione Siguiente.
  5. Asegúrese de que está seleccionado Usuario, grupo o entidad de servicio y, después, seleccione + Seleccionar miembros.
  6. En el control flotante Seleccionar miembros, busque la cuenta usuario@dominio propia y selecciónela en los resultados.
  7. Seleccione Siguiente y, después Revisar y asignar. Una vez que Azure valide la configuración, vuelva a seleccionar Revisar y asignar.

Es posible que tenga que esperar de nuevo a que esta asignación de roles se propague.

Después, puede volver a Visual Studio y ejecutar la aplicación localmente. El código debe seguir funcionando según lo previsto. DefaultAzureCredential usa las credenciales existentes de Visual Studio o la CLI de Azure.

Patrones de aplicación web confiable

Consulte El patrón de aplicación web confiable para .NETen los vídeos de YouTube y el artículo para obtener instrucciones sobre cómo crear una aplicación moderna, confiable, que se puede probar, rentable y escalable de ASP.NET Core, ya sea desde cero o refactorizando una aplicación existente.