Dela via


Distribuera Orleans till Azure Container Apps

I den här självstudien får du lära dig hur du distribuerar ett exempelprogram Orleans för kundvagn till Azure Container Apps. Den här självstudien utökar funktionerna i exempelappen Orleans för kundvagn, som introducerades i Distribuera Orleans till Azure App Service. Exempelappen lägger till AAD-autentisering (Azure Active Directory) autentisering från företag till konsument (B2C) och distribueras till Azure Container Apps.

Du får lära dig hur du distribuerar med GitHub Actions, .NET och Azure CLIs och Azure Bicep. Dessutom får du lära dig hur du konfigurerar containerappens HTTP-ingress.

I den här guiden får du lära dig att:

  • Distribuera ett Orleans program till Azure Container Apps
  • Automatisera distributionen med GitHub Actions och Azure Bicep
  • Konfigurera HTTP-ingress

Krav

Köra appen lokalt

Om du vill köra appen lokalt förgrenar du Azure Samples: Orleans kundvagnen på Azure Container Apps-lagringsplatsen och klonar den till din lokala dator. När du har klonat öppnar du lösningen i valfri IDE. Om du använder Visual Studio högerklickar du på Orleans. ShoppingCart.Silo-projekt och välj Ange som startprojekt och kör sedan appen. Annars kan du köra appen med följande .NET CLI-kommando:

dotnet run --project Silo\Orleans.ShoppingCart.Silo.csproj

Mer information finns i dotnet run. När appen körs visas en landningssida som beskriver appens funktioner. I det övre högra hörnet visas en inloggningsknapp. Du kan registrera dig för ett konto eller logga in om du redan har ett konto. När du har loggat in kan du navigera runt och testa dess funktioner. Alla appfunktioner när de körs lokalt förlitar sig på minnesintern beständighet, lokal klustring och använder Bogus NuGet-paketet för att generera falska produkter. Stoppa appen genom att välja alternativet Stoppa felsökning i Visual Studio eller genom att trycka på Ctrl+C i .NET CLI.

AAD B2C

Medan du lär dig begreppen autentisering ligger utanför omfånget för den här självstudien kan du lära dig hur du skapar en Azure Active Directory B2C-klientorganisation och sedan kan du registrera en webbapp för att använda den. När det gäller den här exempelappen i kundvagnen måste den resulterande distribuerade Container Apps-URL:en registreras i B2C-klientorganisationen. Mer information finns i ASP.NET Core Blazor-autentisering och auktorisering.

Viktigt

När containerappen har distribuerats måste du registrera appens URL i B2C-klientorganisationen. I de flesta produktionsscenarier behöver du bara registrera appens URL en gång eftersom den inte bör ändras.

Information om hur appen är isolerad i Azure Container Apps-miljön finns i följande diagram:

Http-ingress för Azure Container Apps.

I föregående diagram dirigeras all inkommande trafik till appen via en skyddad HTTP-ingress. Azure Container Apps-miljön innehåller en appinstans och appinstansen innehåller en ASP.NET Core värd, som exponerar Blazor Server- och Orleans appfunktionerna.

Distribuera till Azure Container Apps

Om du vill distribuera appen till Azure Container Apps använder lagringsplatsen GitHub Actions. Innan den här distributionen kan ske behöver du några Azure-resurser och du måste konfigurera GitHub-lagringsplatsen korrekt.

Innan du distribuerar appen måste du skapa en Azure-resursgrupp (eller välja att använda en befintlig). Om du vill skapa en ny Azure-resursgrupp använder du någon av följande artiklar:

Anteckna namnet på resursgruppen som du väljer. Du behöver det senare för att distribuera appen.

Skapa ett huvudnamn för tjänsten

För att automatisera distributionen av appen måste du skapa ett huvudnamn för tjänsten. Det här är ett Microsoft-konto som har behörighet att hantera Azure-resurser för din räkning.

az ad sp create-for-rbac --sdk-auth --role Contributor \
  --name "<display-name>"  --scopes /subscriptions/<your-subscription-id>

JSON-autentiseringsuppgifterna som skapas ser ut ungefär så här, men med faktiska värden för din klient, prenumeration och klientorganisation:

{
  "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"
}

Kopiera utdata från kommandot till Urklipp och fortsätt till nästa steg.

Skapa en GitHub-hemlighet

GitHub tillhandahåller en mekanism för att skapa krypterade hemligheter. De hemligheter som du skapar är tillgängliga att använda i GitHub Actions arbetsflöden. Du kommer att se hur GitHub Actions kan användas för att automatisera distributionen av appen tillsammans med Azure Bicep. Bicep är ett domänspecifikt språk (DSL) som använder en deklarativ syntax för att distribuera Azure-resurser. Mer information finns i Vad är Bicep. Med hjälp av utdata från steget Skapa ett huvudnamn för tjänsten måste du skapa en GitHub-hemlighet med namnet AZURE_CREDENTIALS med JSON-formaterade autentiseringsuppgifter.

På GitHub-lagringsplatsen väljer du Inställningar>Hemligheter>Skapa en ny hemlighet. Ange namnet AZURE_CREDENTIALS och klistra in JSON-autentiseringsuppgifterna från föregående steg i fältet Värde .

GitHub-lagringsplats: Inställningar Hemligheter >

Mer information finns i GitHub: Encrypted Secrets (GitHub: Krypterade hemligheter).

Förbereda för Azure-distribution

Appen måste paketeras för distribution. Orleans.ShoppingCart.Silos I projektet definierar vi ett Target element som körs efter Publish steget. Då zippar du publiceringskatalogen i en silo.zip fil:

