Развертывание и масштабирование приложения ASP.NET Core в Контейнерах приложений Azure

Приложения, развернутые в Azure и периодически испытывающие высокую нагрузку, выигрывают от масштабируемости. Емкость масштабируемых приложений может увеличиваться во время периодов пиковой нагрузки, а по их завершении автоматически уменьшаться с целью снижения затрат. Горизонтальное масштабирование (горизонтальное увеличение масштаба) — это добавление новых экземпляров ресурса, например, виртуальных машин или реплик базы данных. В этой статье показано, как развернуть горизонтально масштабируемое приложение ASP.NET Core в контейнерах приложений Azure, выполнив следующие задачи:

  1. Настройка примера проекта
  2. Развертывание приложения в Контейнерах приложений Azure
  3. Масштабирование и устранение неполадок приложения
  4. Создание служб Azure
  5. Подключение служб Azure
  6. Настройка и повторное развертывание приложения

В этой статье используется Razor Pages, но большая часть информации применима и к другим приложениям ASP.NET Core.

В некоторых случаях базовые приложения ASP.NET Core могут масштабироваться без дополнительных усилий. Однако приложения, использующие определенные функции платформы или архитектурные шаблоны, требуют дополнительной настройки, включая следующее:

  • Безопасная отправка форм: приложения Razor Pages, MVC и веб-API часто используют отправку форм. По умолчанию для защиты запросов эти приложения используют маркеры защиты от подделки межсайтовых запросов и внутренние службы защиты данных. При развертывании в облаке эти приложения должны быть настроены для управления службами защиты данных в безопасном централизованном расположении.

  • Каналы SignalR: приложения Blazor Server требуют использования централизованной службы Azure SignalR для безопасного масштабирования. Эти службы также используют упомянутые ранее службы защиты данных.

  • Централизованные службы кэширования или управления состоянием: масштабируемые приложения могут использовать Кэш Azure для Redis для обеспечения распределенного кэширования. Служба хранилища Azure может требоваться для хранения состояния платформ, таких как Microsoft Orleans. Это помогает создавать приложения с управлением состоянием множества экземпляров.

В этой статье показано, как надлежащим образом решить указанные выше проблемы путем развертывания масштабируемого приложения в Контейнерах приложений Azure. Большинство концепций, описанных в этом руководстве, также применимы при масштабировании экземпляров Службы приложений Azure.

Настройка примера проекта

Для работы с этим руководством используйте пример приложения GitHub Explorer. Чтобы клонировать приложение из GitHub, выполните следующую команду.

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

Перейдите в папку /tutorials/scalable-razor-apps/start и откройте файл ScalableRazor.csproj.

В примере приложения используется форма поиска для просмотра репозиториев GitHub по именам. Форма использует встроенные службы защиты данных ASP.NET Core для защиты от подделки. По умолчанию, когда приложение горизонтально масштабируется в Контейнерах приложений, служба защиты данных создает исключение.

Тестирование приложения

  1. Запустите приложение в Visual Studio. Проект содержит файл Docker, который означает, что стрелка рядом с кнопкой запуска может быть выбрана для запуска приложения с помощью программы установки Docker Desktop или стандартного локального веб-сервера ASP.NET Core.

Используйте форму поиска для поиска репозиториев GitHub по имени.

A screenshot showing the GitHub Explorer app.

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

Для развертывания приложения в Контейнерах приложений Azure используется Visual Studio. Контейнеры приложений — это управляемая служба, призванная упростить размещение контейнерных приложений и микрослужб.

Примечание.

