Лучшие практики контейнеризации .net-приложений

Контейнеризация с помощью Docker стала основной тенденцией в разработке веб-приложений, которую переняли многие разработчики .NET. Для разработчиков и DevOps-инженеров существует множество неоспоримых преимуществ контейнеризации .NET-приложений, даже при работе с более старыми версиями .NET Framework 4.x. Однако если мы не знаем, как правильно использовать контейнеры, мы не получим от них практически никакой пользы.

В этой статье мы рассмотрим некоторые лучшие практики контейнеризации приложений .NET, в том числе приложений на платформе 4.x. Мы также обсудим использование маленьких образов и сканирование образов для снижения рисков безопасности и удаления ненужных компонентов из наших контейнеров.

Требования

Прежде чем приступить к работе, вам потребуется:

  • Скачать и установить Visual Studio 2022.
  • Иметь локальный клиент Docker для локального запуска контейнеров. Вы можете использовать Docker Desktop, для которого требуется Windows 10 или более поздняя версия. Обязательно выберите установку Windows.
  • Загрузите и установите интерфейс командной строки (CLI) Snyk.
  • Зарегистрируйте бесплатную учетную запись Snyk.

Рассмотрите возможность контейнеризации приложений .NET (даже .NET Framework 4.x)

После выхода .NET Core 1.0 веб-приложения стали кроссплатформенными, портативными и с открытым исходным кодом, что позволило разработчикам перенести их в Docker и получить максимальную отдачу от контейнеризации.

Но если новые версии .NET, работающие в Linux, привлекают наибольшее внимание, то контейнеры для Windows поддерживают старые версии .NET только для Windows, на которые опираются бесчисленные корпоративные приложения. И не каждая организация, поддерживающая веб-приложения .NET Framework, готова перенести их на более новые версии. Вот почему контейнеризация приложений .NET Framework 4.x имеет смысл.

Следующие шаги демонстрируют, как создать и запустить контейнерное приложение ASP.NET Web Forms в Visual Studio 2022.

Сначала запустите Docker Desktop на вашей машине разработки:

В окне Visual Studio Get started выберите Create a new project.

Введите «Web Forms» в текстовое поле Search for templates и выберите ASP.NET Web Application (.NET Framework).

Введите имя для вашего нового приложения (например, WebFormsApp), укажите расположение на диске, выберите .NET Framework 4.8 , и нажмите Создать.

Затем выберите тип Web Forms.

Убедитесь, что опции Web Forms и Docker support отмечены, затем нажмите Create.

Подождите, пока Visual Studio создаст проект. Вот структура проекта, показанная в Visual Studio:

Теперь откройте Docker Desktop. Вы заметите, что контейнер WebFormsApp запущен на порту 61469:

Откройте вкладку Images, чтобы увидеть образ WebFormsApp, с которого запускается контейнер WebFormsApp.

Наконец, нажмите Ctrl + F5, чтобы собрать образ Docker и запустить его локально. Когда образ контейнера собран и запущен в контейнере Docker, Visual Studio запускает веб-приложение в браузере по умолчанию.

Теперь вернитесь в Visual Studio и нажмите на файл Dockerfile:

Это откроет Dockerfile, который конфигурирует ваш проект для запуска в контейнере.

Инструкция FROM инициализирует новый этап сборки и устанавливает базовый образ для последующих инструкций. В данном случае это образ aspnet:4.8-windowsservercore-ltsc2019, который Docker берет из репозитория образов Microsoft.

Конечно, более вероятно, что ваш проект Web Forms изначально не был создан с поддержкой Docker. Чтобы смоделировать эту конкретную ситуацию, создайте новый проект ASP.NET Web Forms, но на этот раз без поддержки Docker:

Теперь давайте добавим Dockerfile в новый проект. Щелкните правой кнопкой мыши на имени проекта, выберите меню Add, а затем подменю Docker Support:

Это заставит Visual Studio автоматически создать проект Dockerfile.

Обратите внимание, что Visual Studio уже выбрала образ и путь к исходному коду, из которого будет сгенерирован контейнер.

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

Делайте образы контейнеров как можно меньше

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

Давайте обсудим некоторые базовые образы, которые разработчики .NET могут рассмотреть для небольших контейнеров. Во-первых, если вы все еще используете ASP.NET Framework 4.x, который не поддерживается в Linux, то единственным вариантом для вас являются контейнеры Windows. Рекомендуемые компанией Microsoft базовые образы для тонких контейнеров — это Windows Server Core и Nano Server.

Windows Server Core — это минимальная ОС с командной строкой для выполнения ролей Windows Server и запуска приложений, не требующих стандартного графического интерфейса Windows. Nano Server — это операционная система, оптимизированная для частных облаков и центров обработки данных. Nano Server не имеет возможности локального входа в систему, имеет меньший размер и перезапускается гораздо быстрее, чем Server Core.

Для .NET Core и .NET 5+ образы SDK следует использовать только для сборки, а образы среды выполнения следует использовать для производственных развертываний как часть многоэтапной сборки. Некоторые достаточно тонкие базовые образы включают образы Debian bullseye-slim-amd64 и Alpine Linux.

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

Теперь давайте попрактикуемся в создании веб-приложения .NET 6 с тонкими образами. Откройте Visual Studio 2022, нажмите Create New Project , и выберите тип ASP.NET Core Web App.

Дайте проекту имя, например WebApp.

