GNU/Linux >> Linux の 問題 >  >> Panels >> Docker

可能な限り小さい、完全にコンテナー化された .NET Core アプリケーション マイクロサービス

OK、技術的にはマイクロサービスではないかもしれませんが、それは最近の流行語ですよね?数週間前、Zeit の now.sh での ASP.NET Core 展開の改善と小さなコンテナー イメージの作成についてブログを書きました。最終的に、コンテナのサイズを半分にすることができました.

私が使用していたトリミングは、実験的で非常に積極的です。アプリが実行時に何かをロードする場合 (ASP.NET Razor Pages が時々行うように)、Type が欠落している場合、実行時に奇妙なエラーが発生する可能性があります。 一部のタイプが削除された可能性があります!

例:

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)

いいね!

自己完結型の展開を行ってから、結果をトリミングしています! Richard Lander は素晴らしい dockerfile の例を持っています。彼が "dotnet add package" を使用して dotnet CLI でパッケージを追加し、その後 within をトリムする方法に注目してください。 Dockerfile (ローカルの開発コピーの csproj に追加するのではなく)。

ツリー トリミング リンカーを Dockerfile に追加しているので、コンテナー イメージのビルド時にトリミングが行われます。私は dotnet コマンドを使用して "dotnet add package 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"]

リンカーでこのバグに遭遇しましたが (リリースされていません)、簡単な回避策があります。プロパティ CrossGenDuringPublish を設定するだけです falseまで

リンカーの高度な手順を見ると、タイプまたはアセンブリを「ルート化」できることがわかります。ルートとは、「これらまたはそれらにぶら下がっているものをいじらないでください」という意味です。したがって、実行時にアプリを実行して、アプリに必要なすべての型が利用可能であり、不要な型がないことを確認するだけで済みます。

プロジェクト ファイルへのトリミング/リンク中に保持したい (削除しない) アセンブリを追加しました:

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

どのアセンブリを「ルート化」してトリミングから除外するかを理解するための私の戦略は、文字通り反復することでした。エラー メッセージを読んで、ビルド、トリム、テスト、アセンブリの追加を繰り返します。

このサンプル ASP.NET Core アプリは、可能な限り最小のイメージ フットプリントで Zeit にクリーンにデプロイされます。 https://github.com/shanselman/superzeit

次に、実際のマイクロサービス (これは完全な Web サイトではなく) を試して、どれだけ小さくできるかを確認します。とても楽しい!

更新: この手法は「dotnet new webapi」でも機能し、「docker images」あたり約 73 メガバイトであり、Zeit の「now」CLI を介して送信および圧縮すると 34 メガメガバイトになります。

スポンサー: Rider 2018.2 が登場! IIS への発行、デバッガーでの Docker のサポート、組み込みのスペル チェック、MacBook Touch Bar のサポート、C# 7.3 の完全なサポート、高度な Unity のサポートなど。


Docker
  1. 可能な限り小さい、完全にコンテナー化された .NET Core アプリケーション マイクロサービス

  2. .NET Core アプリが Docker コンテナーで実行され、XUnit で SkippableFacts が実行されていることを検出する

  3. ASP.NET Core Docker イメージ サイズの最適化

  1. Debian10に.NETCoreをインストールする方法

  2. コア/プリインストール/デフォルトのUbuntuアプリケーションになるアプリケーションの機能は何ですか?

  3. VPS自体で完全なVPSバックアップを取ることは可能ですか?

  1. Visual Basic は Linux 上の .NET Core でサポートされていますか?

  2. 自己完結型の ASP.NET Core アプリケーションを Ubuntu で実行する

  3. Linux 上の .NET コア X509Store