乘风破浪,遇见最佳跨平台跨终端框架.Net Core/.Net生态 - 微软和Canonical联手打造.Net 6+Ubuntu 22.04生态

微软和Canonical宣布在Ubuntu 22.04主机和容器中提供本地.NET服务

https://ubuntu.com//blog/install-dotnet-on-ubuntu

image

  • .NET开发者现在可以通过一个"apt install"命令从Ubuntu 22.04 LTS安装ASP.NET和.NET SDK以及运行时。
  • Canonical为.NET 6 LTS和ASP.NET运行时发布了新的、符合OCI标准的超小型设备镜像,无需外壳或软件包管理器。
  • 微软和Canonical正在合作以确保.NET和Ubuntu之间的软件供应链,并提供企业级支持。

Canonical很自豪地欢迎.NET开发平台,这是微软对开源项目最早的贡献之一,从Ubuntu 22.04 LTS开始,它将成为Ubuntu主机和容器镜像的本地体验

.NET开发者将能够从Ubuntu开始他们的Linux之旅,从及时的安全补丁和新版本中获益。

.NET 6用户和开发者现在可以通过简单的apt install dotnet6命令在Ubuntu上安装.NET 6软件包。优化的、预先构建的、超小的容器镜像现在也可以开箱使用。

作为Ubuntu .deb软件包的.NET是微软和Canonical之间紧密合作的结果。这两家公司正在合作,为Ubuntu提供及时的安全补丁和新版本。这是Ubuntu上开源框架后续更多功能的基础,用于主机和最小化的容器镜像。

.NET项目经理Richard Lander说:"与Canonical合作使我们能够同时向.NET开发者提供易用性和改进的安全性。"该项目得益于Canonical在Linux生态系统中的领导地位,以及微软在开发工具和平台方面的深厚经验。其结果是将盒内包和容器镜像结合起来,通过开源使社区开发者和大型企业客户都能受益。"

Canonical产品经理Valentin Viennot说:"Ubuntu现在有一个从开发到生产的端到端故事,从.NET平台开始,支持超小的容器镜像"。"我们认为这对我们两个社区来说都是一个巨大的进步;与微软的.NET团队的合作使我们能够超越自我"。

在Ubuntu上安装.NET 6

有了Canonical软件库的这个新成员,在Ubuntu 22.04 LTS上安装和保持.NET和ASP.NET的更新是很简单的。

# 快速安装SDK和运行时的包
sudo apt update && sudo apt install dotnet6

# 或者根据开发需要按需安装
sudo apt install dotnet-sdk-6.0
sudo apt install dotnet-runtime-6.O
sudo apt install aspnetcore-runtime-6.0

微软和Canonical:为安全而合作

对于所有的开源消费者来说,软件的出处比以往任何时候都更加重要。开源社区和企业都需要对其软件的依赖性有信心。

Canonical和微软已经合作,直接与对方分享内容,没有中间商。微软的.NET项目经理Richard Lander说:"我们现在对所有Canonical的资产来说,实际上是一个零距离的供应链"。

微软最近为.NET建立了一个发行版维护者小组。Canonical现在是该小组的成员,为确保从源头到软件包的软件供应链做出了贡献。

Canonical的软件库继续扩大。迄今为止,已经有超过28000个软件包,为Ubuntu Pro和Ubuntu Advantage用户以及免费社区用户提供了独家和扩展的安全补丁。

及时的安全补丁和发布

.NET和Ubuntu的长期支持(LTS)版本在不同年份发布,但完全一致。.NET LTS在奇数年的11月发布,而Ubuntu LTS则在下一个偶数年的4月发布。

因此,Ubuntu用户在每个Ubuntu LTS系列中都会有一个全新的.NET LTS。这种组合是开发者和软件供应商的合理选择,它结合了两个安全和稳定的产品版本,为他们的应用程序形成一个可信赖的基础。微软和Canonical致力于合作,以确保新的.NET版本与新的Ubuntu版本一起发布,并确保它们能很好地协同工作

在微软和Canonical之间建立最短的信任链对于建立这种伙伴关系至关重要。其结果是一个直接的开发者体验,以及一个定期的安全补丁和更新。

