Обзор создания контейнера пакета 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 |