다음을 통해 공유


.NET SDK 컨테이너 만들기 개요

.NET 앱을 Dockerfile을 사용하여 컨테이너화할 수 있지만, .NET SDK를 통해 직접 앱을 컨테이너화하는 것이 더 강력한 이유가 있습니다. 이 문서에서는 원격 분석, 게시 고려 사항, 빌드 속성 및 컨테이너 레지스트리에 대한 인증과 관련된 세부 정보와 함께 .NET SDK 컨테이너 만들기 기능에 대한 개요를 제공합니다.

게시 프로젝트 고려 사항

이제 .NET 앱이 있으므로 컨테이너로 게시할 수 있습니다. 이렇게 하기 전에 유의해야 할 몇 가지 중요한 고려 사항이 있습니다. .NET SDK 버전 8.0.200 이전에는 📦 Microsoft.NET.Build.Containers NuGet 패키지가 필요했습니다. 컨테이너 지원이 기본적으로 포함되므로 .NET SDK 버전 8.0.200 이상에는 이 패키지가 필요하지 않습니다.

.NET 앱을 컨테이너로 게시할 수 있도록 하려면 다음 빌드 속성이 필요합니다.

  • IsPublishable: true로 설정. 실행 가능한 프로젝트 형식인 console, webappworker에 대해 이 속성은 암시적으로 true으로 설정됩니다.
  • 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 사용하여 프로필을 지정하면 게시 프로세스 후에 SDK가 다른 대상을 트리거하도록 하는 속성을 설정할 수 있습니다. 이는 원하는 결과를 달성하는 간접적인 방법입니다. 반면에 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 구성 파일과 상호 작용하는 방법인 docker login 명령을 통해 설정된 패턴이 있습니다. 이 파일과 인코딩하는 인증 유형은 레지스트리 인증을 위해 Microsoft.Net.Build.Containers에서 지원됩니다. 이렇게 하면 이 패키지가 docker pushdocker pull 수 있는 모든 레지스트리에서 원활하게 작동합니다. 이 파일은 일반적으로 ~/.docker/config.json저장되지만 config.json 파일이 포함된 디렉터리를 가리키는 변수를 통해 추가로 지정할 수 있습니다.

인증 종류

config.json 파일에는 세 가지 종류의 인증이 포함되어 있습니다.

명시적 사용자 이름/암호

config.json 파일의 auths 섹션은 레지스트리 이름과 Base64로 인코딩된 username:password 문자열 간의 키/값 맵입니다. 일반적인 Docker 시나리오에서 docker login <registry> -u <username> -p <password> 실행하면 이 맵에 새 항목이 만들어집니다. 이러한 자격 증명은 실행 시작 시 토큰에 의해 로그인이 수행되는 CI(연속 통합) 시스템에서 널리 사용됩니다. 그러나 파일에 자격 증명이 노출되어 있는 보안 위험 때문에 최종 사용자 개발 컴퓨터에서는 덜 인기가 있습니다.

자격 증명 도우미

config.json 파일의 credHelpers 섹션은 레지스트리 이름과 해당 레지스트리에 대한 자격 증명을 만들고 검색하는 데 사용할 수 있는 특정 프로그램의 이름 사이의 키/값 맵입니다. 이는 특정 레지스트리에 복잡한 인증 요구 사항이 있는 경우에 자주 사용됩니다. 이 인증이 작동하려면 시스템의 PATHdocker-credential-{name}이라는 애플리케이션이 있어야 합니다. 이러한 종류의 자격 증명은 안전한 경향이 있지만 개발 또는 CI 머신에서 설정하기 어려울 수 있습니다.

시스템 키체인

credsStore 섹션은 해당 값이 시스템의 암호 관리자와 인터페이스하는 방법을 알고 있는 Docker 자격 증명 도우미 프로그램의 이름인 단일 문자열 속성입니다. Windows의 경우 예를 들어 wincred 수 있습니다. 이러한 기능은 macOS 및 Windows용 Docker 설치 관리자에게 인기가 있습니다.

환경 변수를 통한 인증