Для многих ресурсов приложения требуется расположение. Для данного приложения расположение не важно. Для реального приложения следует выбрать расположение как можно ближе к клиентам. Возможно, это будет расположение рядом с вами.

  1. В обозревателе решений Visual Studio щелкните правой кнопкой мыши узел проекта верхнего уровня и выберите пункт Опубликовать.

  2. В диалоговом окне публикации выберите Azure в качестве цели развертывания, а затем нажмите кнопку Далее.

  3. В качестве целевой платформы выберите Контейнеры приложений Azure (Linux) и нажмите кнопку Далее.

  4. Создайте новое приложение-контейнер для развертывания. Щелкните зеленый значок +, чтобы открыть новое диалоговое окно, и введите следующие значения:

    A screenshot showing Visual Studio deployment.

    • Имя приложения-контейнера: оставьте значение по умолчанию или введите имя.
    • Имя подписки: выберите подписку для развертывания.
    • Группа ресурсов: выберите Создать и создайте группу ресурсов с именем msdocs-scalable-razor.
    • Среда приложений контейнеров: выберите "Создать ", чтобы открыть диалоговое окно среды приложений контейнеров и введите следующие значения:
      • Имя приложения: оставьте значение по умолчанию.
      • Расположение: выберите ближайшее расположение.
      • Рабочая область Azure Log Analytics: выберите Создать, чтобы открыть диалоговое окно рабочей области Log Analytics.
        • Имя: оставьте значение по умолчанию.
        • Расположение: выберите ближайшее расположение и нажмите кнопку ОК, чтобы закрыть диалоговое окно.
      • Нажмите кнопку ОК, чтобы закрыть диалоговое окно среды приложений-контейнеров.
    • Нажмите кнопку Создать, чтобы закрыть исходное диалоговое окно приложений-контейнеров. Visual Studio создает ресурс приложения-контейнера в Azure.
  5. После создания ресурса убедитесь в том, что он выбран в списке приложений-контейнеров, а затем нажмите кнопку Далее.

  6. Вам потребуется создать Реестр контейнеров Azure для хранения опубликованного артефакта образа для приложения. Щелкните зеленый значок + на экране реестра контейнеров.

    A screenshot showing how to create a new container registry.

  7. Оставьте значения по умолчанию и нажмите кнопку Создать.

    A screenshot showing the values for a new container registry.

  8. После создания реестра контейнеров убедитесь в том, что он выбран, а затем нажмите кнопку "Готово", чтобы закрыть диалоговое окно и отобразить сводку по профилю публикации.

    Если в Visual Studio появляется запрос на то, чтобы разрешить администратору доступ к опубликованному контейнеру Docker, выберите Да.

  9. Выберите Опубликовать в правом верхнем углу сводки по профилю публикации, чтобы развернуть приложение в Azure.

По завершении развертывания Visual Studio запустит браузер с размещенным приложением. В поле формы выполните поиск по запросу Microsoft, и отобразится список репозиториев.

Масштабирование и устранение неполадок приложения

В настоящее время приложение работает без проблем, но мы хотели бы масштабировать его, увеличив количество экземпляров с учетом предстоящего роста объема трафика.

  1. На портале Azure найдите приложение-контейнер razorscaling-app-**** с помощью строки поиска вверху и выберите его в результатах.
  2. На странице обзора в области навигации слева выберите Масштабирование, а затем выберите + Изменить и развернуть.
  3. На странице редакций перейдите на вкладку Масштабирование.
  4. Задайте минимальное и максимальное количество экземпляров равным 4, а затем нажмите кнопку Создать. Это изменение конфигурации обеспечивает горизонтальное масштабирование приложения до четырех экземпляров.

Вернитесь к приложению. После загрузки страницы поначалу кажется, что все работает правильно. Однако при вводе и отправке условия поиска может возникнуть ошибка. Если ошибка не происходит, отправьте форму еще несколько раз.

Устранение ошибки

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

  1. На странице обзора приложения-контейнера в области навигации слева выберите Журналы.

  2. На странице Журналы закройте появившееся всплывающее окно и перейдите на вкладку Таблицы.

  3. Разверните элемент Настраиваемые журналы, чтобы увидеть узел ContainerAppConsoleLogs_CL. В этой таблице содержатся различные журналы приложения-контейнера, которые можно запросить для устранения неполадок.

    A screenshot showing the container app logs.

  4. В редакторе запросов составьте простой запрос для поиска в таблице ContainerAppConsoleLogs_CL Logs последних исключений, таких как следующий скрипт:

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

    Предыдущий запрос ищет в таблице ContainerAppConsoleLogs_CL все строки, содержащие слово exception. Результаты упорядочены по времени создания, ограничены 500 строками и включают только столбцы ContainerAppName_s и Log_s, чтобы упростить чтение.

  5. Выберите Выполнить, чтобы отобразить список результатов. Просмотрите записи журналов и обратите внимание, что большинство из них связаны с токенами защиты от подделки и шифрованием.

    A screenshot showing the logs query.

    Важно!

    Ошибки в приложении вызваны службами защиты данных .NET. При запуске нескольких экземпляров приложения нет гарантии того, что HTTP-запрос POST для отправки формы будет направляться в тот же контейнер, который изначально загрузил страницу из HTTP-запроса GET. Если запросы обрабатываются разными экземплярами, токены защиты от подделки обрабатываются неправильно и возникает исключение.

    Далее эта проблема будет устранена путем централизованного размещения ключей защиты данных в службе хранилища Azure и их защиты с помощью Key Vault.

