dotnet / tye

Tye is a tool that makes developing, testing, and deploying microservices and distributed applications easier. Project Tye includes a local orchestrator to make developing microservices easier and the ability to deploy microservices to Kubernetes with minimal configuration.
MIT License
5.29k stars 520 forks source link

Lighter and faster process for .NET containerization without a container runtime #1433

Open lippertmarkus opened 2 years ago

lippertmarkus commented 2 years ago

What should we add or change to make your life better?

We should include konet's ideas into Tye to make containerization of .NET apps more easy, lightweight and faster without requiring a container runtime, Dockerfiles or downloading base images.

Why is this important to you?

Tye is already able to automatically generate Dockerfiles, what helps with quicker deployments and removes the need to manually maintain a Dockerfile. Having a dependency on Docker as a container runtime however slows down the containerization process and makes it more heavyweight. This slows down development cycles and CI/CD automation.

These problems have been addressed by popular tools like Jib for Java and ko for Go. Recently, I created konet to bring these benefits to the .NET ecosystem.

Including konet's ideas into Tye would make containerization of .NET apps more easy, lightweight and a faster without requiring a container runtime. Creating multi-arch and multi-OS container images for .NET apps would be a breeze.

konet works by creating binaries for different platforms and architectures by running dotnet build and pushes only those binaries as new tarball layers to a container image registry with a reference to a .NET base image - all without pulling base images, creating Dockerfiles or installing container runtimes.

Performance comparison

Below is a performance comparison for building and pushing a .NET Hello World console application on Linux and on Windows:

image image

In these diagrams, “Cold” means that there was nothing cached, i.e. no base images, no build cache, no .NET build objects and no images in the container registry. “Warm” represents a scenario where the image has already been build and pushed before, so re-building after a change in the source code can use existing base images, build cache, .NET build objects and layer blobs in the container registry.

Both on Linux and Windows konet is faster compared to a traditional process with Docker. The reasons for that are as follows:

konet doesn't have these shortcomings. It builds the image using the local .NET SDK, without the need of pulling a .NET SDK image. When pushing the image, it only references the .NET runtime image as the base image without pulling it before. Only a tarball containing the binaries is uploaded to the container registry.

More information GitHub repo: https://github.com/lippertmarkus/konet More details on how it works (where I reused some content from for this issue): https://lippertmarkus.com/2022/05/21/dotnet-konet/

davidfowl commented 2 years ago

These are for pushing only? How do you run and test the container that was built? (BTW this is a good idea).

lippertmarkus commented 2 years ago

For running and testing locally (e.g. tye run with --docker param or when config contains other docker services), you would still need a container runtime and the base images to run the created image. So in this scenario, you would "only" benefit from the shorter build times.

I think there are also a lot of users who develop and debug locally without containers and afterwards just want to run tye publish or even tye deploy to quickly test within a real cluster. Those would get the additional benefits of not needing to pull base images and having a container runtime.

So in both scenarios there would be advantages, and it's also great to say "you only need docker (or another container runtime) if you want to test your container images locally or if you run other services as containers" instead of "docker is a hard requirement if you want to use tye".

phillipsj commented 2 years ago

There are lots of advantages here with little downsides IMO. Not everyone is going to have Docker available, unless they are paying for Desktop or using the CLI. Decoupling and not requiring it seems like a great move.

schmitch commented 2 years ago

well there are downsides. first of the image for linux uses musl, which might not be the best case, when it comes to performance. sometimes it's also good to actually have a "base image" to include native dependencies. often people want to include more languages in their containers and since these "small" images do not contain a tz db it's sometimes troublesome and not really simple to use.

imjasonh commented 2 years ago

@schmitch both ko and Jib allow the user to configure the base image, with the minimal base image only as a default. Konet and tye should easily be able to do the same.

lippertmarkus commented 2 years ago

With .NET 7 this may isn't needed anymore: https://devblogs.microsoft.com/dotnet/announcing-builtin-container-support-for-the-dotnet-sdk/

Phiph commented 1 year ago

if you have time @lippertmarkus it'd be great to see how .net 7 container support compares in your benchmark.