Нажмите Next и выберите следующие параметры:

  • .NET 6.0 Framework
  • Тип аутентификации: None
  • Настроить для HTTPS: Установите флажок
  • Включить Docker: Проверьте
  • Docker OS: Linux

Нажмите кнопку Create и наблюдайте новый проект в Visual Studio.

Теперь нажмите F5, чтобы запустить веб-приложение, размещенное в локальном контейнере Docker.

Теперь выполните команду docker images, чтобы получить список образов Docker в вашей системе:

> docker images
Войдите в полноэкранный режим Выйти из полноэкранного режима

В результате выполнения этой команды вы получите что-то вроде следующего:

REPOSITORY TAG IMAGE ID CREATED SIZE
webapp dev e3b51b1eef08 4 hours ago 208MB
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что приложение работает в контейнере Linux, а размер приведенного выше образа веб-приложения составляет 208 МБ.

Далее, давайте уменьшим размер образа контейнера нашего веб-приложения.

Остановите приложение в Visual Studio и откройте файл Dockerfile. Вы увидите следующий блок, инструктирующий Docker извлечь образы dotnet/aspnet:6.0 и dotnet/sdk:6.0 из Microsoft Container Registry (mcr) и использовать их в качестве базовых образов для вашего контейнера приложения:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApp/WebApp.csproj", "WebApp/"]
RUN dotnet restore "WebApp/WebApp.csproj"
COPY . .
WORKDIR "/src/WebApp"
RUN dotnet build "WebApp.csproj" -c Release -o /app/build
Войдите в полноэкранный режим Выйдите из полноэкранного режима

Затем нажмите F5 для повторного запуска приложения. Когда веб-приложение будет запущено, выполните команду docker images, чтобы получить список образов Docker в вашей системе:

> docker images
Войти в полноэкранный режим Выйти из полноэкранного режима

Список образов будет выглядеть следующим образом:

REPOSITORY TAG IMAGE ID CREATED SIZE
webapp dev 778bcd52f366 4 hours ago 100MB
<none> <none> e3b51b1eef08 4 hours ago 208MB
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что образ webapp был перестроен, и его размер теперь составляет 100 МБ (на 108 МБ меньше, чем исходный образ).

Сканирование образов на наличие уязвимостей

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

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

Сканирование контейнеров на наличие уязвимостей необходимо для оценки потенциальных рисков безопасности и принятия соответствующих мер. В данном случае выберем старый образ .NET: mcr.microsoft.com/dotnet/core/aspnet:2.2.

dotnet new webapp -n "AspNet2.2" -f "netcoreapp2.2"
Вход в полноэкранный режим Выйти из полноэкранного режима

Откроем проект в Visual Studio и добавим Dockerfile в новый проект. Щелкните правой кнопкой мыши на имени проекта, выберите меню Add, а затем подменю Docker Support.

Теперь откройте файл Dockerfile и замените его содержимое следующим кодом:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2.105 AS build
WORKDIR /src
COPY ["AspNet2.2.csproj", "."]
RUN dotnet restore "./AspNet2.2.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "AspNet2.2.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "AspNet2.2.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AspNet2.2.dll"]
Вход в полноэкранный режим Выйти из полноэкранного режима

Далее мы посмотрим, как применить сканирование образа, чтобы узнать, насколько уязвим наш контейнер. Сначала выполните CLI-команду docker images, чтобы получить список текущих локальных образов:

docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
aspnet22 latest 223b485f4516 About a minute ago 265MB
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем выполните команду snyk auth для аутентификации в Snyk CLI:

> snyk auth
Войти в полноэкранный режим Выход из полноэкранного режима

После аутентификации учетной записи мы готовы к использованию Snyk CLI. Выполним команду snyk container test <repository>:<tag> для проверки образа, который мы создали локально и сделали доступным в нашем локальном демоне Docker:

> snyk container test aspnet22:latest
Вход в полноэкранный режим Выйти из полноэкранного режима

Команда snyk container test формирует список компонентов, установленных в образе, отправляет этот список в службу Snyk и возвращает список уязвимостей в нашем образе.

В итоге сканирование образа обнаружило 193 уязвимости:

Для мониторинга образа выполните команду snyk container monitor <repository>:<tag>:

> snyk container monitor aspnet22:latest
Вход в полноэкранный режим Выход из полноэкранного режима

Команда snyk container monitor формирует список компонентов, установленных в образе, отправляет этот список в службу Snyk и возвращает ссылку на службу Snyk по адресу http://app.snyk.io/org/{YOUR-ACCOUNT}/, где вы можете увидеть результаты:

3 лучших совета по контейнеризации

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

Несмотря на устойчивое заблуждение, что контейнеры предназначены только для приложений .NET Core, мы видели, как контейнеры могут принести пользу и приложениям .NET Framework 4.x.

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

Наконец, мы увидели, как снизить риски безопасности путем сканирования образов контейнеров и их обновления. Команды Snyk container test и Snyk container monitor — это бесценные инструменты, которые помогают нам сканировать и постоянно контролировать наши .NET-контейнеры на предмет уязвимостей. При правильном использовании контейнеризация может обеспечить дополнительный уровень безопасности и гибкости нашим приложениям, независимо от их возраста.

Защитите свои образы контейнеров бесплатно

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

Зарегистрируйтесь бесплатно

Оцените статью
devanswers.ru
Добавить комментарий