Создание служб Azure

Чтобы устранить предыдущие ошибки, необходимо создать и подключить к приложению следующие службы:

  • Учетная запись хранения Azure: отвечает за хранение данных для служб защиты данных. Позволяет централизованно хранить данные ключей по мере масштабирования приложения. Учетные записи хранения также можно использовать для хранения документов, данных очередей, общих папок и практически любых BLOB-объектов.
  • Azure KeyVault: в этой службе хранятся секреты приложения, и она используется для управления шифрованием в службах защиты данных.

Создание учетной записи хранения

  1. В строке поиска на портале Azure введите Storage accounts и выберите соответствующий результат.
  2. На странице со списком учетных записей хранения выберите + Создать.
  3. На вкладке "Основные сведения" введите следующие значения:
    • Подписка: выберите ту же подписку, которую вы выбрали для приложения-контейнера.
    • Группа ресурсов: выберите созданную ранее группу ресурсов msdocs-scalable-razor.
    • Имя учетной записи хранения: присвойте учетной записи имя scalablerazorstorageXXXX, где X — любые цифры на ваш выбор. Это имя должно быть уникальным в Azure.
    • Регион: выберите тот же регион, который был выбран ранее.
  4. Оставьте остальные значения по умолчанию и щелкните Проверить. После проверки входных данных в Azure нажмите кнопку Создать.

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

Создание контейнера хранилища

Создайте контейнер для хранения ключей защиты данных приложения.

  1. На странице обзора новой учетной записи хранения в области навигации слева выберите Обозреватель хранилища.
  2. Выберите Контейнеры BLOB-объектов.
  3. Выберите команду + Добавить контейнер, чтобы открыть всплывающее меню Новый контейнер.
  4. Введите имя scalablerazorkeys, для остальных параметров оставьте значения по умолчанию и нажмите кнопку Создать.

Новые контейнеры появятся в списке.

Создание службы хранилища ключей

Создайте хранилище для ключей, которые защищают данные в контейнере хранилища BLOB-объектов.

  1. В строке поиска на портале Azure введите Key Vault и выберите соответствующий результат.
  2. На странице описания хранилища ключей нажмите кнопку + Создать.
  3. На вкладке "Основные сведения" введите следующие значения:
    • Подписка: выберите ту же подписку, которая была выбрана ранее.
    • Группа ресурсов: выберите созданную ранее группу ресурсов msdocs-scalable-razor .
    • Имя Key Vault: введите имя scalablerazorvaultXXXXX.
    • Регион: выберите ближайший регион.
  4. Сохраните остальные параметры по умолчанию для остальных параметров и щелкните Просмотреть и создать. Подождите, пока Azure проверит параметры, и нажмите кнопку Создать.

Azure подготовит новое хранилище ключей. По завершении этой задачи выберите команду Перейти к ресурсу, чтобы просмотреть новую службу.

Создание ключа

Создайте секретный ключ для защиты данных в учетной записи хранения BLOB-объектов.

  1. На главной странице обзора хранилища ключей в области навигации слева выберите Ключи.
  2. На странице Создание ключа выберите + Создать или импортировать, чтобы открыть всплывающее меню Создание ключа.
  3. В поле Имя введите razorkey. Оставьте значения по умолчанию для остальных параметров и щелкните Создать. На странице со списком ключей появится новый ключ.

Подключение служб Azure