最小的OCI镜像:为.NET删减Ubuntu

.NET开发平台是微软对开源项目最早的贡献之一。其开发者社区由500多万名.NET开发者组成,许多人在运行时采用Linux和基于Linux的OCI容器

自Docker问世以来,Ubuntu一直是使用容器的开发者的热门选择。在Ubuntu上推出.NET的同时,Canonical还提供了一种新型的容器镜像,只由运行时需要的严格的软件包和文件组成

这些"删减"的镜像---所谓的原因是为OCI容器优化的最小Ubuntu镜像所不需要的东西都被砍掉了---解决了开发者对攻击面和镜像大小的反馈,同时不影响Ubuntu的稳定性和熟悉性。

到目前为止,这个过程已经减少了100MB,提供了有史以来最小的基于Ubuntu的OCI镜像,小于6MB(压缩)。Canonical的目标是提供有史以来最小的OCI镜像,同时仍然提供已知和可信赖的Ubuntu内容

Canonical已经为.NET 6发布了两个新的基于Ubuntu的OCI镜像,作为现有LTS镜像组合的一部分进行维护:

这些用于.NET和ASP.NET运行时的首批Ubuntu镜像也可以从Microsoft Artifact Registry(MCR)中获得。

下一步是什么

这个项目是Canonical为.NET和Ubuntu计划的一系列项目中的第一个。在微软的博客上阅读更多关于这种合作关系的信息。

.NET deb包现在已经在Ubuntu Jammy 22.04 LTS的x64架构中,并将很快在Arm64架构以及所有较新的Ubuntu版本中使用。

在Azure容器注册中心和Docker Hub上已经有了预构建的容器镜像。

  • docker.io/ubuntu/dotnet-runtime:6.0-22.04_beta
  • ubuntu.azurecr.io/dotnet-runtime:6.0-22.04_beta
  • docker.io/ubuntu/dotnet-aspnet:6.0-22.04_beta
  • ubuntu.azurecr.io/dotnet-aspnet:6.0-22.04_beta
  • docker.io/ubuntu/dotnet-deps:6.0-22.04_beta
  • ubuntu.azurecr.io/dotnet-deps:6.0-22.04_beta

更多资源

.NET 6已在Ubuntu 22.04中出现

https://devblogs.microsoft.com/dotnet/dotnet-6-is-now-in-ubuntu-2204/

.NET 6现在包含在Ubuntu 22.04(Jammy)中,只需用apt install dotnet6就可以安装。这一变化对Ubuntu用户来说是一个重大的改进和简化。我们还发布了带有Chiseled Ubuntu Containers的.NET,这是Canonical提供的一个新的小型安全容器。这些改进是Canonical和微软之间新的伙伴关系的结果。

下面是在Ubuntu 22.04上安装.NET 6 SDK的命令:

sudo apt update
sudo apt install dotnet6

https://github.com/ubuntu-rocks/dotnet

我们还宣布,.NET 6可与Chiseled Ubuntu Containers一起使用。我们在Canonical的朋友开发了一种新的雕琢方法来制作超小的容器镜像。我们对此感到非常兴奋。Chiseled Ubuntu镜像比你之前一直在使用的Ubuntu镜像小100MB!你可以在这里找到它。

下面是提取新的ASP.NET Chiseled镜像的命令:

docker pull mcr.microsoft.com/dotnet/nightly/aspnet:6.0-jammy-chiseled

我们还更新了我们的dotnetappaspnetapp样本,这样你就可以用Chiseled Ubuntu容器尝试一下.NET。

这些新的容器镜像大大改善了安全状况:

  • 超小的镜像(减少了体积和攻击面)
  • 没有软件包管理器(避免了一整类的攻击)
  • 无shell(避免了一整类的攻击)
  • 非root(避免了一整类的攻击)

最重要的是,Canonical和微软致力于合作,以确保新的.NET版本可以与新的Ubuntu版本一起使用,并且它们可以很好地协同工作。这包括安全更新和容器镜像的安全交付。

