Часть 1. Перевод приложений в Aspire
Часть 2. Локальное развертывание с помощью Aspire

Вступление

Надо сказать, что на момент создания первой статьи, эта могла быть отложена на неопределенный срок. А все из-за такого поведения. Если коротко, то aspirate не осуществлял публикацию консольных приложений, это исправили только в ночь с 7 на 8 мая. При этом больше информации о том, что приложения Microsoft.NET.Sdk не публикуются найти не получилось.

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

Подготовка к запуску

Для начала необходимо включить Kubernetes в Docker Desktop, чтобы можно было поднять приложение. Делается это в настройках.

Необходимо выбрать Enable Kubernetes,  после чего применить изменения
Необходимо выбрать Enable Kubernetes, после чего применить изменения

Также необходимо установить aspirate, с помощью этого инструмента осуществляется развертывание приложения в kubernetes.

dotnet tool install --global aspirate --version 8.0.4

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

Также можно установить Kubernetes Dashboard, чтобы просматривать состояние приложений.

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

Исправление консольных приложений

Просто так приложения Microsoft.NET.Sdk не запустятся, для этого необходимо внести следующую правку в их .csproj файл:

<!--Необходимо добавить в файл данный блок-->
<PropertyGroup>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>

Это разрешит публикацию приложения в контейнер.

Также, как оказалось, Aspire не создаст https адрес для API, поэтому нужно исправить строку с созданием фабрики для HttpClient:

// Меняем название переменной окружения на "services__api__http__0"
services.AddHttpClient("WebAPI", x=> x.BaseAddress = new Uri(Environment.GetEnvironmentVariable("services__api__http__0")));

Публикация приложений

Вроде бы все просто: в Readme описан процесс публикации, но есть пара моментов, которые как минимум в моем случае не давали опубликовать приложение (именно из-за этого вынес данный публикацию в отдельную статью), но обо всем по порядку.

Первым делом нужно создать реестр контейнеров:

docker run -d -p 5000:5000 --name registry registry:latest

Лучше создать на порту 5000, а не на 6000, как в руководстве, потому что 6000 порт блокируется браузерами (как минимум Chrome) (на самом деле не критично, но быстро посмотреть список контейнеров может и не получиться).

Следующим шагом нужно инициализировать Aspir8, для этого в папке с проектом выполняем следующую команду:

aspirate init

Дальше нужно настроить параметры инициализации. Обязательно необходимо установить хранилище образов, следующие параметры можно не устанавливать:

Would you like to set a fall-back value for the container registry? [y/n] (n): y
Please enter the container registry to use as a fall-back value: localhost:5000

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

aspirate generate
Would you like to use all previous state values, and skip re-prompting where possible ? [y/n] (y): n

При первом выполнении команды, вторая строка не требуется. Если же сборка выполняется в первый раз, то необходимо установить пароль для шифрования секретов приложения:

Please enter new Password: <Ваш пароль>
Please enter it again to confirm: <Ваш пароль>

Дальше необходимо выбрать компоненты, которые необходимо использовать. В нашем случае выбираем все компоненты. Чтобы выбрать какой-то конкретный компонент, необходимо при его выборе нажать пробел. После этого будет предложено добавить панель Aspire (ту самую, которую видно при запуске проекта через VS, но с урезанным функционалом). Выбираем требуемый вариант, я добавлю ее:

Would you like to deploy the aspire dashboard and connect the OTLP endpoint? [y/n] (y): y

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

После публикации у вас запросят imagePullPolicy для Kubernetes, выбираем IfNotPresent.И последним важным параметров при генерации образов является генерация манифеста для Kubernetes. Его необходимо создать:

Would you like to generate the top level kustomize manifest to run against your kubernetes cluster? [y/n] (y): y

Последним этапом будет развертывание приложения в кластере Kubernetes. Вводим в консоль команду и обязательно выбираем использование предыдущих значений (как минимум в версии Aspir8 (aspirate) 8.0.2 выбор другого варианта приводил к ошибке):

aspirate apply
Would you like to use all previous state values, and skip re-prompting where possible ? [y/n] (y): y

Дальше вводим пароль, используем манифест, сгенерированный этапом раньше:

Would you like to deploy the generated manifests to a kubernetes cluster defined in your kubeconfig file? [y/n] (y): y

И выбираем контекст для публикации (в случае локальной публикации на Windows - docker-desktop). После этого начнется развертывание приложения. Чтобы проверить работоспособность, откроем панель управления Kubernetes. В ней можно увидеть, что все необходимые pods работают исправно:

Теперь посмотрим в панель управления Aspire. Для этого необходимо в командной строке перенаправить порты для Aspire Dashboard с помощью консоли:

kubectl port-forward aspire-dashboard-586bccb649-q8nz7 18888:18888

После чего переходим по адресу localhost:18888 и видим следующее:

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

Заключение

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

Комментарии (4)


  1. buldo
    09.06.2024 09:32

    Aspire выглядит интересным, но можно ли его использовать, если каждый сервис лежит в отдельной репе?


    1. nyarovoy Автор
      09.06.2024 09:32

      В первой части статьи рассматривал переход как раз-таки из отдельных проектов, но там я просто перевел все проекты в новый репозиторий.

      Но действительно может возникнуть проблема с тем, что разрабатывать все сервисы внутри Aspire решения может быть проблематично. Лично я собираюсь эту проблему решать так (не говорю, что метод оптимальный):

      0) Если в репозитории лежит все решение, а не отдельный проект, выделить проект в подмодуль. Например так: https://web.archive.org/web/20170813014246/http://ishmuradov.ru/page/git-otdelit-direktoriju-v-otdelnyj-repozitorij
      Также можно добавить полный существующий репозиторий как подмодуль в Aspire, и просто из него взять проекты, но зачем тащить .sln файл?

      1) В решение каждого сервиса добавить проект ServiceDefaults, в builder'ах добавить AssServiceDefaults()
      2) В Aspire добавить каждый сервис как подмодуль
      3) В случае необходимости запуска сервисов по отдельности для тестов, вставить следующий костыль:

      3.1) При запуске проекта через Aspire передавать переменную среды с заранее определенным именем и значением в случае, если запускается через Aspire.
      3.2) Выделить AddServiceDefaults, а также всю информацию, получаемую из Aspire в if, в котором проверяется существование переменной среды и ее название.
      3.3) Если данной переменной среды не существует, запускать так, как запускалось до перехода в Aspire

      Но в этом своем решении не претендую на истину в последней инстанции.


      1. nyarovoy Автор
        09.06.2024 09:32

        Забыл добавить, что 0 шаг на самом деле не обязателен: Aspire ориентирован на проекты, то есть можно добавить весь репозиторий как подмодуль, но остальные шаги все равно все также обязательны для исполнения


      1. buldo
        09.06.2024 09:32

        Я читаю этот цикл статей и мне начинает казаться, что Aspire - это замена serviceFabric только на стеройдах.