Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial, aprenderá a implementar una aplicación de carro de compra de ejemplo Orleans en Azure Container Apps. En este tutorial se expande la funcionalidad de la Orleans aplicación de carro de la compra de ejemplo, introducida en Implementación Orleans en Azure App Service. La aplicación de ejemplo agrega la autenticación de negocio a consumidor (B2C) de Azure Active Directory (AAD) e implementa en Azure Container Apps.
Aprenda a implementar con Acciones de GitHub, las CLIs de .NET y Azure y Azure Bicep. Además, aprenda a configurar la entrada HTTP de la aplicación contenedora.
En este tutorial, aprenderá a:
- Implementación de una Orleans aplicación en Azure Container Apps
- Automatización de la implementación mediante Acciones de GitHub y Azure Bicep
- Configuración de la entrada HTTP
Implementación con .NET Aspire (recomendado)
Si la aplicación Orleans usa .NET Aspire, puede implementar en Azure Container Apps con un flujo de trabajo simplificado mediante la CLI de Aspire (aspire). La Aspire CLI aprovisiona automáticamente toda la infraestructura necesaria y controla la implementación.
Aspire requisitos previos de implementación
- Aspire CLI instalada
- La CLI de Azure instalada
- Carga de trabajo de .NETAspire
- Una suscripción de Azure con permisos para crear recursos
- Docker Desktop o Podman en ejecución (para compilar imágenes de contenedor)
Instalación de la Aspire CLI
irm https://aspire.dev/install.ps1 | iex
Habilitación del comando deploy
El aspire deploy comando está actualmente en versión preliminar y debe estar habilitado explícitamente:
$env:DOTNET_ASPIRE_ENABLE_DEPLOY_COMMAND="true"
Autenticación e implementación
Inicie sesión en Azure:
az loginImplemente la aplicación:
Vaya al directorio del proyecto appHost y ejecute:
aspire deployEste único comando realiza los pasos siguientes:
- Valida la configuración
- Aprovisiona recursos de Azure (entorno de Container Apps, Container Registry, almacenamiento, etc.)
- Compila y sube imágenes de contenedor
- Implementa la aplicación
Especificar parámetros de implementación
Puede proporcionar parámetros de implementación en línea:
aspire deploy --deployment-param location=eastus --deployment-param environment=production
O bien, use un archivo de parámetros para implementaciones complejas:
{
"location": "eastus",
"environment": "production",
"resourceGroupName": "my-orleans-app-rg"
}
aspire deploy --deployment-params-file deployment-params.json
Qué aprovisiona Aspire automáticamente
Al implementar una aplicación de OrleansAspire en Azure Container Apps, aspire deploy aprovisiona automáticamente:
- Entorno de Azure Container Apps : el entorno de hospedaje de los contenedores.
- Azure Container Registry (ACR): para almacenar las imágenes de contenedor.
- Redis Cache - Si el Orleans clúster utiliza Redis para la agrupación, el almacenamiento de granulados o los recordatorios.
- Azure Storage : si el Orleans clúster usa Azure Storage para la agrupación en clústeres, el almacenamiento específico, los recordatorios o el streaming.
- Azure Monitor / Application Insights: para observabilidad y trazado distribuido.
- Identidades administradas : para la autenticación segura sin contraseña entre servicios.
Sugerencia
Para actualizar la aplicación después de que el código cambie, simplemente ejecute aspire deploy de nuevo. La CLI controla las actualizaciones incrementales de forma eficaz.
Para obtener instrucciones completas sobre la implementación de aplicaciones de .NET Aspire en Azure, consulte Deploy Aspire para Azure Container Apps mediante la CLI de Aspire.
Implementación tradicional (sin Aspire)
En las secciones siguientes se describe cómo implementar Orleans en Azure Container Apps mediante Acciones de GitHub y Azure Bicep, sin .NET Aspire.
Prerrequisitos
- Una cuenta de GitHub
- Leer una introducción a Orleans
- SDK de .NET 6
- La CLI de Azure
- Un entorno de desarrollo integrado (IDE) de .NET
- No dude en usar Visual Studio o Visual Studio Code
Probar la aplicación localmente
Para ejecutar la aplicación localmente, haga un fork del repositorio Azure Samples: Orleans Carro de la compra en Azure Container Apps y clónelo en su máquina local. Una vez clonada, abra la solución en un IDE de su elección. Si usa Visual Studio, haga clic con el botón derecho en .Orleans Proyecto ShoppingCart.Silo, seleccione Establecer como proyecto de inicio y, a continuación, ejecute la aplicación. De lo contrario, ejecute la aplicación con el siguiente comando de la CLI de .NET:
dotnet run --project Silo\Orleans.ShoppingCart.Silo.csproj
Para obtener más información, consulte dotnet run. Con la aplicación en ejecución, una página de aterrizaje describe la funcionalidad de la aplicación. En la esquina superior derecha, se puede ver un botón de inicio de sesión. Regístrese para obtener una cuenta o inicie sesión si ya existe una. Una vez que haya iniciado sesión, desplácese por él y pruebe sus funcionalidades. Toda la funcionalidad de la aplicación cuando se ejecuta localmente se basa en la persistencia en memoria y la agrupación en clústeres locales. También usa el paquete NuGet Bogus para generar productos falsos. Detenga la aplicación seleccionando la opción Detener depuración en Visual Studio o presionando Ctrl+C en la CLI de .NET.
AAD B2C
Aunque la enseñanza de los conceptos de autenticación está fuera del ámbito de este tutorial, aprenda a crear un inquilino de Azure Active Directory B2C y, a continuación, a registrar una aplicación web para consumirla. Para esta aplicación de ejemplo de carrito de compras, registre la URL resultante de las aplicaciones contenedoras implementadas en el inquilino B2C. Para obtener más información, consulte ASP.NET autenticación y autorización de Core Blazor.
Importante
Una vez implementada la aplicación de contenedores, registre la URL de la aplicación en el entorno de B2C. En la mayoría de los escenarios de producción, la dirección URL de la aplicación solo necesita registro una vez, ya que no debería cambiar.
Para ayudar a visualizar cómo está aislada la aplicación en el entorno de Azure Container Apps, consulte el diagrama siguiente:
En el diagrama anterior, todo el tráfico entrante a la aplicación se canaliza a través de un ingreso HTTP seguro. El entorno de Azure Container Apps contiene una instancia de aplicación, y esta instancia contiene un host de ASP.NET Core que expone la funcionalidad del servidor Blazor y la aplicación Orleans.
Implementación en Azure Container Apps
Para implementar la aplicación en Azure Container Apps, el repositorio usa Acciones de GitHub. Para poder realizar esta implementación, se necesitan algunos recursos de Azure y el repositorio de GitHub debe configurarse correctamente.
Antes de implementar la aplicación, cree un grupo de recursos de Azure (o puede usar uno existente). Para crear un nuevo grupo de recursos de Azure, use uno de los siguientes artículos:
Anote el nombre del grupo de recursos que elija; lo necesitará más adelante para implementar la aplicación.
Crear un principal de servicio
Para automatizar el despliegue de la aplicación, necesita crear un principal de servicio. Se trata de una cuenta microsoft que tiene permiso para administrar recursos de Azure en su nombre.
az ad sp create-for-rbac --sdk-auth --role Contributor \
--name "<display-name>" --scopes /subscriptions/<your-subscription-id>
Las credenciales JSON creadas son similares a las siguientes, pero con valores reales para el cliente, la suscripción y el inquilino:
{
"clientId": "<your client id>",
"clientSecret": "<your client secret>",
"subscriptionId": "<your subscription id>",
"tenantId": "<your tenant id>",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com/",
"resourceManagerEndpointUrl": "https://brazilus.management.azure.com",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com",
"managementEndpointUrl": "https://management.core.windows.net"
}
Copie la salida del comando en el Portapapeles y continúe con el paso siguiente.
Creación de un secreto de GitHub
GitHub proporciona un mecanismo para crear secretos cifrados. Los secretos que cree están disponibles para su uso en flujos de trabajo de Acciones de GitHub. Verá cómo usar Acciones de GitHub para automatizar la implementación de la aplicación junto con Azure Bicep. Bicep es un lenguaje específico del dominio (DSL) que usa sintaxis declarativa para implementar recursos de Azure. Para obtener más información, consulte ¿Qué es Bicep?. Usando la salida del paso Creación de una entidad de servicio, debe crear un secreto de GitHub llamado AZURE_CREDENTIALS con las credenciales en formato JSON.
En el repositorio de GitHub, seleccione Configuración>secretos>Crear un nuevo secreto. Escriba el nombre AZURE_CREDENTIALS y pegue las credenciales JSON del paso anterior en el campo Valor .
Para obtener más información, consulte GitHub: Secretos cifrados.
Preparación para la implementación de Azure
Empaquetar la aplicación para la implementación. En el Orleans.ShoppingCart.Silos proyecto, se define un Target elemento que se ejecuta después del Publish paso. Este destino comprime el directorio publish en un archivo silo.zip
<Target Name="ZipPublishOutput" AfterTargets="Publish">
<Delete Files="$(ProjectDir)\..\silo.zip" />
<ZipDirectory SourceDirectory="$(PublishDir)" DestinationFile="$(ProjectDir)\..\silo.zip" />
</Target>
Hay muchas maneras de implementar una aplicación .NET en Azure Container Apps. En este tutorial, use Acciones de GitHub, Azure Bicep y los CLIs de .NET y Azure. Considere el archivo ./github/workflows/deploy.yml en la raíz del repositorio de GitHub:
name: Deploy to Azure Container Apps
on:
push:
branches:
- main
env:
UNIQUE_APP_NAME: orleanscart
SILO_IMAGE_NAME: orleanscart-silo
AZURE_RESOURCE_GROUP_NAME: orleans-resourcegroup
AZURE_RESOURCE_GROUP_LOCATION: eastus
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.x
- name: .NET publish shopping cart app
run: dotnet publish ./Silo/Orleans.ShoppingCart.Silo.csproj --configuration Release
- name: Login to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Flex ACR Bicep
run: |
az deployment group create \
--resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
--template-file '.github/workflows/flex/acr.bicep' \
--parameters location=${{ env.AZURE_RESOURCE_GROUP_LOCATION }}
- name: Get ACR Login Server
run: |
ACR_NAME=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} -n acr \
--query properties.outputs.acrName.value | tr -d '"')
echo "ACR_NAME=$ACR_NAME" >> $GITHUB_ENV
ACR_LOGIN_SERVER=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} -n acr \
--query properties.outputs.acrLoginServer.value | tr -d '"')
echo "ACR_LOGIN_SERVER=$ACR_LOGIN_SERVER" >> $GITHUB_ENV
- name: Prepare Docker buildx
uses: docker/setup-buildx-action@v1
- name: Login to ACR
run: |
access_token=$(az account get-access-token --query accessToken -o tsv)
refresh_token=$(curl https://${{ env.ACR_LOGIN_SERVER }}/oauth2/exchange -v \
-d "grant_type=access_token&service=${{ env.ACR_LOGIN_SERVER }}&access_token=$access_token" | jq -r .refresh_token)
# The null GUID 0000... tells the container registry that this is an ACR refresh token during the login flow
docker login -u 00000000-0000-0000-0000-000000000000 \
--password-stdin ${{ env.ACR_LOGIN_SERVER }} <<< "$refresh_token"
- name: Build and push Silo image to registry
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ env.ACR_LOGIN_SERVER }}/${{ env.SILO_IMAGE_NAME }}:${{ github.sha }}
file: Silo/Dockerfile
- name: Flex ACA Bicep
run: |
az deployment group create \
--resource-group ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
--template-file '.github/workflows/flex/main.bicep' \
--parameters location=${{ env.AZURE_RESOURCE_GROUP_LOCATION }} \
appName=${{ env.UNIQUE_APP_NAME }} \
acrName=${{ env.ACR_NAME }} \
repositoryImage=${{ env.ACR_LOGIN_SERVER }}/${{ env.SILO_IMAGE_NAME }}:${{ github.sha }} \
--debug
- name: Get Container App URL
run: |
ACA_URL=$(az deployment group show -g ${{ env.AZURE_RESOURCE_GROUP_NAME }} \
-n main --query properties.outputs.acaUrl.value | tr -d '"')
echo $ACA_URL
- name: Logout of Azure
run: az logout
El flujo de trabajo de GitHub anterior hace lo siguiente:
- Publica la aplicación de carro de la compra como un archivo ZIP mediante el comando dotnet publish .
- Inicia sesión en Azure usando las credenciales del paso Creación de una entidad de servicio.
- Evalúa el archivo acr.bicep e inicia un grupo de implementación mediante az deployment group create.
- Obtiene el servidor de inicio de sesión de Azure Container Registry (ACR) del grupo de implementación.
- Inicia sesión en ACR usando el secreto
AZURE_CREDENTIALSdel repositorio. - Compila y publica la imagen del silo en ACR.
- Evalúa el archivo main.bicep e inicia un grupo de implementación mediante az deployment group create.
- Implementa el silo.
- Cierra la sesión de Azure.
El flujo de trabajo se activa cuando hay una inserción a la rama main. Para obtener más información, consulte Acciones de GitHub y .NET.
Sugerencia
Si tiene problemas al ejecutar el flujo de trabajo, es posible que tenga que comprobar que la entidad de servicio tiene registrados todos los espacios de nombres de proveedor necesarios. A continuación se detallan los espacio de nombres de proveedor necesarios:
Microsoft.AppMicrosoft.ContainerRegistryMicrosoft.InsightsMicrosoft.OperationalInsightsMicrosoft.Storage
Para más información, consulte el artículo Resoluión de errores de registro del proveedor de recursos.
Azure impone restricciones de nomenclatura y convenciones para los recursos. Actualice los valores del archivo deploy.yml para las siguientes variables de entorno:
UNIQUE_APP_NAMESILO_IMAGE_NAMEAZURE_RESOURCE_GROUP_NAMEAZURE_RESOURCE_GROUP_LOCATION
Establezca estos valores en el nombre único de su aplicación y en el nombre y la ubicación de su grupo de recursos de Azure.
Para más información, consulte Reglas y restricciones de nomenclatura de recursos de Azure.
Exploración de las plantillas de Bicep
Cuando se ejecuta el az deployment group create comando, evalúa una referencia de archivo .bicep determinada. Este archivo contiene información declarativa que detalla los recursos de Azure que se van a implementar. Piense en este paso como aprovisionar todos los recursos para la implementación.
Importante
Si va a usar Visual Studio Code, la experiencia de creación de Bicep se mejora con la extensión de Bicep.
El primer archivo de Bicep evaluado es el archivo acr.bicep . Este archivo contiene los detalles del recurso del servidor de inicio de sesión de Azure Container Registry (ACR):
param location string = resourceGroup().location
resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' = {
name: toLower('${uniqueString(resourceGroup().id)}acr')
location: location
sku: {
name: 'Basic'
}
properties: {
adminUserEnabled: true
}
}
output acrLoginServer string = acr.properties.loginServer
output acrName string = acr.name
Este archivo Bicep genera el servidor de inicio de sesión de ACR y el nombre correspondiente. El siguiente archivo de Bicep encontrado contiene más de un único objeto resource. Considere el archivo main.bicep , que consta principalmente de delegar module definiciones:
param appName string
param acrName string
param repositoryImage string
param location string = resourceGroup().location
resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
name: acrName
}
module env 'environment.bicep' = {
name: 'containerAppEnvironment'
params: {
location: location
operationalInsightsName: '${appName}-logs'
appInsightsName: '${appName}-insights'
}
}
var envVars = [
{
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
value: env.outputs.appInsightsInstrumentationKey
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: env.outputs.appInsightsConnectionString
}
{
name: 'ORLEANS_AZURE_STORAGE_CONNECTION_STRING'
value: storageModule.outputs.connectionString
}
{
name: 'ASPNETCORE_FORWARDEDHEADERS_ENABLED'
value: 'true'
}
]
module storageModule 'storage.bicep' = {
name: 'orleansStorageModule'
params: {
name: '${appName}storage'
location: location
}
}
module siloModule 'container-app.bicep' = {
name: 'orleansSiloModule'
params: {
appName: appName
location: location
containerAppEnvironmentId: env.outputs.id
repositoryImage: repositoryImage
registry: acr.properties.loginServer
registryPassword: acr.listCredentials().passwords[0].value
registryUsername: acr.listCredentials().username
envVars: envVars
}
}
output acaUrl string = siloModule.outputs.acaUrl
El archivo Bicep anterior hace lo siguiente:
- Hace referencia a un
existingrecurso de ACR. Para más información, consulte Azure Bicep: Recursos existentes. - Define un
module envque delega en el archivo de definición environment.bicep. - Define un
module storageModuleque delega en el archivo de definición storage.bicep. - Declara varios
envVarscompartidos usados por el módulo silo. - Define un
module siloModuleque delega en el archivo de definición container-app.bicep. - Genera como salida la URL de ACA (posiblemente usada para actualizar el URI de redireccionamiento de un registro de aplicación existente en AAD B2C).
El archivo main.bicep delega en varios otros archivos Bicep. La primera es el archivo environment.bicep :
param operationalInsightsName string
param appInsightsName string
param location string
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
name: appInsightsName
location: location
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logs.id
}
}
resource logs 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
name: operationalInsightsName
location: location
properties: {
retentionInDays: 30
features: {
searchVersion: 1
}
sku: {
name: 'PerGB2018'
}
}
}
resource env 'Microsoft.App/managedEnvironments@2022-03-01' = {
name: '${resourceGroup().name}env'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: logs.properties.customerId
sharedKey: logs.listKeys().primarySharedKey
}
}
}
}
output id string = env.id
output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey
output appInsightsConnectionString string = appInsights.properties.ConnectionString
Este archivo de Bicep define los recursos de Azure Log Analytics y Application Insights. El appInsights recurso es un web tipo y el logs recurso es un PerGB2018 tipo. Tanto los recursos appInsights como logs se aprovisionan en la ubicación del grupo de recursos. El appInsights recurso se vincula al logs recurso a través de la WorkspaceResourceId propiedad . Este archivo de Bicep define tres salidas usadas más adelante por Container Apps module. A continuación, considere el archivo storage.bicep :
param name string
param location string
resource storage 'Microsoft.Storage/storageAccounts@2021-08-01' = {
name: name
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
var key = listKeys(storage.name, storage.apiVersion).keys[0].value
var protocol = 'DefaultEndpointsProtocol=https'
var accountBits = 'AccountName=${storage.name};AccountKey=${key}'
var endpointSuffix = 'EndpointSuffix=${environment().suffixes.storage}'
output connectionString string = '${protocol};${accountBits};${endpointSuffix}'
El archivo Bicep previo enumera lo siguiente:
- Dos parámetros para el nombre del grupo de recursos y el nombre de la aplicación.
- La definición de
resource storagede la cuenta de almacenamiento. - Un único
outputque construye la cadena de conexión para la cuenta de almacenamiento.
El último archivo de Bicep es el archivo container-app.bicep :
param appName string
param location string
param containerAppEnvironmentId string
param repositoryImage string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
param envVars array = []
param registry string
param registryUsername string
@secure()
param registryPassword string
resource containerApp 'Microsoft.App/containerApps@2022-03-01' = {
name: appName
location: location
properties: {
managedEnvironmentId: containerAppEnvironmentId
configuration: {
activeRevisionsMode: 'multiple'
secrets: [
{
name: 'container-registry-password'
value: registryPassword
}
]
registries: [
{
server: registry
username: registryUsername
passwordSecretRef: 'container-registry-password'
}
]
ingress: {
external: true
targetPort: 80
}
}
template: {
revisionSuffix: uniqueString(repositoryImage, appName)
containers: [
{
image: repositoryImage
name: appName
env: envVars
}
]
scale: {
minReplicas: 1
maxReplicas: 1
}
}
}
}
output acaUrl string = containerApp.properties.configuration.ingress.fqdn
La extensión de Visual Studio Code mencionada anteriormente para Bicep incluye un visualizador. Todos estos archivos Bicep se visualizan de la siguiente manera:
Resumen
A medida que el código fuente se actualiza y los cambios se incorporan (pushed) a la rama main del repositorio, el flujo de trabajo deploy.yml se ejecuta. Aprovisiona los recursos de Azure definidos en los archivos de Bicep e implementa la aplicación. Las revisiones se registran automáticamente en Azure Container Registry.
Además del visualizador desde la extensión de Bicep, la página del grupo de recursos de Azure Portal es similar al ejemplo siguiente después de aprovisionar e implementar la aplicación: