Partilhar via


Visão geral da criação de contêineres do SDK do .NET

Embora seja possível colocar aplicativos .NET em contêineres com um Dockerfile, há motivos convincentes para colocar aplicativos em contêineres diretamente com o SDK do .NET. Este artigo fornece uma visão geral do recurso de criação de contêiner do SDK do .NET, com detalhes relacionados à telemetria, considerações de publicação, propriedades de compilação e autenticação em registros de contêiner.

Considerações sobre o projeto de publicação

Agora que você tem um aplicativo .NET, pode publicá-lo como um contêiner. Antes de o fazer, há várias considerações importantes a ter em mente. Antes da versão 8.0.200 do SDK do .NET, necessitava-se do pacote NuGet 📦Microsoft.NET.Build.Containers. Este pacote não é necessário para o .NET SDK versão 8.0.200 e posterior, pois o suporte ao contêiner está incluído por padrão.

Para habilitar a publicação de um aplicativo .NET como um contêiner, as seguintes propriedades de compilação são necessárias:

  • IsPublishable: Definido como true. Esta propriedade é implicitamente definida como true para tipos de projeto executáveis, como console, webappe worker.
  • EnableSdkContainerSupport: Defina como true quando o tipo de projeto é um aplicativo de console.

Para habilitar explicitamente o suporte ao contêiner SDK, considere o seguinte trecho de arquivo de projeto:

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

Publicar opções e construir propriedades

Como com todos os comandos da CLI do .NET, você pode especificar propriedades do MSBuild na linha de comando. Há muitas formas de sintaxe válidas disponíveis para fornecer propriedades, como:

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

Você é livre para usar qualquer sintaxe que preferir, mas a documentação mostra exemplos usando o -p formulário.

Sugestão

Para ajudar a solucionar problemas, considere usar os logs do MSBuid. Para gerar um ficheiro de log binário (binlog), adicione a -bl switch ao comando dotnet publish. Os arquivos Binlog são úteis para diagnosticar problemas de compilação e podem ser abertos no MSBuild Structured Log Viewer. Eles fornecem um rastreamento detalhado do processo de compilação, essencial para a análise do MSBuild. Para obter mais informações, consulte Solucionar problemas e criar logs para MSBuild.

Publicar perfis e destinos

Ao usar dotnet publish, especificar um perfil com -p PublishProfile=DefaultContainer pode configurar uma propriedade que leva o SDK a acionar outra tarefa após o processo de publicação. Esta é uma forma indireta de alcançar o resultado desejado. Por outro lado, usar dotnet publish /t:PublishContainer invoca diretamente o PublishContainer alvo, alcançando o mesmo resultado, mas de uma forma mais direta.

Em outras palavras, o seguinte comando da CLI do .NET:

dotnet publish -p PublishProfile=DefaultContainer

O que define a PublishProfile propriedade como DefaultContainer, é equivalente ao seguinte comando:

dotnet publish /t:PublishContainer

A diferença entre os dois métodos é que o primeiro usa um perfil para definir a propriedade, enquanto o segundo invoca diretamente o alvo. A razão pela qual isso é importante é que os perfis são um recurso do MSBuild, e eles podem ser usados para definir propriedades de uma maneira mais complexa do que apenas defini-los diretamente.

Uma questão fundamental é que nem todos os tipos de projetos suportam perfis ou têm o mesmo conjunto de perfis disponíveis. Além disso, há uma disparidade no nível de suporte para perfis entre diferentes ferramentas, como o Visual Studio e a CLI do .NET. Por conseguinte, a utilização de metas é geralmente um método mais claro e mais amplamente apoiado para alcançar o mesmo resultado.

Autenticar em registos de contentores

A interação com registros de contêineres privados requer autenticação com esses registros.

O Docker tem um padrão estabelecido com isso por meio do docker login comando, que é uma maneira de interagir com um arquivo de configuração do Docker que contém regras para autenticação com registros específicos. Esse arquivo e os tipos de autenticação que ele codifica são suportados por Microsoft.Net.Build.Containers para autenticação do Registro. Isso deve garantir que este pacote funcione perfeitamente com qualquer registro que você possa docker pull de e docker push. Este arquivo é normalmente armazenado em ~/.docker/config.json, mas pode ser especificado adicionalmente através da DOCKER_CONFIG variável, que aponta para um diretório contendo um arquivo config.json .