Приложению-контейнеру требуется безопасное подключение к учетной записи хранения и службе хранилища ключей для устранения ошибок защиты данных и правильного масштабирования. Новые службы подключаются вместе описанным ниже образом.

Важно!

Распространение сведений о назначении ролей безопасности с помощью соединителя сервисов и других средств обычно занимает минуту или две, но в некоторых редких случаях может занять до восьми минут.

Подключение учетной записи хранения

  1. На портале Azure перейдите на страницу обзора приложения-контейнера.
  2. В области навигации слева выберите Соединитель сервисов.
  3. На странице Подключение службы нажмите кнопку "Создать", чтобы открыть панель всплывающего меню "Создание Подключение ion" и введите следующие значения:
    • Контейнер: выберите созданное ранее приложение-контейнер.
    • Тип службы: выберите Хранилище — BLOB-объект.
    • Подписка: выберите ранее использованную подписку.
    • Имя подключения: оставьте значение по умолчанию.
    • Учетная запись хранения: выберите ранее созданную учетную запись хранения.
    • Тип клиента: выберите .NET.
  4. Выберите Далее: проверка подлинности, чтобы перейти к следующему шагу.
  5. Выберите вариант Управляемое удостоверение, назначаемое системой, а затем нажмите кнопку Далее: Сеть.
  6. Оставьте параметры сети по умолчанию и нажмите кнопку Проверка и создание.
  7. После проверки параметров в Azure нажмите кнопку Создать.

Соединитель сервисов включает управляемое удостоверение, назначаемое системой, для приложения-контейнера. Он также назначает удостоверению роль Участник для данных BLOB-объектов хранилища, чтобы оно могло выполнять операции с данными в контейнерах хранилища.

Подключение хранилища ключей

  1. На портале Azure перейдите на страницу обзора приложения-контейнера.
  2. В области навигации слева выберите Соединитель сервисов.
  3. На странице Подключение службы нажмите кнопку "Создать", чтобы открыть панель всплывающего меню "Создание Подключение ion" и введите следующие значения:
    • Контейнер: выберите созданное ранее приложение-контейнер.
    • Тип службы: выберите Key Vault.
    • Подписка: выберите ранее использованную подписку.
    • Имя подключения: оставьте значение по умолчанию.
    • Хранилище ключей: выберите созданное ранее хранилище ключей.
    • Тип клиента: выберите .NET.
  4. Выберите Далее: проверка подлинности, чтобы перейти к следующему шагу.
  5. Выберите вариант Управляемое удостоверение, назначаемое системой, а затем нажмите кнопку Далее: Сеть.
  6. Оставьте параметры сети по умолчанию и нажмите кнопку Проверка и создание.
  7. После проверки параметров в Azure нажмите кнопку Создать.

Соединитель сервисов назначает удостоверению роль, чтобы оно могло выполнять операции с данными в хранилище ключей.

Настройка и повторное развертывание приложения

Необходимые ресурсы Azure созданы. В этом разделе код приложения настраивается для использования новых ресурсов.

  1. Установите следующие пакеты NuGet:

    • Azure.Identity: предоставляет классы для работы со службами управления идентификацией и доступом в Azure.
    • Microsoft.Extensions.Azure: предоставляет полезные методы расширения для выполнения основных операций по настройке в Azure.
    • Azure.Extensions.AspNetCore.DataProtection.Blobs: позволяет хранить ключи ASP.NET Core DataProtection в Хранилище BLOB-объектов Azure, чтобы их можно было использовать совместно в нескольких экземплярах веб-приложения.
    • Azure.Extensions.AspNetCore.DataProtection.Keys: обеспечивает защиту неактивных ключей с помощью функции шифрования и упаковки ключей 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. Обновите Program.cs следующий выделенный код:

    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();
    

Описанные выше изменения позволяют приложению управлять защитой данных с помощью централизованной масштабируемой архитектуры. DefaultAzureCredential обнаруживает ранее включенные конфигурации управляемых удостоверений при повторном развертывании приложения.