我们非常高兴.NET 6可以在Ubuntu 22.04中使用,而且Canonical选择与我们合作,作为他们推出Chiseled Ubuntu镜像的合作伙伴。这是Canonical对这个项目的评价:

Canonical的产品经理Valentin Viennot说:"Ubuntu现在有一个从开发到生产的端到端故事,从.NET平台开始,支持超小型容器镜像"。"我们认为这对我们两个社区来说都是一个巨大的进步;与微软的.NET团队的合作使我们能够超越自我"。

Canonical和微软

几个月前,Canonical和微软的人开始合作,目的是使Ubuntu成为一个对.NET开发者来说更好的环境

我们有两个主要目标:

  • 简化Ubuntu上的.NET使用。
  • 缩短Canonical和微软之间的供应链。

我们已经知道许多.NET开发者使用Ubuntu多年了。在我们讨论之后,很明显,我们可以做很多事情来使这种体验更好。让我告诉你,我们已经交付了什么。

.NET in APT

你现在可以用APT安装.NET 6,由Canonical通过source-build构建。这些软件包可以在Ubuntu 22.04(Jammy)及以后的版本中使用。这是升级到Jammy的一个很好的理由!

这里有多个包:

我将告诉你如何使用Docker安装这些镜像(同样的模式适用于其他地方):

docker run --rm -it ubuntu:jammy
apt update && apt install -y dotnet6
dotnet --version

image

image

image

如果这不起作用,你需要在/etc/apt/sources.list中注册以下来源:

deb http://archive.ubuntu.com/ubuntu/ jammy-updates universe

Canonical和微软将共同努力,确保这些软件包在每月的.NET团队发布计划中得到更新。这包括微软在公开发布前与Canonical分享CVE信息(描述和代码)。同样地,Canonical也会在另一个方向上分享安全信息。

注意:

  • 我们目前缺少Arm64的构建。这些将很快到来。这两家公司都是Arm64的坚定支持者。
  • .NET 7的构建还没有,可能要到.NET 7 GA才会有。
  • .NET SDK工作负载在软件包中是不可用的(对于任何Linux发行版)。另外,Linux上不支持.NET MAUI工作负载。

精雕Ubuntu容器中的.NET

现在你可以在Chiseled Ubuntu容器中使用.NET。Chiseling提供了最小的容器足迹,同时仍然是你所熟悉和信任的Ubuntu。它类似于传统的无发行版,有一个为切分.deb包而定制的工具。

这些镜像比我们到目前为止提供的Ubuntu镜像小100MB,而且不包括根用户。

我们将提供三层Chiseled Ubuntu容器镜像,适用于Arm64和x64,适用于.NET 6和7:

  • 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包:

让我们来看看大小的对比。以下所有的大小都是未压缩的(磁盘上的,不是注册表/线的尺寸)。

首先是runtime-deps层。

  • Ubuntu 22.04 (Jammy): 112MB
  • Chiseled Ubuntu 22.04 (Jammy): 12.9MB

而在另一端,是aspnet层。

  • Ubuntu 22.04 (Jammy): 213MB
  • Chiseled Ubuntu 22.04 (Jammy): 104MB

这确实是一个惊人的差异! Canonical公司的人已经想出了如何从这些图像中减少100MB的二进制文件和其他内容。当我们刚开始讨论的时候,我们根本不知道我们会谈论这么大的差异!

仔细的读者会注意到,chiseled aspnet比现有的runtime-deps层要小。这真是令人震惊的好。

问及Alpine是什么样子的,这很合理。它是一个较新的发行版,从一开始就被设计成超小和组件化。Alpinerunime-deps:6.0-alpine9.84MB,aspnet:6.0-alpine为100MB。这些都是令人印象深刻的数字,也是未经压缩的。这就是为什么Alpine如此受欢迎的关键原因(也是为什么我们多年来一直为它发布.NET镜像)。

Alpine很好(我们也是这些人的朋友),但它并不适合每个人和每个应用程序,因为它使用musl,这是一个不同的(不兼容的)libc变量。这只是在你的应用程序包括本地库时才重要。如果不包括(大多数.NET应用程序不包括),你就不需要担心这个细节。.NET产品本身很乐意使用musl或glibc运行,每一个关于dotnet/runtime的PR都会对这两者进行测试。

