Поделиться через


Обзор создания контейнера пакета SDK для .NET

Хотя можно контейнеризировать приложения .NET с помощью Dockerfile, существуют убедительные причины для контейнеризации приложений непосредственно с помощью .NET SDK. В этой статье представлен обзор функции создания контейнера пакета SDK для .NET с подробными сведениями о телеметрии, публикации, свойствах сборки и проверке подлинности в реестрах контейнеров.

Рекомендации по публикации проекта

Теперь, когда у вас есть приложение .NET, его можно опубликовать в виде контейнера. Перед этим следует учитывать несколько важных аспектов. До пакета SDK для .NET версии 8.0.200 необходимо 📦 пакет NuGet microsoft.NET.Build.Containers. Этот пакет не требуется для пакета SDK для .NET версии 8.0.200 и более поздних версий, так как поддержка контейнеров включена по умолчанию.

Чтобы включить публикацию приложения .NET в качестве контейнера, требуются следующие свойства сборки:

  • IsPublishable: задано значение true. Это свойство неявно устанавливается на значение true для типов исполняемых проектов, таких как console, webappи worker.
  • EnableSdkContainerSupport. Установите значение true, если тип проекта является консольным приложением.

Чтобы явно включить поддержку контейнеров SDK, рассмотрите следующий фрагмент кода файла проекта:

<PropertyGroup>
  <IsPublishable>true</IsPublishable>
  <EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>

Публикация коммутаторов и свойств сборки

Как и во всех командах .NET CLI, вы можете указать свойства MSBuild в командной строке. Существует множество допустимых форм синтаксиса, доступных для предоставления свойств, таких как:

  • /p:PropertyName=Value
  • -p:PropertyName=Value
  • -p PropertyName=Value
  • --property PropertyName=Value

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

Совет

Чтобы устранить неполадки, рассмотрите возможность использования журналов MSBuid. Чтобы создать файл двоичного журнала (binlog), добавьте параметр -bl в команду dotnet publish. Файлы binlog полезны для диагностики проблем сборки и могут быть открыты в средстве просмотра структурированных журналов MSBuild. Они предоставляют подробную трассировку процесса сборки, необходимую для анализа MSBuild. Дополнительные сведения см. в статье Устранение неполадок и создание журналов для MSBuild.

Публикация профилей и целевых объектов

При использовании dotnet publishуказание профиля с -p PublishProfile=DefaultContainer может задать свойство, которое приводит к активации другого целевого объекта после процесса публикации. Это косвенный способ достижения желаемого результата. С другой стороны, использование dotnet publish /t:PublishContainer напрямую вызывает целевой объект PublishContainer, добиваясь того же результата, но более просто.

Другими словами, следующая команда .NET CLI:

dotnet publish -p PublishProfile=DefaultContainer

Которое устанавливает для свойства PublishProfile значение DefaultContainer, что эквивалентно следующей команде:

dotnet publish /t:PublishContainer

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

Одна из ключевых проблем заключается в том, что не все типы проектов поддерживают профили или имеют одинаковый набор профилей. Кроме того, существует неравенство в уровне поддержки профилей между различными инструментами, такими как Visual Studio и .NET CLI. Поэтому использование целевых объектов обычно является более четким и широко поддерживаемым методом для достижения того же результата.

Аутентификация в реестрах контейнеров

Для взаимодействия с частными реестрами контейнеров требуется проверка подлинности с этими реестрами.

Docker имеет установленный шаблон с помощью команды docker login, которая является способом взаимодействия с файлом конфигурации Docker, который содержит правила проверки подлинности с определенными реестрами. Этот файл и типы проверки подлинности, которые он кодирует, поддерживаются Microsoft.Net.Build.Containers для проверки подлинности реестра. Это должно обеспечить беспрепятственную работу этого пакета с любым реестром, из которого вы можете docker pull и docker push. Этот файл обычно хранится в ~/.docker/config.json, но его можно указать дополнительно с помощью переменной DOCKER_CONFIG, которая указывает на каталог, содержащий файл config.json.

Типы проверки подлинности

Файл config.json содержит три типа проверки подлинности:

Явное имя пользователя и пароль

Раздел auths файла config.json — это сопоставление ключей и значений между именами реестра и строками имени пользователя:password в кодировке Base64. В обычном сценарии Docker выполнение docker login <registry> -u <username> -p <password> создает новые элементы на этой карте. Эти учетные данные популярны в системах непрерывной интеграции (CI), где авторизация осуществляется с помощью токенов в начале выполнения. Однако они менее популярны для машин, используемых конечными пользователями для разработки, из-за риска безопасности наличия открытых учетных данных в файле.

Помощники для управления учетными данными

Раздел credHelpers файла config.json — это сопоставление ключей и значений между именами реестра и именами определенных программ, которые можно использовать для создания и получения учетных данных для этого реестра. Это часто используется, если определенные реестры имеют сложные требования к проверке подлинности. Чтобы эта проверка подлинности работала, необходимо иметь приложение с именем docker-credential-{name} в PATHвашей системы. Эти типы учетных данных, как правило, защищены, но могут быть трудно настроить на компьютерах разработки или CI.

Системная цепочка ключей

Раздел credsStore — это одно строковое свойство, значение которого — имя вспомогательной программы учетных данных Docker, которая знает, как интерфейсировать с диспетчером паролей системы. Например, для Windows это может быть wincred. Они популярны в установщиках Docker для macOS и Windows.

Проверка подлинности с помощью переменных среды

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

  • DOTNET_CONTAINER_REGISTRY_UNAME. Это должно быть имя пользователя для реестра. Если пароль для реестра является паролем, то имя пользователя должно быть "<token>".
  • DOTNET_CONTAINER_REGISTRY_PWORD. Это должен быть пароль или маркер для реестра.

