Azure Container Apps'e dağıtma Orleans

Bu öğreticide örnek bir Orleans alışveriş sepeti uygulamasını Azure Container Apps'e dağıtmayı öğreneceksiniz. Bu öğretici, Azure App Service'a dağıtma Orleansbölümünde tanıtılan örnek Orleans alışveriş sepeti uygulamasının işlevselliğini genişletir. Örnek uygulama, Azure Active Directory (AAD) işletmeler arası (B2C) kimlik doğrulamasını ekler ve Azure Container Apps'e dağıtır.

GitHub Actions, .NET ve Azure CLI'leri ve Azure Bicep kullanarak dağıtmayı öğreneceksiniz. Ayrıca, Kapsayıcı Uygulamasının HTTP girişini yapılandırmayı da öğreneceksiniz.

Bu öğreticide şunların nasıl yapıldığını öğreneceksiniz:

  • Orleans Azure Container Apps'e uygulama dağıtma
  • GitHub Actions ve Azure Bicep kullanarak dağıtımı otomatikleştirme
  • HTTP girişini yapılandırma

Önkoşullar

Uygulamayı yerel olarak çalıştırma

Uygulamayı yerel olarak çalıştırmak için Azure Örnekleri: Orleans Azure Container Apps deposundaki alışveriş sepetini çatallayın ve yerel makinenize kopyalayın. Kopyaladıktan sonra çözümü seçtiğiniz bir IDE'de açın. Visual Studio kullanıyorsanız öğesine sağ tıklayın Orleans. ShoppingCart.Silo projesi ve Başlangıç Projesi Olarak Ayarla'yı seçip uygulamayı çalıştırın. Aksi takdirde, aşağıdaki .NET CLI komutunu kullanarak uygulamayı çalıştırabilirsiniz:

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

Daha fazla bilgi için bkz. dotnet run. Uygulama çalışırken size uygulamanın işlevselliğini tartışan bir giriş sayfası sunulur. Sağ üst köşede bir oturum açma düğmesi görürsünüz. Bir hesaba kaydolabilir veya zaten bir hesabınız varsa oturum açabilirsiniz. Oturum açtıktan sonra gezinebilir ve özelliklerini test edebilirsiniz. Yerel olarak çalışırken uygulamanın tüm işlevleri bellek içi kalıcılığa, yerel kümelemeye dayanır ve sahte ürünler oluşturmak için Bogus NuGet paketini kullanır. Visual Studio'da Hata Ayıklamayı Durdur seçeneğini belirleyerek veya .NET CLI'de Ctrl+C tuşlarına basarak uygulamayı durdurun.

AAD B2C

Kimlik doğrulaması kavramlarını öğretirken bu öğreticinin kapsamı dışındadır. Azure Active Directory B2C kiracısı oluşturma hakkında bilgi edinebilir ve bunu kullanmak için bir web uygulaması kaydedebilirsiniz . Bu alışveriş sepeti örnek uygulaması söz konusu olduğunda, sonuçta dağıtılan Container Apps'in URL'sinin B2C kiracısına kaydedilmesi gerekir. Daha fazla bilgi için bkz. Blazor kimlik doğrulaması ve yetkilendirmesini ASP.NET Core.

Önemli

Kapsayıcı Uygulamanız dağıtıldıktan sonra uygulamanın URL'sini B2C kiracısına kaydetmeniz gerekir. Çoğu üretim senaryosunda, değişmemesi gerektiğinden uygulamanın URL'sini yalnızca bir kez kaydetmeniz gerekir.

Uygulamanın Azure Container Apps ortamında nasıl yalıtılmış olduğunu görselleştirmeye yardımcı olmak için aşağıdaki diyagrama bakın:

Azure Container Apps HTTP girişi.

Önceki diyagramda, uygulamaya gelen tüm trafik güvenli bir HTTP girişi üzerinden hunilenir. Azure Container Apps ortamı bir uygulama örneği, uygulama örneği ise Blazor Sunucusu ve Orleans uygulama işlevselliğini kullanıma sunan bir ASP.NET Core ana bilgisayarı içerir.

Azure Container Apps'e dağıtma