从这个角度来看,如果你使用Ubuntu进行开发,并且一直希望有一个小型的Ubuntu来投入生产,这真是个好消息。你现在有了一条从开发箱到云端的直截了当的路径,没有任何发行版兼容的惊喜。看到Ubuntu与Alpine处于同一起跑线上,真是令人惊讶(也相当令人吃惊)。为Canonical的人们在工程上取得的巨大成就而喝彩。

还值得一提的是,Chainguard正在研究最小的容器镜像,以实现安全的未来。该项目是在无发行版的GitHub组织中运行的。我们正在关注这个项目,很高兴看到人们对小型和更安全的容器镜像有更多的兴趣。我们相信最小化+非root容器镜像是未来的趋势

像我们的Alpine镜像一样,我们选择不包括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镜像:mcr.microsoft.com/dotnet/sdk:6.0-jammy 。如果需要精雕的SDK镜像,我们将很乐意重新考虑。

使用精雕的容器镜像

对于大多数应用程序来说,使用这些新的容器镜像,在你的Docker文件的外观方面不会有任何明显的区别。

我们已经更新了我们的样本,以使用这些新的容器镜像。

我将向你展示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"]

只有最后的FROM语句与我们标准的Ubuntu DockerFile不同。

# https://hub.docker.com/_/microsoft-dotnet
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 -r linux-x64

# copy and publish app and libraries
COPY . .
RUN dotnet publish -c Release -o /app -r linux-x64 --self-contained false --no-restore

# final stage/image
FROM mcr.microsoft.com/dotnet/runtime:7.0-jammy-amd64
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["./dotnetapp"]

现在我将构建这个样本:

pwd
docker build -t dotnetapp-chiseled -f Dockerfile.chiseled .
docker images | grep dotnetapp-chiseled

注意:我没有使用任何.NET的修剪功能。当然,这个镜像可以做得更小。

让我们来启动容器:

docker run --rm dotnetapp-chiseled

然后,让我们试着断入:

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.

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容器

Chiseled Ubuntu容器是Canonical对无发行版概念的诠释,最初是由谷歌推广的。在最初的实现中,一个发行版被剥离出来,只安装必要的软件包。Chiseling将这一做法向前推进了一步,只安装每个软件包中必要的目录和文件。

原始实现的另一个挑战是它不一定被任何一方支持。Chiseled Ubuntu 容器是Canonical的一流交付品。这意味着你可以使用超小的容器镜像,并且作为Canonical的客户得到支持。

向谷歌致敬,因为它让我们都开始走这条路。

如前所述,这种方法有很大的价值。

  • 超小的精雕(减少大小和攻击面)
  • 没有软件包管理器(避免了一大类的攻击)。
  • 没有Shell(避免了一整类的攻击)

Chiseled Ubuntu Containers目前正在预览中。当它们在生产中稳定并得到支持时,我们将另行公布。

无root镜像

我们将所有新的.NET Chiseled Ubuntu 容器配置为无root用户。这些镜像不包括root用户,也不包括sudo或su等提升root的命令。这意味着不可能行使需要root的能力和操作。

无root镜像是除删除shell(如bash)之外的另一种安全缓解措施。无root镜像在逻辑上是独立的,是对以无root方式运行守护程序的补充。每一个权限的减少都有帮助。

如果你需要访问特权资源,你可以在你的Docker文件中添加根用户。你不会被阻止这样做,但这是你要做的一个特定的安全决定。

Chiseled镜像是类似于设备的,不是通用的。我们认为它们为我们提供了一个最终提供非root镜像的机会。这为我们今后的政策提供了依据。类似于设备的镜像将以非root身份提供,而通用的镜像将按照基本镜像的政策提供(可能配置了root用户)。然而,这个与Canonical合作的项目启发我们考虑一个中间方案,即提供非root功能的镜像。

安全的供应链

