Развертывание Orleans в контейнерах приложений Azure

В этом руководстве описано, как развернуть пример Orleans приложения корзины для покупок в контейнере приложений Azure. В этом руководстве расширены функциональные возможности примера Orleans приложения корзины покупок, представленного в статье Развертывание Orleans в Служба приложений Azure. Пример приложения добавляет проверку подлинности azure Active Directory (AAD) B2C (бизнес-потребитель) и развертывает в контейнеры приложений Azure.

Вы узнаете, как выполнить развертывание с помощью GitHub Actions, .NET и azure CLIs, а также Azure Bicep. Кроме того, вы узнаете, как настроить входящий трафик HTTP приложения-контейнера.

В этом руководстве описано следующее:

  • Развертывание приложения в Orleans контейнерах приложений Azure
  • Автоматизация развертывания с помощью GitHub Actions и Azure Bicep
  • Настройка входящего трафика HTTP

Предварительные требования

Локальный запуск приложения

Чтобы запустить приложение локально, создайте вилку корзины для покупок Azure Samples: Orleans в репозитории Контейнеров приложений Azure и клонируйте ее на локальный компьютер. После клона откройте решение в выбранной интегрированной среде разработки. Если вы используете Visual Studio, щелкните правой Orleansкнопкой мыши . Проект ShoppingCart.Silo и выберите Задать как запускаемый проект, а затем запустите приложение. В противном случае можно запустить приложение с помощью следующей команды .NET CLI:

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

Дополнительные сведения см. в разделе dotnet run. После запуска приложения вы получите целевую страницу с описанием функциональности приложения. В правом верхнем углу появится кнопка входа. Вы можете зарегистрироваться для получения учетной записи или войти, если у вас уже есть учетная запись. После входа вы сможете перемещаться, и вы можете протестировать его возможности. Все функциональные возможности приложения при локальном запуске зависят от сохраняемости в памяти, локальных кластеризация и используют пакет NuGet Bogus для создания поддельных продуктов. Остановите приложение, выбрав параметр Остановить отладку в Visual Studio или нажав клавиши CTRL+C в .NET CLI.

AAD B2C

Хотя изучение концепций проверки подлинности выходит за рамки область этого руководства, вы можете узнать, как создать клиент Azure Active Directory B2C, а затем зарегистрировать веб-приложение для его использования. В случае с примером приложения корзины покупок полученный URL-адрес развернутых контейнерных приложений должен быть зарегистрирован в клиенте B2C. Дополнительные сведения см. в разделе ASP.NET Core аутентификации и авторизации Blazor.

Важно!

После развертывания контейнерного приложения необходимо зарегистрировать URL-адрес приложения в клиенте B2C. В большинстве рабочих сценариев вам потребуется зарегистрировать URL-адрес приложения только один раз, так как он не должен изменяться.

Чтобы визуализировать, как приложение изолировано в среде Контейнеров приложений Azure, см. следующую схему:

Входящий трафик HTTP контейнеров приложений Azure.

На предыдущей схеме весь входящий трафик к приложению направляется через защищенный входящий трафик HTTP. Среда Контейнеров приложений Azure содержит экземпляр приложения, а экземпляр приложения — узел ASP.NET Core, который предоставляет функциональные возможности сервера Blazor и Orleans приложений.

Развертывание на платформе "Контейнеры приложений Azure"

Чтобы развернуть приложение в контейнерах приложений Azure, репозиторий использует GitHub Actions. Перед развертыванием потребуется несколько ресурсов Azure, и необходимо правильно настроить репозиторий GitHub.

Перед развертыванием приложения необходимо создать группу ресурсов Azure (или использовать существующую). Чтобы создать группу ресурсов Azure, используйте одну из следующих статей:

Запишите выбранное имя группы ресурсов. Оно понадобится вам позже для развертывания приложения.

Создание субъекта-службы

Чтобы автоматизировать развертывание приложения, необходимо создать субъект-службу. Это учетная запись Майкрософт, которая имеет разрешение на управление ресурсами Azure от вашего имени.

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

Созданные учетные данные JSON будут выглядеть примерно так, как показано ниже, но с фактическими значениями для клиента, подписки и клиента:

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

Скопируйте выходные данные команды в буфер обмена и перейдите к следующему шагу.

Создание секрета GitHub

GitHub предоставляет механизм для создания зашифрованных секретов. Создаваемые секреты доступны для использования в GitHub Actions рабочих процессах. Вы узнаете, как GitHub Actions можно использовать для автоматизации развертывания приложения в сочетании с Azure Bicep. Bicep — это доменный язык (DSL), который использует декларативный синтаксис для развертывания ресурсов Azure. Дополнительные сведения см. в статье Что такое Bicep. Используя выходные данные шага Создание субъекта-службы , необходимо создать секрет GitHub с именем AZURE_CREDENTIALS с учетными данными в формате JSON.

В репозитории GitHub выберите Параметры Секреты>>Создать новый секрет. Введите имя AZURE_CREDENTIALS и вставьте учетные данные JSON из предыдущего шага в поле Значение .

Репозиторий GitHub: Параметры Секреты >

Дополнительные сведения см. в разделе GitHub: Зашифрованные секреты.

