net.core 容器化_尽可能小的完整的容器化.NET Core应用程序微服务

net.core 容器化

net.core 容器化

OK, maybe not technically a microservice, but that's a hot buzzword these days, right? A few weeks ago I blogged about Improvements on ASP.NET Core deployments on Zeit's now.sh and making small container images. By the end I was able to cut my container size in half.

好的,也许从技术上讲不是微服务,但这是近来的热门词汇,对吗? 几周前,我在Zeit的now.sh上写了关于ASP.NET Core部署的改进以及制作小型容器映像的博客。 到最后,我能够将容器的尺寸减半。

The trimming I was using is experimental and very aggressive. If you app loads things at runtime - like ASP.NET Razor Pages sometimes does - you may end up getting weird errors at runtime when a Type is missing. Some types may have been trimmed away!

我使用的修整是实验性的,非常具有侵略性。 如果您的应用程序在运行时加载内容(例如ASP.NET Razor Pages有时会加载),则当缺少Type时,您可能最终在运行时遇到奇怪的错误。 某些类型可能已被修剪掉!

For example:

例如:

fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLGQ1DIEF1KV", Request id "0HLGQ1DIEF1KV:00000001": An unhandled exception was thrown by the application.
System.TypeLoadException: Could not load type 'Microsoft.AspNetCore.Diagnostics.IExceptionHandlerPathFeature' from assembly 'Microsoft.Extensions.Primitives, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Hosting.Internal.HostingApplication.ProcessRequestAsync(Context context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

Yikes!

kes!

I'm doing a self-Contained deployment and then trim the result! Richard Lander has a great dockerfile example. Note how he's doing the package addition with the dotnet CLI with "dotnet add package" and subsequent trim within the Dockerfile (as opposed to you adding it to your local development copy's csproj).

我正在做一个自包含的部署,然后修剪结果! Richard Lander有一个很好的dockerfile示例。 注意他是怎么做的与“DOTNET添加包”和后续的修整的DockerfileDOTNET CLI包除了(而不是你将它添加到你的本地开发副本的的csproj)。

I'm adding the Tree Trimming Linker in the Dockerfile, so the trimming happens when the container image is built. I'm using the dotnet command to "dotnet add package ILLink.Tasks. This means I don't need to reference the linker package at development time - it's all at container build time.

我在Dockerfile中添加了Tree Trimming Linker,因此修剪在构建容器映像时发生。 我使用dotnet命令来“ dotnet添加程序包ILLink.Tasks。这意味着我不需要在开发时引用链接器程序包-一切都在容器构建时进行。

FROM microsoft/dotnet:2.1-sdk-alpine AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.sln .
COPY nuget.config .
COPY superzeit/*.csproj ./superzeit/
RUN dotnet restore

# copy everything else and build app
COPY . .
WORKDIR /app/superzeit
RUN dotnet build

FROM build AS publish
WORKDIR /app/superzeit
# add IL Linker package
RUN dotnet add package ILLink.Tasks -v 0.1.5-preview-1841731 -s https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
RUN dotnet publish -c Release -o out -r linux-musl-x64 /p:ShowLinkerSizeComparison=true

FROM microsoft/dotnet:2.1-runtime-deps-alpine AS runtime
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
WORKDIR /app
COPY --from=publish /app/superzeit/out ./
ENTRYPOINT ["./superzeit"]

I did end up hitting this bug in the Linker (it's not Released) but there's an easy workaround. I just need to set the property CrossGenDuringPublish to false in the project file.

我确实确实在Linker中遇到了此bug (尚未发布),但是有一个简单的解决方法。 我只需要在项目文件中将属性CrossGenDuringPublish设置为false

If you look at the Advanced Instructions for the Linker you can see that you can "root" types or assemblies. Root means "don't mess with these or stuff that hangs off them." So I just need to exercise my app at runtime and make sure that all the types that my app needs are available, but no unnecessary ones.

如果查看链接程序高级说明,您会看到您可以“根”类型或程序集。 根的意思是“不要弄乱这些或悬挂它们的东西”。 因此,我只需要在运行时练习我的应用程序,并确保我的应用程序需要的所有类型都可用,但没有不必要的类型。

I added the Assemblies I wanted to keep (not remove) while trimming/linking to my project file:

我在修剪/链接到我的项目文件时添加了要保留(而不是删除)的程序集:

<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<CrossGenDuringPublish>false</CrossGenDuringPublish>
</PropertyGroup>

<ItemGroup>
<LinkerRootAssemblies Include="Microsoft.AspNetCore.Mvc.Razor.Extensions;Microsoft.Extensions.FileProviders.Composite;Microsoft.Extensions.Primitives;Microsoft.AspNetCore.Diagnostics.Abstractions" />
</ItemGroup>

<ItemGroup>
<!-- this can be here, or can be done all at runtime in the Dockerfile -->
<!-- <PackageReference Include="ILLink.Tasks" Version="0.1.5-preview-1841731" /> -->
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

</Project>

My strategy for figuring out which assemblies to "root" and exclude from trimming was literally to just iterate. Build, trim, test, add an assembly by reading the error message, and repeat.

我确定要“根”并从修剪中排除的程序集的策略实际上只是进行迭代。 通过读取错误消息来构建,修剪,测试,添加装配,然后重复。

This sample ASP.NET Core app will deploy cleanly on Zeit with the smallest image footprint as possible. https://github.com/shanselman/superzeit

此示例ASP.NET Core应用程序将在Zeit上干净地部署,并且图像占用空间尽可能小。 https://github.com/shanselman/superzeit

Next I'll try an actual Microservice (as opposed to a complete website, which is what this is) and see how small I can get that. Such fun!

接下来,我将尝试一个实际的微服务(而不是一个完整的网站,这就是它的意思),看看我能得到多少。 好好玩!

UPDATE: This technique works with "dotnet new webapi" as well and is about 73 megs per "docker images" and it's 34 megs when sent and squished through Zeit's "now" CLI.

更新:此技术也适用于“ dotnet new webapi”,每个“ docker images”大约73兆,通过Zeit的“ now” CLI发送和压缩时为34兆。

Small services!

翻译自: https://www.hanselman.com/blog/a-complete-containerized-net-core-application-microservice-that-is-as-small-as-possible

net.core 容器化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值