Заметка

По состоянию на пакет SDK для .NET 8.0.400 переменные среды для операций контейнеров были обновлены. Теперь переменные SDK_CONTAINER_* префиксируются DOTNET_CONTAINER_*.

Этот механизм потенциально уязвим для утечки учетных данных, поэтому его следует использовать только в сценариях, где другой механизм недоступен. Например, если вы используете инструменты SDK Container в Docker-контейнере. Кроме того, этот механизм не поддерживает пространства имен — он пытается использовать одни и те же учетные данные для реестра источника (где находится ваш базовый образ) и целевого реестра (куда отправляется окончательный образ).

Использование небезопасных реестров

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

Начиная с .NET 8.0.400, пакет SDK понимает эти файлы конфигурации и форматы и автоматически будет использовать такую конфигурацию, чтобы определить, следует ли использовать HTTP или HTTPS. Настройка реестра для небезопасного взаимодействия зависит от выбранного средства контейнера.

Докер

Docker сохраняет конфигурацию реестра в конфигурации демона. Чтобы добавить новые небезопасные реестры, новые узлы добавляются в свойство массива "insecure-registries":

{
  "insecure-registries": [
    "registry.mycorp.net"
  ]
}

Заметка

Чтобы применить изменения к этому файлу, необходимо перезапустить управляющая программа Docker.

Podman

Podman использует registries.conf TOML-файл для хранения сведений о подключении реестра. Этот файл обычно находится в /etc/containers/registries.conf. Чтобы добавить новые небезопасные реестры, добавляется раздел TOML для хранения параметров реестра, то параметр insecure должен быть установлен на true.

[[registry]]
location = "registry.mycorp.net"
insecure = true

Заметка

Необходимо перезапустить Podman, чтобы применить любые изменения к файлу registries.conf.

Переменные среды

Начиная с версии 9.0.100 пакет SDK для .NET распознает небезопасные реестры, передаваемые через переменную среды DOTNET_CONTAINER_INSECURE_REGISTRIES. Эта переменная принимает разделенный запятыми список доменов для рассмотрения как небезопасными, аналогично примерам Docker и Podman выше.

$Env:DOTNET_CONTAINER_INSECURE_REGISTRIES=localhost:5000,registry.mycorp.com; dotnet publish -t:PublishContainer -p:ContainerRegistry=registry.mycorp.com -p:ContainerBaseImage=localhost:5000/dotnet/runtime:9.0

Телеметрия

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

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

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

Чтобы отказаться от телеметрии, задайте для переменной среды DOTNET_CLI_TELEMETRY_OPTOUT значение true. Для получения дополнительной информации см. информацию о телеметрии .NET CLI в .

Анализ телеметрии

Ниже приведены сведения о том, как произошл процесс вывода базового образа:

Точка даты Объяснение Примерное значение
InferencePerformed Если пользователи вручную указывают базовые образы вместо использования механизмов вывода. true
TargetFramework TargetFramework, выбранный при выводе базового образа. net8.0
BaseImage Значение выбранного базового образа, но только в том случае, если этот базовый образ является одним из созданных корпорацией Майкрософт образов. Если пользователь указывает любой образ, отличный от образов, созданных корпорацией Майкрософт на mcr.microsoft.com, это значение равно NULL. mcr.microsoft.com/dotnet/aspnet
BaseImageTag Значение выбранного тега, но только в том случае, если этот тег предназначен для одного из созданных корпорацией Майкрософт образов. Если пользователь указывает любой образ, отличный от образов, созданных корпорацией Майкрософт на mcr.microsoft.com, это значение равно NULL. 8.0
ContainerFamily Значение свойства ContainerFamily, если пользователь использовал функцию ContainerFamily для выбора "вкуса" одного из базовых образов. Это значение устанавливается только в том случае, если пользователь выбрал или вывел один из созданных Microsoft образов .NET из mcr.microsoft.com jammy-chiseled
ProjectType Тип проекта, который подлежит контейнеризации. AspNetCore или Console
PublishMode Как было упаковано приложение. Aot, Trimmed, SelfContainedили FrameworkDependent
IsInvariant Если для выбранного изображения требуется инвариантная глобализация или пользователь выбрал его вручную. true
TargetRuntime RID, для которого было опубликовано это приложение. linux-x64

Телеметрия создания изображения

Ниже приведены сведения о том, как выполняется процесс создания и публикации контейнера:

Точка даты Объяснение Пример значения
RemotePullType Если базовый образ был получен из удаленного реестра, какой именно реестр был? Azure, AWS, Google, GitHub, DockerHub, MRC или Другие
LocalPullType Если базовый образ был получен из локального источника, например управляющей программы контейнера или tarball. Docker, Podman, Tarball
RemotePushType Если образ был отправлен в удаленный реестр, какой именно реестр был? Azure, AWS, Google, GitHub, DockerHub, MRC или Другие
LocalPushType Если изображение было отправлено в локальное место назначения, что это было? Docker, Podman, Tarball

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

Точка даты Объяснение Пример значения
Error Тип ошибки, которая произошла unknown_repository, credential_failure, rid_mismatch, local_load.
Direction Если ошибка является credential_failure, была ли она в реестре отправки или извлечения? push
Целевой объект RID Если ошибка была rid_mismatch, какой RID был запрошен? linux-x64
Доступные ИДЕНТИФИКАТОРЫ Если ошибка была rid_mismatch, какие идентификаторы RID поддерживал базовый образ? linux-x64,linux-arm64

См. также