Uygulamayı Azure Container Apps'e dağıtmak için depo, GitHub Actions kullanır. Bu dağıtımın gerçekleşebilmesi için birkaç Azure kaynağına ihtiyacınız olacak ve GitHub deposunu doğru yapılandırmanız gerekir.

Uygulamayı dağıtmadan önce bir Azure Kaynak Grubu oluşturmanız gerekir (veya mevcut bir kaynak grubunu kullanmayı seçebilirsiniz). Yeni bir Azure Kaynak Grubu oluşturmak için aşağıdaki makalelerden birini kullanın:

Seçtiğiniz kaynak grubu adını not edin; daha sonra uygulamayı dağıtmak için buna ihtiyacınız olacaktır.

Hizmet sorumlusu oluşturma

Uygulamanın dağıtımını otomatikleştirmek için bir hizmet sorumlusu oluşturmanız gerekir. Bu, Azure kaynaklarını sizin adınıza yönetme iznine sahip bir Microsoft hesabıdır.

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

Oluşturulan JSON kimlik bilgileri aşağıdakine benzer, ancak istemciniz, aboneliğiniz ve kiracınız için gerçek değerlerle birlikte:

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

Komutun çıkışını panonuza kopyalayın ve sonraki adıma geçin.

GitHub gizli dizisi oluşturma

GitHub, şifrelenmiş gizli diziler oluşturmaya yönelik bir mekanizma sağlar. Oluşturduğunuz gizli diziler GitHub Actions iş akışlarında kullanılabilir. Azure Bicepile birlikte uygulamanın dağıtımını otomatikleştirmek için GitHub Actions nasıl kullanılabileceğini göreceksiniz. Bicep , Azure kaynaklarını dağıtmak için bildirim temelli bir söz dizimi kullanan etki alanına özgü bir dildir (DSL). Daha fazla bilgi için bkz. Bicep nedir? Hizmet sorumlusu oluşturma adımının çıkışını kullanarak JSON biçimli kimlik bilgileriyle adlı AZURE_CREDENTIALS bir GitHub gizli dizisi oluşturmanız gerekir.

GitHub deposunda Ayarlar>Gizli Diziler>Yeni gizli dizi oluştur'u seçin. Adı AZURE_CREDENTIALS girin ve önceki adımda yer alan JSON kimlik bilgilerini Değer alanına yapıştırın.

GitHub Deposu: Gizli Dizileri Ayarlar >

Daha fazla bilgi için bkz . GitHub: Şifrelenmiş Gizli Diziler.

Azure dağıtımına hazırlanma

Uygulamanın dağıtım için paketlenmiş olması gerekir. ProjedeOrleans.ShoppingCart.Silos, adımdan Publish sonra çalıştırılan bir Target öğe tanımlayacağız. Bu işlem yayımlama dizinini birsilo.zip dosyasına sıkıştıracaktır:

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

Bir .NET uygulamasını Azure Container Apps'e dağıtmanın birçok yolu vardır. Bu öğreticide GitHub Actions, Azure Bicep ve .NET ile Azure CLI'lerini kullanacaksınız. GitHub deposunun kökündeki ./github/workflows/deploy.yml dosyasını göz önünde bulundurun:

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

Önceki GitHub iş akışı:

İş akışı , ana dala yapılan bir gönderimle tetikleniyor. Daha fazla bilgi için bkz. GitHub Actions ve .NET.

İpucu

İş akışını çalıştırırken sorunlarla karşılaşırsanız, hizmet sorumlusunun tüm gerekli sağlayıcı ad alanlarının kayıtlı olduğunu doğrulamanız gerekebilir. Aşağıdaki sağlayıcı ad alanları gereklidir:

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

Daha fazla bilgi için bkz . Kaynak sağlayıcısı kaydı hatalarını çözme.

Azure, kaynaklar için adlandırma kısıtlamaları ve kurallar uygular. Aşağıdakiler için deploy.yml dosya değerlerini güncelleştirmeniz gerekir:

  • UNIQUE_APP_NAME
  • SILO_IMAGE_NAME
  • AZURE_RESOURCE_GROUP_NAME
  • AZURE_RESOURCE_GROUP_LOCATION