Canonical已经有了安全的流程,可以直接将Ubuntu虚拟机镜像交付给Azure供客户使用。我们想到,Canonical可以用Ubuntu容器基础镜像做同样的事情,我们用它来构建基于Ubuntu的.NET镜像(常规和Chiseled)。这就是我们现在所使用的,而不是从Docker Hub中提取。我们现在对所有Canonical的资产都有一个有效的零距离供应链,并且在整个过程中都有已知的监管/证明。

我们在分享CVE修复方面也做了类似的事情。我们有一个共享的私有虚拟mono repo来分享每月的补丁。这也是与Red Hat共享的。这意味着我们可以一起工作,以协调的方式在正确的时间内获得正确的修复。

.NET容器镜像还没有被签署,但这很快就会到来。我们经常努力提高我们的安全能力。

支持

Canonical和微软一直在合作,为您提供更好的体验。这包括支持。你可以在熟悉的.NET仓库中报告问题,如dotnet/core和dotnet/runtime。如果你想要商业支持,你应该从Canonical支持开始。Canonical是支持Ubuntu软件包的最佳位置。Canonical可能会根据需要联系微软来协助解决问题。

在Canonical提供的.NET软件包中发现漏洞的安全研究人员仍有资格参加微软的.NET赏金计划。

微软继续在其为Ubuntu提供的packages.microsoft.com中维护.NET软件包,我们打算继续这样做下去。对于大多数用户来说,我们建议使用Ubuntu Jammy+附带的dotnet6软件包。这就是我将要做的。这也是我们为红帽用户提供的相同指导。

继续使用微软的软件包有两个主要原因:

  • 你特别想要微软的.NET构建,而不是任何其他供应商的。
  • 微软软件包针对的是后来的.NET SDK功能段(如6.0.4xx),而source-build跟踪的是6.0.1xx。这对Windows用户来说更有意义,但对一些Linux用户可能很重要。

新的软件包可用于.NET 6+和Ubuntu 22.04+。以前的.NET和Ubuntu版本不被支持(新的软件包)。你必须使用现有的packages.microsoft.com feed才能在早期Ubuntu版本上使用.NET。另外,早期的.NET版本在Ubuntu 22.04上不被支持,因为它们不支持OpenSSL v3

下一步是什么

我们已经确定了一些机会,使Canonical能够更容易地使用.NET源代码。我们将在近期内重点关注这些问题。这些改进也将使其他从源代码构建和发布.NET的用户受益。

我们最近为.NET建立了一个发行维护者小组。Canonical是该小组的成员之一。我们已经开始在该论坛中讨论潜在的源代码构建改进。欢迎其他发行版(从源代码构建.NET)加入。请联系dotnet@microsoft.com了解更多信息。

Canonical从支持x64开始,并将迅速增加Arm64的.NET软件包。这是一个令人兴奋的行业时刻,有多种主线芯片架构需要支持。Ubuntu和.NET都有支持多种架构的悠久历史。

结语

.NET已经开放源代码5年多了。在我们在GitHub上开展项目的早期,感觉与Canonical的合作是无法把握的。我们已经学到了很多关于如何构建一个开放源码项目,使其成为Linux发行版中的候选项目。这要感谢我们的其他合作伙伴,他们教会了我们很多,尤其是Fedora和Red Hat。回顾过去,我们不难发现,现在的开源、信任和行业关系比我们开始时更加重要。我们很高兴也很荣幸能与Canonical合作

实操

在WSLg上安装Ubuntu 22.04

如果你已经安装了WSLg,只需要前往商店安装下Ubuntu 22.04即可。

然后通过Windows Terminal进入它。

image

替换Ubuntu包源为国内节点

备份包源

cd /etc/apt && sudo cp sources.list sources.list.bak

image

进入编辑模式

sudo vim sources.list

image

dG清空,再按i进入插入模式,粘贴国内的包源进来。

# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse

image

ESC退出,输入:wq保存退出。

更新包源并安装.Net 6

sudo apt update && sudo apt install dotnet6

image

image

查看版本号,验证安装信息

dotnet --version && dotnet --info

image

参考

posted @ 2022-08-23 23:43  TaylorShi  阅读(300)  评论(0编辑  收藏  举报