GNU/Linux >> Belajar Linux >  >> Panels >> Docker

Layanan mikro Aplikasi .NET Core terkemas lengkap yang sekecil mungkin

Oke, mungkin secara teknis bukan layanan mikro, tapi itu kata kunci yang populer akhir-akhir ini, bukan? Beberapa minggu yang lalu saya membuat blog tentang Peningkatan pada penerapan ASP.NET Core di Zeit's now.sh dan membuat gambar wadah kecil. Pada akhirnya saya bisa memotong ukuran wadah saya menjadi dua.

Pemangkasan yang saya gunakan bersifat eksperimental dan sangat agresif. Jika aplikasi Anda memuat hal-hal saat runtime - seperti yang kadang-kadang dilakukan oleh ASP.NET Razor Pages - Anda mungkin akan mendapatkan kesalahan aneh saat runtime ketika Jenis hilang. Beberapa jenis mungkin telah dipangkas!

Misalnya:

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)

Astaga!

Saya melakukan penerapan mandiri dan kemudian memangkas hasilnya! Richard Lander memiliki contoh dockerfile yang bagus. Perhatikan bagaimana dia melakukan penambahan paket dengan CLI dotnet dengan "dotnet add package" dan trim berikutnya dalam Dockerfile (sebagai lawan Anda menambahkannya ke csproj salinan pengembangan lokal Anda).

Saya menambahkan Tree Trimming Linker di Dockerfile, jadi pemangkasan terjadi saat image container dibuat. Saya menggunakan perintah dotnet untuk "dotnet add package ILLink.Tasks. Ini berarti saya tidak perlu merujuk paket linker pada waktu pengembangan - semuanya pada waktu pembuatan container.

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

Saya akhirnya menemukan bug ini di Linker (ini tidak Dirilis) tetapi ada solusi yang mudah. Saya hanya perlu mengatur properti CrossGenDuringPublish ke false dalam file proyek.

Jika Anda melihat Petunjuk Lanjutan untuk Linker, Anda dapat melihat bahwa Anda dapat "meng-root" jenis atau rakitan. Root berarti "jangan main-main dengan ini atau hal-hal yang menggantung dari mereka." Jadi saya hanya perlu menjalankan aplikasi saya saat runtime dan memastikan bahwa semua jenis yang dibutuhkan aplikasi saya tersedia, tetapi tidak ada yang tidak perlu.

Saya menambahkan Majelis yang ingin saya simpan (bukan hapus) saat memangkas/menautkan ke file proyek saya:

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

Strategi saya untuk mencari tahu rakitan mana yang harus "di-root" dan dikecualikan dari pemangkasan secara harfiah hanya mengulangi. Bangun, potong, uji, tambahkan rakitan dengan membaca pesan kesalahan, dan ulangi.

Contoh aplikasi ASP.NET Core ini akan diterapkan dengan bersih di Zeit dengan jejak gambar sekecil mungkin. https://github.com/shanselman/superzeit

Selanjutnya saya akan mencoba Microservice yang sebenarnya (sebagai lawan dari situs web lengkap, yang merupakan apa ini) dan melihat seberapa kecil saya bisa mendapatkannya. Sangat menyenangkan!

PERBARUI: Teknik ini bekerja dengan "dotnet webapi baru" juga dan sekitar 73 MB per "gambar buruh pelabuhan" dan 34 MB saat dikirim dan ditekan melalui CLI "sekarang" Zeit.

Sponsor: Pengendara 2018.2 ada di sini! Menerbitkan ke IIS, dukungan Docker di debugger, pemeriksaan ejaan bawaan, dukungan MacBook Touch Bar, dukungan penuh C# 7.3, dukungan Unity lanjutan, dan banyak lagi.


Docker
  1. Cara Menginstal .NET Core di Debian 10

  2. Apa Saja Fitur Aplikasi yang Menjadi Aplikasi Ubuntu Inti/pra-instal/default?

  3. Mengoptimalkan ukuran Gambar ASP.NET Core Docker

  1. Apakah mungkin untuk mengambil cadangan VPS lengkap di VPS itu sendiri?

  2. Layanan mikro Aplikasi .NET Core terkemas lengkap yang sekecil mungkin

  3. Mendeteksi bahwa aplikasi .NET Core berjalan di Docker Container dan SkippableFacts di XUnit

  1. Apakah Visual Basic didukung oleh .NET Core di Linux?

  2. Menjalankan aplikasi ASP.NET Core mandiri di Ubuntu

  3. .NET core X509Store di linux