Tipos de autenticação

O arquivo config.json contém três tipos de autenticação:

Nome de utilizador/palavra-passe explícito

A auths seção do arquivo config.json é um mapa de chave/valor entre nomes do Registro e cadeias de caracteres de usuário:senha codificadas em Base64. Em um cenário comum do Docker, a execução docker login <registry> -u <username> -p <password> cria novos itens neste mapa. Essas credenciais são populares em sistemas de integração contínua (CI), onde o login é feito por tokens no início de uma execução. No entanto, elas são menos populares para máquinas de desenvolvimento de utilizador final devido ao risco de segurança de ter credenciais desprotegidas num ficheiro.

Auxiliares de credenciais

A credHelpers seção do arquivo config.json é um mapa de chave/valor entre nomes de registro e os nomes de programas específicos que podem ser usados para criar e recuperar credenciais para esse registro. Isso é frequentemente usado quando registros específicos têm requisitos de autenticação complexos. Para que este tipo de autenticação funcione, deves ter um aplicativo chamado docker-credential-{name} no PATH do teu sistema. Esses tipos de credenciais tendem a ser seguros, mas podem ser difíceis de configurar em máquinas de desenvolvimento ou CI.

Chaves do sistema

A credsStore seção é uma propriedade de cadeia de caracteres única cujo valor é o nome de um programa auxiliar de credenciais do docker que sabe como interagir com o gerenciador de senhas do sistema. Para o Windows, isso pode ser wincred , por exemplo. Estes são populares entre os instaladores do Docker para macOS e Windows.

Autenticação via variáveis de ambiente

Em alguns cenários, o mecanismo de autenticação padrão do Docker descrito acima simplesmente não é suficiente. Essa ferramenta tem um mecanismo adicional para fornecer credenciais aos registros: variáveis de ambiente. Se as variáveis de ambiente forem usadas, o mecanismo de fornecimento de credenciais não será usado. As seguintes variáveis de ambiente são suportadas:

  • DOTNET_CONTAINER_REGISTRY_UNAME: Este deve ser o nome de utilizador do registo. Se a senha para o registro é um token, então o nome de usuário deve ser "<token>".
  • DOTNET_CONTAINER_REGISTRY_PWORD: Esta deve ser a senha ou token para o registro.

Observação

A partir do .NET SDK 8.0.400, as variáveis de ambiente para operações de contêiner foram atualizadas. As SDK_CONTAINER_* variáveis agora são prefixadas com DOTNET_CONTAINER_*.

Esse mecanismo é potencialmente vulnerável ao vazamento de credenciais, portanto, só deve ser usado em cenários em que o outro mecanismo não está disponível. Por exemplo, se você estiver usando as ferramentas do contêiner SDK dentro de um contêiner do Docker. Além disso, esse mecanismo não é namespace — ele tenta usar as mesmas credenciais para o registro de origem (onde a imagem base está localizada) e o registro de destino (onde você está enviando a imagem final).

Utilização de registos inseguros

A maioria do acesso ao registro é considerada segura, o que significa que HTTPS é usado para interagir com o registro. No entanto, nem todos os registros são configurados com certificados TLS - especialmente em situações como um registro corporativo privado por trás de uma VPN. Para dar suporte a esses casos de uso, as ferramentas de contêiner fornecem maneiras de declarar que um registro específico usa comunicação insegura.

A partir do .NET 8.0.400, o SDK compreende esses arquivos e formatos de configuração e usará automaticamente essa configuração para determinar se HTTP ou HTTPS devem ser usados. A configuração de um registro para comunicação insegura varia de acordo com a ferramenta de contêiner de sua escolha.

Docker

O Docker armazena sua configuração do Registro na configuração do daemon. Para adicionar novos registos não seguros, novos hosts são adicionados à propriedade "insecure-registries" array.

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

Observação

Você deve reiniciar o daemon do Docker para aplicar quaisquer alterações a esse arquivo.

Podman

Podman usa um registries.conf arquivo TOML para armazenar informações de conexão do registro. Esse arquivo normalmente vive em /etc/containers/registries.conf. Para adicionar novos registros inseguros, uma seção TOML é adicionada para manter as configurações do Registro e, em seguida, a insecure opção deve ser definida como true.

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

Observação

Você deve reiniciar o Podman para aplicar quaisquer alterações ao arquivo registries.conf .

