.NET 8 容器中的新增功能

本文介绍适用于 .NET 8 的容器中的新功能。

容器映像

已对 .NET 8 的 .NET 容器映像进行了以下更改:

非根用户

映像包括一个 non-root 用户。 该用户使映像具有 non-root 功能。 若要以 non-root 运行,请在 Dockerfile 的末尾添加以下行(或在 Kubernetes 清单中添加类似指令):

USER app

.NET 8 为 non-root 用户的 UID 添加了环境变量,即 64198。 此环境变量适用于 Kubernetes runAsNonRoot 测试,该测试要求通过 UID 而不是按名称设置容器用户。 此 dockerfile 演示了用法示例。

默认端口也从端口 80 更改为 8080。 为支持此更改,可以使用新的环境变量 ASPNETCORE_HTTP_PORTS 来更轻松地更改端口。 该变量接受端口列表,这比 ASPNETCORE_URLS 所需的格式更简单。 如果使用这些变量之一将端口更改回端口 80,则将无法以 non-root 运行。

有关详细信息,请参阅默认 ASP.NET 核心端口从 80 更改为 8080 以及 Linux 映像中新的非根“应用”用户

Debian 12

容器映像现在使用 Debian 12 (Bookworm)。 Debian 是 .NET 容器映像中的默认 Linux 发行版。

有关详细信息,请参阅升级到 Debian 12 的 debian 容器映像

Chiseled Ubuntu 映像

Chiseled Ubuntu 映像可用于 .NET 8。 Chiseled 映像的受攻击面较小,因为它们超级小,没有包管理器或 shell,并且是 non-root。 此类映像适用于希望获得设备式计算优势的开发人员。

默认情况下,Chiseled 映像不支持全球化。 提供 extra 映像,包括 icutzdata 包。

有关全球化和容器的详细信息,请参阅全球化测试应用

生成多平台容器映像

Docker 支持使用和构建可跨多个环境工作的多平台映像。 .NET 8 引入了一种新模式,使你能够将体系结构与生成的 .NET 映像混合和匹配。 例如,如果使用的是 macOS 并希望将 Azure 中的 x64 云服务作为目标,则可以使用 --platform 开关构建映像,如下所示:

docker build --pull -t app --platform linux/amd64

.NET SDK 现在支持 $TARGETARCH 值和还原时的 -a 参数。 以下代码片段演示了一个示例:

RUN dotnet restore -a $TARGETARCH

# Copy everything else and build app.
COPY aspnetapp/. .
RUN dotnet publish -a $TARGETARCH --self-contained false --no-restore -o /app

有关详细信息,请参阅改进多平台容器支持博客文章。

ASP.NET 复合映像

为了提高容器化性能,可以使用新的 ASP.NET Docker 映像,这些映像具有运行时的复合版本。 通过将多个 MSIL 程序集编译为单个随时可以运行的 (R2R) 输出二进制文件来生成此复合。 由于这些程序集嵌入到单个映像中,因此抖动所需的时间更少,并且应用的启动性能也得到提高。 与常规 ASP.NET 映像相比,复合映像的另一大优点是复合映像在磁盘上的大小较小。

有一个需要注意的注意事项。 由于复合映像将多个程序集嵌入到一个程序集中,因此它们的版本耦合更紧密。 应用不能使用自定义版本的框架或 ASP.NET 二进制文件。

复合映像可用于来自 mcr.microsoft.com/dotnet/aspnet 存储库的 Alpine Linux、Ubuntu(“jammy”)Chiseled 和 Mariner Distroless 平台。 这些标记在 ASP.NET Docker 页上列出,它们带有 -composite 后缀。

容器发布

生成的映像默认值

dotnet publish 可以生成容器映像。 它默认生成 non-root 映像,这能帮助应用保持预设安全。 通过设置 ContainerUser 属性(例如设为 root)可以随时更改此默认值。

默认输出容器标记现在为 latest。 此默认值与容器空间中的其他工具一致,使容器更易于在内部开发循环中使用。

性能和兼容性

.NET 8 改进了将容器推送到远程注册表(尤其是 Azure 注册表)的性能。 在一个操作中推送层让速度更快,而对于不支持原子上传的注册表,则通过更可靠的分块机制实现加速。

这些改进还意味着支持更多注册表:Harbor、Artifactory、Quay.io 和 Podman。

身份验证

.NET 8 现支持在将容器推送到注册表时进行 OAuth 令牌交换身份验证(Azure 托管标识)。 此支持意味着现在可以推送到 Azure 容器注册表等注册表,而不会发生任何身份验证错误。 以下命令显示了一个示例发布流:

> az acr login -n <your registry name>
> dotnet publish -r linux-x64 -p PublishProfile=DefaultContainer

若要详细了解如何将 .NET 应用容器化,请参阅使用 dotnet publish 容器化 .NET 应用

发布到 tar.gz 存档

从 .NET 8 开始,可以直接创建容器作为 tar.gz 存档。 如果你的工作流并不简单,并且要求你在推送图像之前对图像运行扫描工具(例如),则此功能会非常有用。 创建存档后,可以移动、扫描或将存档加载到本地 Docker 工具链中。

要发布到存档,请将 ContainerArchiveOutputPath 属性添加到 dotnet publish 命令,例如:

dotnet publish \
  -p PublishProfile=DefaultContainer \
  -p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz

可以指定文件夹名称或包含特定文件名的路径。

另请参阅