dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.18k stars 4.72k forks source link

Statically linked cloud native executables - FROM SCRATCH containers #80654

Closed kant2002 closed 1 year ago

kant2002 commented 1 year ago

I have done experimental PR with support for making AOT web server statically linked, like Go and Graal for example.

I would like .NET have similar abilities, even with some harsh limitations (like now), mostly to be used in distroless containers for simple microservices. For accessing services over HTTPS in statically linked executables I need OpenSSL to be statically linked. That's trade-off from security perspective where old and potentially buggy OpenSSL would be in you executable, but for cloud native applications or just dockerized apps, deployment pipeline always can re-create said images, so that would risk can be mitigated by using proper dev practices.

Based on experiments minimum baseline size for such images dropped to 23.5MB from 34MB if I use Chiselled Ubuntu.

That does not solve other potential issues within this scenario, like DB access (probably ODBC would work), and other libraries with native dependencies, but I expect other work (like Woodwork) will help here and maybe community work too.

Repo with experiment on Docker containers - https://github.com/kant2002/NativeAOTDocker

ghost commented 1 year ago

Tagging subscribers to this area: @dotnet/area-meta See info in area-owners.md if you want to be subscribed.

Issue Details
I have done [experimental PR](https://github.com/dotnet/runtime/pull/80380) with support for making AOT web server statically linked, like Go and [Graal](https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/) for example. I would like .NET have similar abilities, even with some harsh limitations (like now), mostly to be used in distroless containers for simple microservices. For accessing services over HTTPS in statically linked executables I need OpenSSL to be statically linked. That's trade-off from security perspective where old and potentially buggy OpenSSL would be in you executable, but for cloud native applications or just dockerized apps, deployment pipeline always can re-create said images, so that would risk can be mitigated by using proper dev practices. Based on experiments minimum baseline size for such images dropped to 23.5MB from 34MB if I use Chiselled Ubuntu. That does not solve other potential issues within this scenario, like DB access (probably ODBC would work), and other libraries with native dependencies, but I expect other work (like Woodwork) will help here and maybe community work too. Repo with experiment on Docker containers - https://github.com/kant2002/NativeAOTDocker
Author: kant2002
Assignees: -
Labels: `area-Meta`, `untriaged`
Milestone: -
kant2002 commented 1 year ago

/cc @davidfowl @jkotas @am11 @blowdart

am11 commented 1 year ago

Great! This will also help running .NET 8 published apps with -p:'PublishAot=true;StaticExecutable=true;StaticIcuLinking=true;StaticOpenSslLinking=true;StaticNumaLinking=true' in unikernels such as nanos with no runtime dependency headches https://github.com/nanovms/ops-examples/issues/47#issuecomment-1382082451.

I think the answer to questions like 'what about security updates' is that these slim / headless environments are essentially OS less. The app is the OS (well, it is the trimmed version of build machine OS). When there is a security update available on the build machine, user is expected to update the build machine, re-publish the app and recreate the freestanding image.

cc @eyberg, @francescolavra, .NET 8 is still in development, we are using alpha version for these experiments.

jkotas commented 1 year ago

cc @eerhardt

benaadams commented 1 year ago

Does bflat help at all? https://flattened.net/

@MichalStrehovsky

ghost commented 1 year ago

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas See info in area-owners.md if you want to be subscribed.

Issue Details
I have done [experimental PR](https://github.com/dotnet/runtime/pull/80380) with support for making AOT web server statically linked, like Go and [Graal](https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/) for example. I would like .NET have similar abilities, even with some harsh limitations (like now), mostly to be used in distroless containers for simple microservices. For accessing services over HTTPS in statically linked executables I need OpenSSL to be statically linked. That's trade-off from security perspective where old and potentially buggy OpenSSL would be in you executable, but for cloud native applications or just dockerized apps, deployment pipeline always can re-create said images, so that would risk can be mitigated by using proper dev practices. Based on experiments minimum baseline size for such images dropped to 23.5MB from 34MB if I use Chiselled Ubuntu. That does not solve other potential issues within this scenario, like DB access (probably ODBC would work), and other libraries with native dependencies, but I expect other work (like Woodwork) will help here and maybe community work too. Repo with experiment on Docker containers - https://github.com/kant2002/NativeAOTDocker
Author: kant2002
Assignees: -
Labels: `untriaged`, `area-NativeAOT-coreclr`
Milestone: -
MichalStrehovsky commented 1 year ago

Does bflat help at all? https://flattened.net/

Bflat doesn't offer static linking on Linux. Bflat is more targeted towards people writing small tools than people running web workloads in containers.

  1. Static linking requires one to target a specific distro and the binary is unlikely to work on a different distro (e.g. libssl typically has distro-specific tweaks to paths where certificates are stored, etc.)
  2. For whatever crazy reason static linking on Linux implies one cannot use dlopen/dlsym to dynamically load libraries, so p/invokes stop working unless one links everything statically.

Not a fundamental problem, but this makes static linking on Linux only feasible if one is in full control of the environment where the binary will run. It also requires a full copy of the target static libraries for all p/invokes to successfully build - this goes against bflat's "crosscompile from everywhere to everywhere without any extra SDKs/crossrootfs".

MichalStrehovsky commented 1 year ago

The PR mentioned in top post merged and we had a couple other PRs to enable static linking. I'm not aware of anything else left and I'm trying to keep the backlog manageable. Scream if I'm wrong.