.NET 6 现在包含在 Ubuntu 22.04 (Jammy) 中,只需 .此更改是 Ubuntu 用户的重大改进和简化。我们还发布了带有Chiseled Ubuntu Containers的.NET,这是Canonical提供的一种新的小型安全容器。这些改进是 Canonical 和 Microsoft 之间新合作伙伴关系的结果。apt install dotnet6
以下是在 Ubuntu 22.04 上安装 .NET 6 SDK 的命令:
sudo apt update
sudo apt install dotnet6
我们还宣布.NET 6可以与Chiseled Ubuntu Containers一起使用。我们在Canonical的朋友开发了一种新的凿子方法来制作超小型容器图像。我们对此感到非常兴奋。凿成的 Ubuntu 映像比您迄今为止一直在使用的 Ubuntu 映像小!100MB
以下是提取新 ASP.NET 凿图像的命令:
docker pull mcr.microsoft.com/dotnet/nightly/aspnet:6.0-jammy-chiseled
我们还更新了我们的 dotnetapp 和 aspnetapp 示例,以便您可以使用 Chiseled Ubuntu Containers 试用 .NET。
这些新的容器映像显著改善了安全状况:
- 超小图像(减小大小和攻击面)
- 没有包管理器(避免了一整类攻击)
- 无 shell(避免一整类攻击)
- 非根(避免一整类攻击)
最重要的是,Canonical和Microsoft致力于共同努力,以确保新的.NET版本与新的Ubuntu版本一起提供,并且它们可以很好地协同工作。这包括安全更新和容器映像的安全交付。
我们非常高兴 .NET 6 在 Ubuntu 22.04 中可用,并且 Canonical 选择与我们合作,作为他们 Chiseled Ubuntu 映像的发布合作伙伴。这就是Canonical对这个项目的看法。
“Ubuntu现在有一个端到端的故事,从开发到生产,从超小的容器映像支持,从.NET平台开始,”Canonical产品经理Valentin Viennot说。“我们认为这对我们两个社区来说都是一个巨大的进步。与微软的.NET团队合作使我们能够超越一切。
Canonical 和 Microsoft
几个月前,Canonical和微软的人开始合作,目标是使Ubuntu成为.NET开发人员更好的环境。
我们心中有两个主要目标:
- 简化在 Ubuntu 上使用 .NET 的过程。
- 缩短Canonical和微软之间的供应链。
多年来,我们一直知道许多 .NET 开发人员使用 Ubuntu。在我们交谈之后,很明显,我们可以做一些事情来使这种体验更好。让我告诉您我们交付了什么。
.NET in APT
您现在可以安装带有APT的.NET 6,由Canonical通过源代码构建构建。这些软件包随 Ubuntu 22.04 (Jammy) 及更高版本提供。这是升级到Jammy的一个很好的理由!
注意:请查看此有关使用软件包的通报
。微软。通信
在 Ubuntu 22.04 上,现在 .NET 6 包含在 Ubuntu 中。
有多个包:
dotnet6
— .NET 6 SDK(简称)。dotnet-sdk-6.0
— 同上(长名称)。aspnet-runtime-6.0
— ASP.NET Coredotnet-runtime-6.0
— .NET Runtime
我将向您展示如何使用 Docker 安装这些映像(相同的模型适用于其他地方):
rich@kamloops:~$ docker run --rm -it ubuntu:jammy
root@7d4dfca0ef55:/# apt update && apt install -y dotnet6
root@7d4dfca0ef55:/# dotnet --version
6.0.108
如果这不起作用,您需要在 /etc/apt/sources.list 中注册以下源:
deb http://archive.ubuntu.com/ubuntu/ jammy-updates universe
Canonical 和 Microsoft 将共同努力,确保这些包在每月的 .NET 团队发布计划中更新。这包括 Microsoft 在公开发布之前与 Canonical 共享 CVE 信息(说明和代码)。同样,Canonical将在另一个方向共享安全信息。
笔记:
- 我们目前缺少Arm64版本。这些将很快到来。两家公司都是Arm64的坚定支持者。
- .NET 7 内部版本尚不可用,可能要到 .NET 7 GA 才能发布。
- .NET SDK 工作负荷在包中不可用(对于任何 Linux 发行版)。此外,Linux 不支持 .NET MAUI 工作负载。
凿砌的 Ubuntu 容器中的 .NET
您现在可以在 Chiseled Ubuntu Containers 中使用 .NET。凿刻提供了最小的容器占用空间,同时仍然是您熟悉和信任的Ubuntu。它类似于传统的无发行版,具有为切片包定制的工具。.deb
这些映像比我们迄今为止提供的 Ubuntu 映像小,并且不包含 root 用户!100MB
我们为 Arm64 和 x64、.NET 6 和 7 提供了三层 Chiseled Ubuntu 容器映像:
mcr.microsoft.com/dotnet/nightly/runtime-deps:6.0-jammy-chiseled
mcr.microsoft.com/dotnet/nightly/runtime:6.0-jammy-chiseled
mcr.microsoft.com/dotnet/nightly/aspnet:6.0-jammy-chiseled
注意:图像将在我们的存储库中提供,而凿刻的产品处于预览状态。当它们在生产中得到支持时,我们将发布另一个公告。这将是今年的某个时候,但我们还没有选择一个时间表,因为我们一直专注于基本的支持。nightly
Canonical还通过Docker Hub发布了用于.NET的Chiseled Ubuntu容器映像,其中包括新的APT包:
- https://hub.docker.com/r/ubuntu/dotnet-deps
- https://hub.docker.com/r/ubuntu/dotnet-runtime
- https://hub.docker.com/r/ubuntu/dotnet-aspnet
让我们来看看大小胜利。以下所有大小都是未压缩的(在磁盘上,而不是注册表/线路大小)。
首先是图层。runtime-deps
- Ubuntu 22.04 (Jammy):
112MB
- 凿的 Ubuntu 22.04 (Jammy):
12.9MB
在光谱的另一端,是层。aspnet
- Ubuntu 22.04 (Jammy):
213MB
- 凿的 Ubuntu 22.04 (Jammy):
104MB
这是一个真正惊人的差异!Canonical的人已经想出了如何从这些图像中删除100MB的二进制文件和其他内容。当我们第一次开始交谈时,我们不知道我们会谈论这么大的差异!
密切的读者会注意到凿子比现有层小。这真是太好了。aspnet
runtime-deps
有理由问阿尔派恩是什么样子的。这是一个较新的发行版,从一开始就设计得超级小且组件化。阿尔卑斯是为和为.这些都是令人印象深刻的数字,同样是未压缩的。这就是Alpine如此受欢迎的关键原因(也是我们多年来一直为它发布.NET图像的原因)。9.84MB
runtime-deps:6.0-alpine
100MB
aspnet:6.0-alpine
Alpine很棒(我们也和那些人是朋友),但它并不适合每个人和每个应用程序,因为它使用musl,这是一个不同的(和不兼容的)变体。仅当你的应用包含本机库时,这才重要。如果没有(大多数 .NET 应用没有),则无需担心此详细信息。.NET 产品本身很高兴使用 glibc 或 glibc
和每个 PR 在 dotnet/runtime 测试中运行。libc
musl
从这个角度来看,如果你使用Ubuntu进行开发,并且总是希望一个小的Ubuntu交付到生产中,这真的是个好消息。现在,您拥有了从开发盒到云的简单路径,没有任何发行版兼容性意外。看到 Ubuntu 与 Alpine 处于同一棒球场真是太神奇了(也非常令人惊讶)。向Canonical的人致敬,他们取得了伟大的工程成就。
还值得一提的是,Chainguard正在研究最小的容器映像,以实现安全的未来。该项目是从无发行版的GitHub组织中运行的。我们正在关注该项目,并很高兴看到人们对小型且更安全的容器映像产生了更多兴趣。我们相信最小 + 非根容器映像是未来。
就像我们的阿尔卑斯图像一样,我们选择不包括ICU。它可能会使图像的大小增加一倍。这意味着我们已经启用了全球化不变模式。对于某些应用程序,这很好,并且大小胜利也很棒。对于其他人来说,这是一个交易破坏者。我们可能需要根据反馈调整计划的这一部分。我们已经记录了将ICU添加到图像中的模式。
让我稍微演示一下这些图像,以说明这些图像是如何(故意)受到限制的。
% docker run --rm mcr.microsoft.com/dotnet/nightly/runtime-deps:6.0-jammy-chiseled-amd64
docker: Error response from daemon: No command specified.
See 'docker run --help'.
让我们再试一次。
% docker run --rm mcr.microsoft.com/dotnet/nightly/runtime-deps:6.0-jammy-chiseled-amd64 bash
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown.
哼?怎么了?它们不起作用!这就是重点。这些是类似于设备的容器映像。它们被剥离到最低限度。它们仅用于执行您设计它们要执行的操作。这就是使它们更安全的方面。如果这种体验不舒服,您可以随时使用常规的 Ubuntu 映像。我们将继续提供它们。它们不会消失。
对于运行时和 aspnet 映像,我们决定使用 dotnet –info 作为 ENTRYPOINT,以使体验更加友好和有用。
% docker run --rm mcr.microsoft.com/dotnet/nightly/runtime:6.0-jammy-chiseled
global.json file:
Not found
Host:
Version: 6.0.8
Architecture: arm64
Commit: 55fb7ef977
.NET SDKs installed:
No SDKs were found.
.NET runtimes installed:
Microsoft.NETCore.App 6.0.8 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Download .NET:
https://aka.ms/dotnet-download
Learn about .NET Runtimes and SDKs:
https://aka.ms/dotnet/runtimes-sdk-info
我们不提供凿刻的 SDK 映像。很明显,有强烈的需求。实际上,在某些情况下,凿刻的 SDK 映像可能很难使用。您可以继续使用现有的 Jammy SDK 映像:。如果需要凿刻的 SDK 映像,我们很乐意重新考虑。mcr.microsoft.com/dotnet/sdk:6.0-jammy
使用凿刻的容器映像
对于大多数应用,使用这些新容器映像在外观方面不会有任何显著差异。Dockerfile
我们更新了示例以使用这些新的容器映像:
我将向您展示使用dotnetapp是多么容易。
Dockerfile几乎没有什么不同。
FROM mcr.microsoft.com/dotnet/sdk:7.0-jammy AS build
WORKDIR /source
# copy csproj and restore as distinct layers
COPY *.csproj .
RUN dotnet restore --use-current-runtime
# copy and publish app and libraries
COPY . .
RUN dotnet publish -c Release -o /app --use-current-runtime --self-contained false --no-restore
# final stage/image
FROM mcr.microsoft.com/dotnet/nightly/runtime:7.0-jammy-chiseled
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "dotnetapp.dll"]
只有最后的陈述真正不同于我们的标准 Ubuntu Dockerfile。FROM
现在,我将生成示例:
rich@MacBook-Air-2 dotnetapp % pwd
/Users/rich/git/dotnet-docker/samples/dotnetapp
rich@MacBook-Air-2 dotnetapp % docker build -t dotnetapp-chiseled -f Dockerfile.chiseled .
rich@MacBook-Air-2 dotnetapp % docker images | grep dotnetapp-chiseled
dotnetapp-chiseled latest bf7e125bd182 20 seconds ago 90.5MB
注意:我没有使用任何 .NET 修剪功能。当然,这个图像可以做得更小。
让我们启动容器:
rich@MacBook-Air-2 dotnetapp % docker run --rm dotnetapp-chiseled
42
42 ,d ,d
42 42 42
,adPPYb,42 ,adPPYba, MM42MMM 8b,dPPYba, ,adPPYba, MM42MMM
a8" `Y42 a8" "8a 42 42P' `"8a a8P_____42 42
8b 42 8b d8 42 42 42 8PP""""""" 42
"8a, ,d42 "8a, ,a8" 42, 42 42 "8b, ,aa 42,
`"8bbdP"Y8 `"YbbdP"' "Y428 42 42 `"Ybbd8"' "Y428
.NET 7.0.0-preview.7.22375.6
Linux 5.10.104-linuxkit #1 SMP PREEMPT Thu Mar 17 17:05:54 UTC 2022
OSArchitecture: Arm64
ProcessorCount: 4
TotalAvailableMemoryBytes: 3.83 GiB
然后,让我们尝试闯入:
rich@MacBook-Air-2 dotnetapp % docker run --rm --entrypoint bash dotnetapp-chiseled
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown.
rich@MacBook-Air-2 dotnetapp % docker run --rm --entrypoint apt dotnetapp-chiseled install -y bash curl
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "apt": executable file not found in $PATH: unknown.
我的“红队”技能让我失望了。请注意,这将具有相同的结果。docker exec
现在,我将更详细地描述凿刻的图像,因为您已经看到了它们的实际效果。
凿成的 Ubuntu 容器
凿砌的 Ubuntu 容器是对无发行版概念的规范化演绎,最初由 Google 推广。在原始实现中,发行版被剥离,并且只安装必要的软件包。凿刻通过仅安装每个包中必需的目录和文件,向前迈出了这一步。
原始实现的另一个挑战是它不一定得到任何一方的支持。凿成的 Ubuntu 容器是一流的规范可交付成果。这意味着您可以使用超小型容器映像,并作为规范客户获得支持。
向谷歌致敬,让我们所有人都走上了这条路。
如前所述,这种方法有很多价值:
- 超小图像(减小大小和攻击面)
- 没有包管理器(避免了一整类攻击)
- 无 shell(避免一整类攻击)
凿砌的 Ubuntu 容器目前处于预览状态。当它们在生产中稳定且受支持时,我们将单独发布公告。
非根映像
我们已经为所有新的 .NET Chiseled Ubuntu 容器配置了非 root 用户。映像不包括用户或包含根提升命令,如 或 。这意味着不可能执行需要的功能和操作。root
sudo
su
root
非根映像是除删除 shell(如 )之外的其他安全缓解措施。非 root 映像在逻辑上是独立的,并且与以无根身份运行守护程序相辅相成。特权的每一次减少都会有所帮助。bash
如果需要访问特权资源,可以在 中添加用户。您不会因此而受阻,但这是您要做出的特定安全决策。root
Dockerfile
凿刻的图像类似于设备,不是通用的。我们认为他们为我们提供了最终提供非根映像的机会。这为我们的政策提供了信息。类似设备的映像将作为非 root 映像提供,而通用映像将根据基础映像的策略(可能由用户配置)传送。但是,这个与Canonical合作的项目激发了我们考虑一个中间地带的选择,即提供不支持root的图像。root
安全供应链
Canonical 已经制定了安全流程,可直接将 Ubuntu 虚拟机映像交付到 Azure 供客户使用。我们突然想到,Canonical 可以对 Ubuntu 容器基础映像执行相同的操作,我们使用这些映像来构建基于 Ubuntu 的 .NET 映像(常规和凿成)。这就是我们现在使用的内容,而不是从Docker Hub中提取。我们现在拥有一个有效的零距离供应链,用于所有具有已知托管/来源的规范资产。
我们正在通过共享 CVE 修复程序来执行类似的操作。我们有一个共享的私有虚拟单一存储库,用于共享每月补丁。它也与红帽共享。这意味着我们可以共同努力,以协调的方式在正确的时间获得正确的修复程序。
.NET 容器映像尚未签名,但很快就会推出。我们经常努力提高以安全为中心的功能。
支持
Canonical和微软一直在合作,为你提供更好的体验。这包括支持。您可以在熟悉的 .NET 存储库(如 dotnet/core 和 dotnet/runtime)中报告问题。如果您想要商业支持,则应从规范支持开始。Canonical 是支持 Ubuntu 软件包的最佳位置。Canonical 可能会根据需要与微软联系以协助解决问题。
在 Canonical 提供的 .NET 程序包中发现漏洞的安全研究人员仍有资格参加 Microsoft .NET 赏金计划。
微软继续在其Ubuntu packages.microsoft.com Feed中维护.NET包,我们打算继续这样做。对于大多数用户,我们建议使用 Ubuntu Jammy+ 附带的软件包。这就是我将要做的。这也是我们为红帽用户提供的相同指导。dotnet6
注意:请查看此有关使用软件包的通报
。微软。通信
在 Ubuntu 22.04 上,现在 .NET 6 包含在 Ubuntu 中。
继续使用微软软件包有两个主要原因:
- 您特别希望从 Microsoft 获得 .NET 内部版本,而不是任何其他供应商。
- Microsoft 软件包面向后来的 .NET SDK 功能频段(如 ),而源代码构建跟踪 。这对Windows用户更相关,但对某些Linux用户来说可能很重要。
6.0.4xx
6.0.1xx
新软件包可用于 .NET 6+ 和 Ubuntu 22.04+。不支持以前的 .NET 和 Ubuntu 版本(使用新包)。您必须使用现有源才能在早期 Ubuntu 版本上使用 .NET。另外,Ubuntu 22.04 不支持早期的 .NET 版本,因为它们不支持 OpenSSL v3。packages.microsoft.com
下一步是什么?
我们已经确定了许多机会,使 Canonical 更容易使用 .NET 源代码。我们将在短期内关注这些。这些改进还将使从源代码生成和分发 .NET 的其他用户受益。
我们最近为 .NET 设置了一个发行版维护者组。Canonical 是该组的成员。我们已经开始讨论该论坛中潜在的源代码构建改进。欢迎其他发行版(从源代码构建 .NET)加入。请联系 dotnet@microsoft.com 了解更多信息。
Canonical从支持x64开始,并将为Arm64快速添加.NET包。这是业界激动人心的时刻,需要支持多种主线芯片架构。Ubuntu 和 .NET 在支持多种架构方面都有悠久的历史。
关闭
.NET已经开源了5年多。与Canonical的合作在我们GitHub项目的早期就感觉失控了。我们已经学到了很多关于如何构建OSS项目的知识,以便它成为包含在Linux发行版中的候选者。这要归功于我们的其他合作伙伴,他们教会了我们很多东西,尤其是 Fedora 和 Red Hat。回顾过去,很容易看出,开源、信任和行业关系现在比我们刚开始时更重要。我们很高兴也很荣幸能与Canonical合作。