Подготовка к развертыванию Azure

Приложение необходимо упаковать для развертывания. В проекте мы определяем Orleans.ShoppingCart.SilosTarget элемент, который выполняется после Publish шага. Каталог публикации будет запаковываться в silo.zip файл:

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

Существует множество способов развертывания приложения .NET в контейнерах приложений Azure. В этом руководстве используются GitHub Actions, Azure Bicep, а также .NET и azure CLIs. Рассмотрим файл ./github/workflows/deploy.yml в корне репозитория 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

Предыдущий рабочий процесс GitHub:

  • Опубликуйте приложение корзины покупок в виде ZIP-файла с помощью команды dotnet publish .
  • Войдите в Azure, используя учетные данные из шага Создание субъекта-службы .
  • Оцените файл acr.bicep и запустите группу развертывания с помощью команды az deployment group create.
  • Получите сервер входа Реестр контейнеров Azure (ACR) из группы развертывания.
  • Войдите в ACR с помощью секрета репозиториев AZURE_CREDENTIALS .
  • Создайте и опубликуйте образ silo в ACR.
  • Оцените файл main.bicep и запустите группу развертывания с помощью команды az deployment group create.
  • Развертывание силоса
  • Выход из Azure.

Рабочий процесс активируется при отправке в ветвь main. Дополнительные сведения см. в разделе GitHub Actions и .NET.

Совет

При возникновении проблем при выполнении рабочего процесса может потребоваться убедиться, что субъект-служба имеет все необходимые пространства имен поставщика. Требуются следующие пространства имен поставщика:

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

Дополнительные сведения см. в статье Устранение ошибок при регистрации поставщика ресурсов.

Azure накладывает ограничения на именование и соглашения для ресурсов. Необходимо обновить значения файла deploy.yml для следующих значений:

  • UNIQUE_APP_NAME
  • SILO_IMAGE_NAME
  • AZURE_RESOURCE_GROUP_NAME
  • AZURE_RESOURCE_GROUP_LOCATION

Задайте для этих значений уникальное имя приложения, а также имя и расположение группы ресурсов Azure.

Дополнительные сведения см. в статье Правила и ограничения именования для ресурсов Azure.

Изучение шаблонов Bicep

При выполнении az deployment group create команды она будет оценивать указанную ссылку на BICEP-файл . Этот файл содержит декларативные сведения о ресурсах Azure, которые требуется развернуть. Один из способов подумать об этом шаге заключается в том, что он подготавливает все ресурсы для развертывания.

Важно!

Если вы используете Visual Studio Code, процесс разработки Bicep улучшается при использовании расширения Bicep.

Первый оцениваемый файл Bicep — это файл acr.bicep . Этот файл содержит сведения о ресурсе сервера входа Реестр контейнеров Azure (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

Этот файл bicep выводит сервер входа ACR и соответствующее имя. Следующий обнаруженный файл Bicep содержит не только один файл resource. Рассмотрим файл main.bicep, состоящий в основном из делегирования module определений:

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

Предыдущий файл Bicep:

  • existing Дополнительные сведения см. в статье Azure Bicep: существующие ресурсы.
  • Определяет module env , который делегирует в файл определения environment.bicep .
  • Определяет , module storageModule который делегирует файл определения storage.bicep .
  • Объявляет несколько общих envVars файлов, используемых модулем silo.
  • Определяет module siloModule , который делегирует в файл определения container-app.bicep .
  • Выводит URL-адрес ACA (потенциально он может использоваться для обновления существующего URI перенаправления регистрации приложения AAD B2C).

Main.bicep делегирует несколько других файлов Bicep. Первый — это файл 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

Этот файл bicep определяет ресурсы Azure Log Analytics и Application Insights. Ресурс appInsights является типом web , а logs ресурс — типом PerGB2018 . appInsights И ресурс, logs и ресурс подготавливаются в расположении группы ресурсов. Ресурс appInsights связан с ресурсом logs через WorkspaceResourceId свойство . В этом bicep определены три выходных данных, которые позже будут использоваться контейнером приложений module. Теперь рассмотрим файл 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}'

Предыдущий файл Bicep определяет следующее:

  • Два параметра для имени группы ресурсов и имени приложения.
  • Определение resource storage для учетной записи хранения.
  • Объект , output создающий строку подключения для учетной записи хранения.

Последний файл Bicep — это файл 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

Упомянутое выше расширение Visual Studio Code для Bicep включает визуализатор. Все эти файлы Bicep визуализируются следующим образом:

Orleans: пример приложения Bicep для подготовки визуализации визуализации корзины для покупок.

Сводка

При обновлении исходного кода и push изменении main ветви репозитория будет выполняться рабочий процесс deploy.yml . Он подготавливает ресурсы Azure, определенные в файлах Bicep, и развертывает приложение. Редакции автоматически регистрируются в Реестр контейнеров Azure.

Помимо визуализатора из расширения Bicep страница группы ресурсов портал Azure будет выглядеть примерно так, как в следующем примере после подготовки и развертывания приложения:

Портал Azure: Orleans примеры ресурсов приложения корзины для контейнеров Azure.

См. также раздел