Variáveis de ambiente

A partir de 9.0.100, o SDK do .NET reconhece registros inseguros passados pela variável de DOTNET_CONTAINER_INSECURE_REGISTRIES ambiente. Essa variável usa uma lista separada por vírgulas de domínios para tratar como inseguros da mesma maneira que os exemplos do Docker e do Podman acima.

$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

Telemetria

Quando você publica um aplicativo .NET como um contêiner, as ferramentas de contêiner do SDK do .NET coletam e enviam telemetria de uso sobre como as ferramentas são usadas. Os dados coletados são adicionais à telemetria enviada pela CLI do .NET, mas usam os mesmos mecanismos e, o que é importante, aderem aos mesmos controles de exclusão.

A telemetria recolhida destina-se a ser de natureza geral e não a vazar nenhuma informação pessoal — o objetivo pretendido é ajudar a medir:

  • Uso do recurso de conteinerização do SDK do .NET em geral.
  • Taxas de sucesso e fracasso, juntamente com informações gerais sobre os tipos de falhas que acontecem com mais frequência.
  • Uso de recursos específicos da tecnologia, como publicação para vários tipos de registro, ou como a publicação foi invocada.

Para desativar a telemetria, defina a DOTNET_CLI_TELEMETRY_OPTOUT variável de ambiente como true. Para obter mais informações, consulte Telemetria da CLI do .NET.

Telemetria de inferência

As seguintes informações sobre como o processo de inferência de imagem base ocorreu são registradas:

Ponto de data Explicação Valor da amostra
InferencePerformed Se os usuários estão especificando manualmente imagens de base vs fazendo uso de inferência. true
TargetFramework O TargetFramework escolhido ao realizar a inferência de imagem base. net8.0
BaseImage O valor da imagem base escolhida, mas apenas se essa imagem base for uma das imagens produzidas pela Microsoft. Se um usuário especificar qualquer imagem diferente das imagens produzidas pela Microsoft no mcr.microsoft.com, esse valor será nulo. mcr.microsoft.com/dotnet/aspnet
BaseImageTag O valor da tag escolhida, mas somente se essa tag for para uma das imagens produzidas pela Microsoft. Se um usuário especificar qualquer imagem diferente das imagens produzidas pela Microsoft no mcr.microsoft.com, esse valor será nulo. 8.0
ContainerFamily O valor da ContainerFamily propriedade se um usuário usou o ContainerFamily recurso para escolher um 'sabor' de uma de nossas imagens base. Isso só é definido se o usuário escolheu ou inferiu uma das imagens .NET produzidas pela Microsoft a partir de mcr.microsoft.com jammy-chiseled
ProjectType O tipo de projeto que está sendo conteinerizado. AspNetCore ou Console
PublishMode Como a aplicação foi empacotada. Aot, Trimmed, SelfContainedou FrameworkDependent
IsInvariant Se a imagem escolhida requer globalização invariante ou o usuário optou por ela manualmente. true
TargetRuntime O RID para o qual esta aplicação foi publicada. linux-x64

Telemetria de criação de imagem

As seguintes informações sobre como ocorreu o processo de criação e publicação do contêiner são registradas:

Ponto de data Explicação Valor da amostra
RemotePullType Se a imagem base veio de um registro remoto, que tipo de registro era? Azure, AWS, Google, GitHub, DockerHub, MRC ou outros
LocalPullType Se a imagem base veio de uma fonte local, como um daemon de contêiner ou um tarball. Portuário, Podman, Tarball
RemotePushType Se a imagem foi enviada para um registro remoto, que tipo de registro era? Azure, AWS, Google, GitHub, DockerHub, MRC ou outros
LocalPushType Se a imagem foi enviada para um destino local, qual foi o destino? Portuário, Podman, Tarball

Além disso, se ocorrerem vários tipos de erros durante o processo, esses dados são coletados sobre que tipo de erro foi:

Ponto de data Explicação Valor da amostra
Error O tipo de erro que ocorreu unknown_repository, credential_failure, rid_mismatch, local_load.
Direction Se o erro for um credential_failure, foi para o repositório de push ou pull? push
RID de destino Se o erro foi um rid_mismatch, qual RID foi solicitado linux-x64
RIDs disponíveis Se o erro foi um rid_mismatch, quais RIDs a imagem base suportava? linux-x64,linux-arm64

Ver também