일부 시나리오에서는 위에서 설명한 표준 Docker 인증 메커니즘이 충분하지 않습니다. 이 도구에는 레지스트리에 자격 증명을 제공하기 위한 추가 메커니즘인 환경 변수가 있습니다. 환경 변수를 사용하는 경우 자격 증명 제공 메커니즘은 전혀 사용되지 않습니다. 지원되는 환경 변수는 다음과 같습니다.

  • DOTNET_CONTAINER_REGISTRY_UNAME: 레지스트리의 사용자 이름이어야 합니다. 레지스트리의 암호가 토큰인 경우 사용자 이름은 "<token>"합니다.
  • DOTNET_CONTAINER_REGISTRY_PWORD: 레지스트리의 암호 또는 토큰이어야 합니다.

메모

.NET SDK 8.0.400부터 컨테이너 작업에 대한 환경 변수가 업데이트되었습니다. 이제 SDK_CONTAINER_* 변수에는 DOTNET_CONTAINER_*접두사로 지정됩니다.

이 메커니즘은 자격 증명 누출에 잠재적으로 취약하므로 다른 메커니즘을 사용할 수 없는 시나리오에서만 사용해야 합니다. 예를 들어 Docker 컨테이너 자체 내에서 SDK 컨테이너 도구를 사용하는 경우입니다. 또한 이 메커니즘에는 네임스페이스가 지정되지 않습니다. 이 메커니즘은 원본 레지스트리(기본 이미지 위치)와 대상 레지스트리(최종 이미지 위치에 푸시)에 대해 동일한 자격 증명을 사용합니다.

안전하지 않은 레지스트리 사용

대부분의 레지스트리 액세스는 보안으로 간주됩니다. 즉, 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

메모

registries.conf 파일에 변경 내용을 적용하려면 Podman을 다시 시작해야 합니다.

환경 변수

9.0.100부터 .NET SDK는 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 앱을 컨테이너로 게시할 때 .NET SDK 컨테이너 도구는 도구 사용 방법에 대한 사용량 원격 분석을 수집하고 보냅니다. 수집된 데이터는 .NET CLI보낸 원격 분석 외에도 동일한 메커니즘을 사용하며, 중요한 것은동일한 옵트아웃 컨트롤을 준수한다는 것입니다.

수집된 원격 분석은 본질적으로 일반적이고 개인 정보를 유출하지 않기 위한 것입니다. 의도된 목적은 다음을 측정하는 데 도움이 되는 것입니다.

  • .NET SDK 컨테이너화 기능의 전체 사용.
  • 성공 및 실패율과 가장 자주 발생하는 오류 종류에 대한 일반적인 정보입니다.
  • 다양한 레지스트리 종류에 게시하거나 게시를 호출하는 방법과 같은 기술의 특정 기능을 사용합니다.

원격 분석을 수신 거부하려면 DOTNET_CLI_TELEMETRY_OPTOUT 환경 변수를 true로 설정하십시오. 자세한 내용은 .NET CLI 원격 분석을 참조하세요.

유추 원격 분석

기본 이미지 유추 프로세스가 발생한 방법에 대한 다음 정보가 기록됩니다.

날짜 지점 설명 샘플 값
InferencePerformed 사용자가 기본 이미지를 수동으로 지정하는 것과 유추를 사용하는 것 중 하나를 선택하는 경우 true
TargetFramework 기본 이미지 추론 시 선택된 TargetFramework. net8.0
BaseImage 선택한 기본 이미지의 값이지만 해당 기본 이미지가 Microsoft에서 생성된 이미지 중 하나인 경우에만 해당합니다. 사용자가 mcr.microsoft.com Microsoft에서 생성된 이미지 이외의 이미지를 지정하는 경우 이 값은 null입니다. mcr.microsoft.com/dotnet/aspnet
BaseImageTag 선택한 태그의 값이지만 해당 태그가 Microsoft에서 생성된 이미지 중 하나에 대한 경우에만 해당됩니다. 사용자가 mcr.microsoft.com Microsoft에서 생성된 이미지 이외의 이미지를 지정하는 경우 이 값은 null입니다. 8.0
ContainerFamily 사용자가 ContainerFamily 기능을 사용하여 기본 이미지 중 하나의 '맛'을 선택한 경우 ContainerFamily 속성의 값입니다. 이 설정은 사용자가 mcr.microsoft.com Microsoft에서 생성된 .NET 이미지 중 하나를 선택하거나 유추한 경우에만 설정됩니다. 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 오류가 rid_mismatch경우 기본 이미지에서 지원한 RID는 무엇인가요? linux-x64,linux-arm64

참고

  • .NET 앱을 컨테이너로 게시
  • .NET 앱을 컨테이너화 참조