Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве вы узнаете, как управлять несколькими контейнерами и взаимодействовать между ними при использовании средств контейнеров в Visual Studio. Для управления несколькими контейнерами требуется оркестрация контейнеров и требуется оркестратор, например Docker Compose. Для этих процедур используется Docker Compose. Docker Compose отлично подходит для локальной отладки и тестирования в ходе цикла разработки.
Полный пример, который вы создали в этом руководстве, можно найти на сайте GitHub https://github.com/MicrosoftDocs/vs-tutorial-samples в папке docker/ComposeSample.
Предпосылки
- Docker Desktop
- Visual Studio с установленной рабочей нагрузкой разработки ASP.NET и веб-разработки, рабочей нагрузкой разработки Azure и (или) кроссплатформенной рабочей нагрузкой разработки .NET . Эта установка включает пакет SDK для .NET.
- Docker Desktop
- Visual Studio с установленной рабочей нагрузкой разработки ASP.NET и веб-разработки, рабочей нагрузкой разработки Azure и (или) кроссплатформенной рабочей нагрузкой разработки .NET . Эта установка включает пакет SDK для .NET.
Создание проекта веб-приложения
В Visual Studio создайте проект ASP.NET Core Web App с именем WebFrontEnd, чтобы создать веб-приложение с помощью страниц Razor.
Не нажимайте кнопку "Включить поддержку контейнеров". Вы добавите поддержку контейнеров позже в процессе.
Создание проекта веб-API
Добавьте проект в то же решение и вызовите его MyWebAPI. Выберите API в качестве типа проекта и снимите флажок " Настроить для HTTPS".
Замечание
В этом проекте мы используем только ПРОТОКОЛ HTTPS для обмена данными с клиентом, а не для обмена данными между контейнерами в одном веб-приложении. Только
WebFrontEndнуждается в HTTPS, и код в примерах предполагает, что вы сняли этот флажок для HTTPS. Как правило, сертификаты разработчика .NET, используемые Visual Studio, поддерживаются только для внешних запросов к контейнерам, а не для запросов контейнеров в контейнер.
Добавьте поддержку кэша Azure для Redis. Добавьте пакет
Microsoft.Extensions.Caching.StackExchangeRedisNuGet (неStackExchange.Redis). В Program.cs добавьте следующие строки непосредственно передvar app = builder.Build().builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = "redis:6379"; // redis is the container name of the redis service. 6379 is the default port options.InstanceName = "SampleInstance"; });Добавьте директивы using в
Program.cs,Microsoft.Extensions.Caching.DistributedиMicrosoft.Extensions.Caching.StackExchangeRedis.using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.StackExchangeRedis;В проекте Web API удалите существующие
WeatherForecast.csи Controllers/WeatherForecastController.cs и добавьте файл в папку Controllers CounterController.cs со следующим содержимым:using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; using StackExchange.Redis; namespace WebApi.Controllers { [ApiController] [Route("[controller]")] public class CounterController : ControllerBase { private readonly ILogger<CounterController> _logger; private readonly IDistributedCache _cache; public CounterController(ILogger<CounterController> logger, IDistributedCache cache) { _logger = logger; _cache = cache; } [HttpGet(Name = "GetCounter")] public string Get() { string key = "Counter"; string? result = null; try { var counterStr = _cache.GetString(key); if (int.TryParse(counterStr, out int counter)) { counter++; } else { counter = 0; } result = counter.ToString(); _cache.SetString(key, result); } catch(RedisConnectionException) { result = "Redis cache is not found."; } return result; } } }Служба увеличивает счетчик при каждом доступе к странице и сохраняет счетчик в кэше.
Добавление кода для вызова веб-API
WebFrontEndВ проекте откройте файл Index.cshtml.cs и заменитеOnGetметод следующим кодом.public async Task OnGet() { // Call *mywebapi*, and display its response in the page using (var client = new System.Net.Http.HttpClient()) { var request = new System.Net.Http.HttpRequestMessage(); // A delay is a quick and dirty way to work around the fact that // the mywebapi service might not be immediately ready on startup. // See the text for some ideas on how you can improve this. // Uncomment if not using healthcheck (Visual Studio 17.13 or later) // await System.Threading.Tasks.Task.Delay(10000); // mywebapi is the service name, as listed in docker-compose.yml. // Docker Compose creates a default network with the services // listed in docker-compose.yml exposed as host names. // The port 8080 is exposed in the WebAPI Dockerfile. // If your WebAPI is exposed on port 80 (the default for HTTP, used // with earlier versions of the generated Dockerfile), change // or delete the port number here. request.RequestUri = new Uri("http://mywebapi:8080/Counter"); var response = await client.SendAsync(request); string counter = await response.Content.ReadAsStringAsync(); ViewData["Message"] = $"Counter value from cache :{counter}"; } }Замечание
В реальном коде вы не должны освобождать
HttpClientпосле каждого запроса. Рекомендации см. в разделе "Использование HttpClientFactory" для реализации устойчивых HTTP-запросов.Универсальный код ресурса (URI) ссылается на имя службы, определенное в файле docker-compose.yml. Docker Compose настраивает сеть по умолчанию для обмена данными между контейнерами с помощью перечисленных имен служб в качестве узлов.
Приведенный здесь код работает с .NET 8 и более поздними версиями, который настраивает учетную запись пользователя в Dockerfile без прав администратора и предоставляет порт 8080, так как порт HTTP по умолчанию 80 недоступен без повышенных привилегий.
Index.cshtmlВ файле добавьте строку для отображенияViewData["Message"], чтобы файл выглядел следующим образом:@page @model IndexModel @{ ViewData["Title"] = "Home page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <p>@ViewData["Message"]</p> </div>Этот код отображает значение счетчика, возвращаемого из проекта веб-API. Он увеличивается каждый раз, когда пользователь обращается к странице или обновляет страницу.
Добавление поддержки Docker Compose
В проекте выберите
WebFrontEnd. Откроется диалоговое окно "Параметры поддержки Docker ".Выберите Docker Compose.
Visual Studio 17.12 и более поздних версий Выберите параметры формирования шаблонов для проекта WebFrontEnd.
Visual Studio 17.11 и более ранних версий Выберите целевую ОС, например Linux.
Visual Studio создает файл docker-compose.yml и еще один
.dockerignoreфайл в узле docker-compose в решении, и этот проект отображается полужирным шрифтом, чтобы показать, что он является стартовым проектом.
Docker-compose.yml отображается следующим образом:
services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/DockerfileФайл
.dockerignoreсодержит типы файлов и расширения, которые не нужно включать в контейнер Docker. Эти файлы обычно связаны с средой разработки и системой управления версиями, а не частью приложения или службы, которую вы разрабатываете.Дополнительные сведения о выполняемых командах см. в разделе "Средства контейнеров " области вывода. Вы увидите, что средство
docker-composeкомандной строки используется для настройки и создания контейнеров среды выполнения.В проекте Web API снова щелкните правой кнопкой мыши на элемент проекта и выберите Добавить>Поддержка оркестратора контейнеров. Выберите Docker Compose и выберите ту же целевую ОС.
Замечание
На этом шаге Visual Studio предложит создать Dockerfile. Если вы делаете это в проекте, который уже поддерживает Docker, вам будет предложено перезаписать существующий Файл Dockerfile. Если вы внесли изменения в Dockerfile, которые вы хотите сохранить, выберите нет.
Visual Studio вносит некоторые изменения в
docker-composeфайл YML. Теперь обе услуги включены.services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi build: context: . dockerfile: MyWebAPI/DockerfileДобавьте кэш в
docker-compose.ymlфайл:redis: image: redisУбедитесь, что отступ находится на том же уровне, что и другие два сервиса.
(Visual Studio 17.13 или более поздней версии) Зависимые службы демонстрируют общую проблему. HTTP-запрос на главной странице внешнего интерфейса может выполняться немедленно при запуске приложения, прежде чем
mywebapiслужба будет готова к получению веб-запросов. Если вы используете Visual Studio 17.13 или более поздней версии, вы можете использовать функцииdepends_onDocker Compose иhealthcheckв docker-compose.yml , чтобы начать проекты в правильной последовательности, и подготовить их к выполнению запросов при необходимости. Смотрите раздел Docker Compose — порядок запуска.services: webfrontend: image: ${DOCKER_REGISTRY-}webfrontend depends_on: mywebapi: condition: service_healthy build: context: . dockerfile: WebFrontEnd/Dockerfile mywebapi: image: ${DOCKER_REGISTRY-}mywebapi depends_on: redis: condition: service_started healthcheck: test: curl --fail http://mywebapi:8080/Counter || exit 1 interval: 20s timeout: 20s retries: 5 build: context: . dockerfile: MyWebAPI/Dockerfile redis: image: redisВ этом примере проверка работоспособности используется
curlдля проверки готовности службы к обработке запросов. Если образ, который вы используете, не имеет установленногоcurl, добавьте строки на этапbaseфайла Dockerfile MyWebAPI для его установки. Для этого шага требуются повышенные привилегии, но вы можете восстановить обычные привилегии пользователя после его установки, как показано здесь (для образов Debian, используемых в этом примере):USER root RUN apt-get update && apt-get install -y curl USER $APP_UIDЗамечание
Если вы используете дистрибутив Linux, например Alpine, который не поддерживает
apt-get, попробуйте вместо этогоRUN apk --no-cache add curl.Для этих функций Docker Compose требуется параметр свойства в файле проекта Docker Compose (
.dcproj). Задайте для свойстваDependencyAwareStartзначение true:<PropertyGroup> <!-- existing properties --> <DependencyAwareStart>true</DependencyAwareStart> </PropertyGroup>Это свойство активирует другой способ запуска контейнеров для отладки, поддерживающего функции зависимости сервисов.
С этими изменениями служба
webfrontendне запустится, покаmywebapiне начнется и успешно не обработает веб-запрос.Первый проект, к которому вы добавляете оркестрацию контейнеров, настраивается для автоматического запуска при запуске или отладке. Действие запуска можно настроить в свойствах проекта Docker Compose. На узле проекта Docker Compose щелкните правой кнопкой мыши, чтобы открыть контекстное меню, а затем выберите пункт "Свойства" или используйте ALT+ВВОД. Например, можно изменить страницу, загруженную путем настройки свойства URL-адреса службы .
Нажмите клавишу F5. Вот что вы видите при запуске:
Контейнеры можно отслеживать с помощью окна "Контейнеры ". Если окно не отображается, используйте поле поиска, нажмите клавиши CTRL+, CTRL+O или нажмите клавиши CTRL+Q. В разделе "Поиск функций" найдите
containersи выберите в списке "Просмотреть>Другие окна Windows>Контейнеры.Разверните узел "Контейнеры решений " и выберите узел для проекта Docker Compose, чтобы просмотреть объединенные журналы на вкладке "Журналы " этого окна.
Вы также можете выбрать узел для отдельного контейнера для просмотра журналов, переменных среды, файловой системы и других сведений.
Настройка профилей запуска
В этом решении используется кэш Azure для Redis, но неэффективно перестраивать контейнер кэша при каждом запуске сеанса отладки. Чтобы избежать этой ситуации, можно настроить несколько профилей запуска. Создайте один профиль, чтобы запустить кэш Azure для Redis. Создайте второй профиль, чтобы запустить другие службы. Второй профиль может использовать контейнер кэша, который уже запущен. В строке меню можно использовать раскрывающийся список рядом с кнопкой "Пуск", чтобы открыть меню с параметрами отладки. Выберите "Управление параметрами запуска Docker Compose".
Откроется диалоговое окно "Управление параметрами запуска Docker Compose ". В этом диалоговом окне можно контролировать, какое подмножество служб запускается во время сеанса отладки, которое запускается с присоединенным отладчиком или без нее, а также службу запуска и URL-адрес. См. раздел Запуск подмножества служб Compose.
Выберите "Создать" , чтобы создать новый профиль и назовите его
Start Redis. Затем установите для контейнера Redis значение Start без отладки, оставьте другой параметр "Не запускать" и нажмите кнопку "Сохранить".
Затем создайте другой профиль
Start My Services, который не запускает Redis, но запускает другие две службы.
(Необязательно) Создайте третий профиль
Start All, чтобы начать все. Вы можете выбрать "Пуск" без отладки для Redis.Выберите "Пуск Redis" в раскрывающемся списке на главной панели инструментов Visual Studio. Контейнер Redis создает и запускается без отладки. Окно "Контейнеры" можно использовать, чтобы увидеть, что оно работает. Затем выберите "Пуск мои службы " из раскрывающегося списка и нажмите клавишу F5 , чтобы запустить их. Теперь контейнер кэша можно запускать во многих последующих сеансах отладки. При каждом использовании Запустить мои службы эти службы используют один и тот же контейнер кэша.
Поздравляем, вы запускаете приложение Docker Compose с пользовательским профилем Docker Compose.
Дальнейшие шаги
Ознакомьтесь с параметрами развертывания контейнеров в Azure. Если вы готовы развернуть приложения контейнеров в Azure, см. статью "Развертывание многоконтейнерного приложения в Azure Container Apps".