Обновите заполнители в разделе AzureURIs файла appsettings.json:

  1. Замените <storage-account-name> заполнитель именем учетной scalablerazorstorageXXXX записи хранения.

  2. Замените <container-name> заполнитель именем scalablerazorkeys контейнера хранилища.

  3. Замените <key-vault-name> заполнитель именем хранилища ключей scalablerazorvaultXXXX .

  4. Замените заполнитель <key-name> в универсальном коде ресурса (URI) хранилища ключей созданным ранее именем razorkey.

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

Повторное развертывание приложения

Теперь приложение правильно настроено для использования созданных ранее служб Azure. Для применения изменений кода повторно разверните приложение.

  1. Щелкните правой кнопкой мыши узел проекта в обозревателе решений и выберите пункт Опубликовать.
  2. В сводном представлении профиля публикации нажмите кнопку Опубликовать в правом верхнем углу.

Visual Studio повторно развернет приложение в созданной ранее среде приложений-контейнеров. По завершении этого процесса запускается браузер и открывается домашняя страница приложения.

Протестируйте приложение еще раз, выполнив поиск по запросу Microsoft в поле поиска. Теперь страница должна каждый раз перезагружаться с правильными результатами.

Настройка ролей для локальной разработки

Существующий код и конфигурация приложения также могут запускаться локально в процессе разработки. Настроенный ранее класс DefaultAzureCredential может получать учетные данные локальной среды для проверки подлинности в службах Azure. Чтобы проходила проверка подлинности, собственной учетной записи потребуется назначить те же роли, которые были назначены управляемому удостоверению приложения. Это должна быть та же учетная запись, которая используется для входа в Visual Studio или Azure CLI.

Вход в локальную среду разработки

Для получения учетных данных классом DefaultAzureCredential потребуется войти в Azure CLI, Visual Studio или Azure PowerShell.

az login

Назначение ролей учетной записи разработчика

  1. На портале Azure перейдите к созданной ранее учетной записи хранения scalablerazor****.
  2. В области навигации слева выберите Управление доступом (IAM).
  3. Нажмите + Добавить, а затем в раскрывающемся меню выберите пункт Добавить назначение ролей.
  4. На странице Добавление назначения ролей выполните поиск по запросу Storage blob data contributor, выберите соответствующий результат и нажмите кнопку Далее.
  5. Убедитесь в том, что выбран вариант Пользователь, группа или субъект-служба, а затем нажмите кнопку + Выбрать участников.
  6. Во всплывающем окне Выбор участников найдите в результатах собственную учетную запись пользователь@домен и выберите ее.
  7. Нажмите кнопку Далее, а затем выберите Проверить и назначить. После проверки параметров в Azure еще раз нажмите кнопку Проверить и назначить.

Как упоминалось ранее, распространение сведений о разрешениях назначения ролей может занять минуту или две, но в редких случаях до восьми минут.

Повторите предыдущие действия, чтобы назначить своей учетной записи роль, предоставляющую доступ к службе и секрету хранилища ключей.

  1. На портале Azure перейдите к созданному ранее хранилищу ключей razorscalingkeys.
  2. В области навигации слева выберите Управление доступом (IAM).
  3. Нажмите + Добавить, а затем в раскрывающемся меню выберите пункт Добавить назначение ролей.
  4. На странице Добавление назначения ролей выполните поиск по запросу Key Vault Crypto Service Encryption User, выберите соответствующий результат и нажмите кнопку Далее.
  5. Убедитесь в том, что выбран вариант Пользователь, группа или субъект-служба, а затем нажмите кнопку + Выбрать участников.
  6. Во всплывающем окне Выбор участников найдите в результатах собственную учетную запись пользователь@домен и выберите ее.
  7. Нажмите кнопку Далее, а затем выберите Проверить и назначить. После проверки параметров в Azure еще раз нажмите кнопку Проверить и назначить.

Возможно, потребуется снова дождаться распространения назначения ролей.

После этого можно вернуться в Visual Studio и запустить приложение локально. Код должен продолжать работать правильно. DefaultAzureCredential использует существующие учетные данные из Visual Studio или Azure CLI.

Надежные шаблоны веб-приложений

См . статью "Шаблон надежных веб-приложений" for.NETвидео и статьи YouTube по созданию современного, надежного, производительного, тестового, экономичного и масштабируемого приложения ASP.NET Core, будь то с нуля или рефакторинг существующего приложения.