<Target Name="ZipPublishOutput" AfterTargets="Publish">
    <Delete Files="$(ProjectDir)\..\silo.zip" />
    <ZipDirectory SourceDirectory="$(PublishDir)" DestinationFile="$(ProjectDir)\..\silo.zip" />
</Target>

Det finns många sätt att distribuera en .NET-app till Azure Container Apps. I den här självstudien använder du GitHub Actions, Azure Bicep och .NET- och Azure-CLIs. Överväg filen ./github/workflows/deploy.yml i roten på GitHub-lagringsplatsen:

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

Föregående GitHub-arbetsflöde kommer att:

  • Publicera kundvagnsappen som en zip-fil med hjälp av kommandot dotnet publish .
  • Logga in på Azure med autentiseringsuppgifterna från steget Skapa ett huvudnamn för tjänsten .
  • Utvärdera filen acr.bicep och starta en distributionsgrupp med az deployment group create.
  • Hämta inloggningsservern Azure Container Registry (ACR) från distributionsgruppen.
  • Logga in på ACR med lagringsplatshemligheten AZURE_CREDENTIALS .
  • Skapa och publicera silo-avbildningen till ACR.
  • Utvärdera filen main.bicep och starta en distributionsgrupp med az deployment group create.
  • Distribuera silon
  • Utloggning av Azure.

Arbetsflödet utlöses av en push-överföring till huvudgrenen . Mer information finns i GitHub Actions och .NET.

Tips

Om du stöter på problem när du kör arbetsflödet kan du behöva kontrollera att tjänstens huvudnamn har alla nödvändiga providernamnområden registrerade. Följande providernamnområden krävs:

  • Microsoft.App
  • Microsoft.ContainerRegistry
  • Microsoft.Insights
  • Microsoft.OperationalInsights
  • Microsoft.Storage

Mer information finns i Lösa fel för registrering av resursprovider.

Azure inför namngivningsbegränsningar och konventioner för resurser. Du måste uppdatera filvärdena deploy.yml för följande:

  • UNIQUE_APP_NAME
  • SILO_IMAGE_NAME
  • AZURE_RESOURCE_GROUP_NAME
  • AZURE_RESOURCE_GROUP_LOCATION

Ange dessa värden till ditt unika appnamn och namnet och platsen för din Azure-resursgrupp.

Mer information finns i Namngivningsregler och begränsningar för Azure-resurser.

Utforska Bicep-mallarna

az deployment group create När kommandot körs utvärderas en viss .bicep-filreferens. Den här filen innehåller deklarativ information som beskriver de Azure-resurser som du vill distribuera. Ett sätt att tänka på det här steget är att det etablerar alla resurser för distribution.

Viktigt

Om du använder Visual Studio Code förbättras Bicep-redigeringsupplevelsen när du använder Bicep-tillägget.

Den första Bicep-filen som utvärderas är filen acr.bicep . Den här filen innehåller resursinformation för Azure Container Registry (ACR) inloggningsserver:

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

Den här bicep-filen matar ut ACR-inloggningsservern och motsvarande namn. Nästa Bicep-fil som påträffades innehåller mer än bara en enda resource. Överväg main.bicep-filen som främst består av delegerande module definitioner:

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

Föregående Bicep-fil:

  • Refererar till en existing ACR-resurs. Mer information finns i Azure Bicep: Befintliga resurser.
  • Definierar en module env som delegerar ut till definitionsfilen environment.bicep .
  • Definierar en module storageModule som delegerar ut till definitionsfilen storage.bicep .
  • Deklarerar flera delade envVars som används av silomodulen.
  • Definierar en module siloModule som delegerar ut till definitionsfilen container-app.bicep .
  • Matar ut ACA-URL:en (detta kan potentiellt användas för att uppdatera en befintlig AAD B2C-appregistrerings omdirigerings-URI).

Main.bicep delegerar ut till flera andra Bicep-filer. Den första är filen 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

Den här bicep-filen definierar Azure Log Analytics- och Application Insights-resurserna. Resursen appInsights är en web typ och resursen logs är en PerGB2018 typ. Både resursen appInsights och resursen logs etableras på resursgruppens plats. Resursen appInsights är länkad till resursen logs via WorkspaceResourceId egenskapen . Det finns tre utdata som definierats i denna bicep, som används senare av Container Apps module. Nu ska vi titta på filen 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}'

Föregående Bicep-fil definierar följande:

  • Två parametrar för resursgruppens namn och appnamnet.
  • Definitionen resource storage för lagringskontot.
  • En enda output som konstruerar anslutningssträngen för lagringskontot.

Den sista Bicep-filen är filen 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

Det tidigare nämnda Visual Studio Code-tillägget för Bicep innehåller en visualiserare. Alla dessa Bicep-filer visualiseras på följande sätt:

Orleans: Kundvagnsexempelapp Bicep-etablering visualiserarendering.

Sammanfattning

När du uppdaterar källkoden och push ändringarna main i lagringsplatsens gren körs arbetsflödet deploy.yml . Den etablerar De Azure-resurser som definierats i Bicep-filerna och distribuerar programmet. Ombearbetningar registreras automatiskt i din Azure Container Registry.

Förutom visualiseraren från Bicep-tillägget skulle sidan Azure Portal-resursgrupp se ut ungefär som i följande exempel efter etablering och distribution av programmet:

Azure-portalen: Orleans Exempelappresurser i kundvagn för Azure Container Apps.

Se även