Bu değerleri benzersiz uygulama adınız, Azure kaynak grubu adınız ve konumunuz olarak ayarlayın.

Daha fazla bilgi için bkz . Azure kaynakları için adlandırma kuralları ve kısıtlamaları.

Bicep şablonlarını keşfetme

az deployment group create Komut çalıştırıldığında, belirli bir .bicep dosya başvurusunu değerlendirir. Bu dosya, dağıtmak istediğiniz Azure kaynaklarının ayrıntılarını içeren bildirim temelli bilgiler içerir. Bu adımı düşünmenin bir yolu, dağıtım için tüm kaynakları sağlamasıdır .

Önemli

Visual Studio Code kullanıyorsanız Bicep Uzantısı kullanılırken Bicep yazma deneyimi iyileştirilir.

Değerlendirilen ilk Bicep dosyası acr.bicep dosyasıdır. Bu dosya Azure Container Registry (ACR) oturum açma sunucusu kaynak ayrıntılarını içerir:

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

Bu bicep dosyası, ACR oturum açma sunucusunu ve buna karşılık gelen adı döndürür. Karşılaşılan sonraki Bicep dosyası tek resourcebir dosyadan fazlasını içerir. Öncelikle module tanımları temsilci seçmeden oluşan main.bicep dosyasını göz önünde bulundurun:

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

Önceki Bicep dosyası:

  • ACR kaynağına başvurur existing , daha fazla bilgi için bkz. Azure Bicep: Mevcut kaynaklar.
  • environment.bicep tanım dosyasına temsilci seçen bir module env tanımlar.
  • storage.bicep tanım dosyasına temsilci seçen bir module storageModule tanımlar.
  • Silo modülü tarafından kullanılan birkaç paylaşılan envVars bildirir.
  • container-app.bicep tanım dosyasına temsilci seçen bir module siloModule tanımlar.
  • ACA URL'sini döndürür (bu, mevcut bir AAD B2C uygulama kaydının yeniden yönlendirme URI'sini güncelleştirmek için kullanılabilir).

main.bicep, diğer birkaç Bicep dosyası için temsilci seçmektedir. Birincisi environment.bicep dosyasıdır:

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

Bu bicep dosyası Azure Log Analytics ve Application Insights kaynaklarını tanımlar. Kaynak appInsights bir web tür ve logs kaynak bir PerGB2018 türdür. appInsights Hem kaynak hem logs de kaynak, kaynak grubunun konumunda sağlanır. KaynakappInsights, özelliği aracılığıyla WorkspaceResourceId kaynağa bağlanırlogs. Bu kaynakta daha sonra Container Apps moduletarafından kullanılan üç çıkış tanımlanmıştır. Şimdi storage.bicep dosyasına bakalım:

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}'

Yukarıdaki Bicep dosyası aşağıdakileri tanımlar:

  • Kaynak grubu adı ve uygulama adı için iki parametre.
  • resource storage Depolama hesabının tanımı.
  • Depolama hesabı için bağlantı dizesini oluşturan tek output bir.

Son Bicep dosyası container-app.bicep dosyasıdır:

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

Bicep için yukarıda belirtilen Visual Studio Code uzantısı bir görselleştirici içerir. Bu Bicep dosyalarının tümü aşağıdaki gibi görselleştirilir:

Orleans: Alışveriş sepeti örnek uygulaması Bicep sağlama görselleştiricisi işleme.

Özet

Kaynak kodu güncelleştirdiğinizde ve push deponun main dalını değiştirdiğinizde deploy.yml iş akışı çalıştırılır. Bicep dosyalarında tanımlanan Azure kaynaklarını sağlar ve uygulamayı dağıtır. Düzeltmeler otomatik olarak Azure Container Registry kaydedilir.

Bicep uzantısındaki görselleştiriciye ek olarak, Azure portal kaynak grubu sayfası uygulamayı sağladıktan ve dağıttığınızda aşağıdaki örneğe benzer olacaktır:

Azure Portal: Orleans Azure Container Apps için alışveriş sepeti örnek uygulama kaynakları.

Ayrıca bkz.