Announcing the General Availability of .NET Chiseled Containers

In a groundbreaking collaboration, Canonical and Microsoft proudly present the General Availability (GA) of .NET chiseled Ubuntu container images, now ready for production use with .NET 6, 7, and 8. The culmination of a long-term partnership and design collaboration, these chiseled images signify a new direction in containerization. This article provides a comprehensive overview of .NET chiseled containers, their benefits, and how to integrate them into your production environment.

The Evolution of Chiseled Containers

Chiseled Images Tag and Availability

The chiseled Ubuntu container images can be accessed from our container repositories using the tag `8.0-jammy-chiseled`. For .NET 6 and 7 variants, the only difference lies in the version number. These images leverage Ubuntu 22.04 (Jammy Jellyfish), as indicated by "jammy" in the tag name.

To gain insights into the journey of chiseled containers, check out the following informative videos:

  1. Chiseled Ubuntu Containers
  2. .NET Containers Advancements in .NET 8 | .NET Conf 2023
  3. .NET in Ubuntu and Chiseled Containers

Additionally, we have crafted a container workshop for .NET Conf, incorporating chiseled containers in various examples. The workshop demonstrates the synergy between chiseled containers and OCI publish, enhancing your containerized application workflows.

The Promise of Chiseled Containers

The core concept behind chiseled containers challenges the notion that general-purpose container images are the future of cloud applications. While container images are the ideal deployment vehicle for cloud apps, conventional images include excess components. Chiseled container images address this by stripping away non-essential components, significantly improving size and security.

A prevalent challenge with container images is managing Common Vulnerabilities and Exposures (CVEs). To mitigate this, we have implemented automation that rebuilds .NET images promptly after updates to base images like Alpine, Debian, and Ubuntu on Docker Hub. This ensures that the images we deliver are always up-to-date. Unfortunately, many users lack such automation, leading to outdated images in their registries that fail CVE scans. Chiseled containers provide a more efficient solution to this problem.

Demonstrating the disparity, using anchore/syft with Docker, reveals the number of "Linux components" in different images:

$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/runtime:8.0 | grep deb | wc -l
92
$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/runtime:8.0-jammy | grep deb | wc -l
105
$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/runtime:8.0-alpine | grep apk | wc -l
17

Chiseled containers significantly reduce the component count:

$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled | grep deb | wc -l
7

That gets us down to 7 components. In fact, the list is so short, we can just look at all of them.

$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled | grep deb
base-files                                         12ubuntu4.4               deb     
ca-certificates                                    20230311ubuntu0.22.04.1   deb     
libc6                                              2.35-0ubuntu3.4           deb     
libgcc-s1                                          12.3.0-1ubuntu1~22.04     deb     
libssl3                                            3.0.2-0ubuntu1.12         deb     
libstdc++6                                         12.3.0-1ubuntu1~22.04     deb     
zlib1g                                             1:1.2.11.dfsg-2ubuntu9.2  deb

That’s a very limited set of quite common dependencies. For example, .NET uses OpenSSL, for everything crypto, including TLS connections. Some customers need FIPS compliance and are able to enable that since .NET relies on OpenSSL.

Native AOT apps are similar but need one less component. We care so much about limiting the size and component count that we created an image just for it, removing libstdc++6. This image is new and still in preview.

$ docker run --rm anchore/syft mcr.microsoft.com/dotnet/nightly/runtime-deps:8.0-jammy-chiseled-aot | grep deb | wc -l
6

As expected, that image only contains 6 components.

Chiseled images are also much smaller. We can see that, this time with (uncompressed) aspnet images.

$ docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | grep mcr.microsoft.com/dotnet/aspnet
mcr.microsoft.com/dotnet/aspnet               8.0-jammy-chiseled                      110MB
mcr.microsoft.com/dotnet/aspnet               8.0-alpine                              112MB
mcr.microsoft.com/dotnet/aspnet               8.0-jammy                               216MB
mcr.microsoft.com/dotnet/aspnet               8.0                                     217MB

In summary, Chiseled images:

  • Slice over 100MB (uncompressed) relative to existing Ubuntu images.
  • Match the size of Alpine, the existing fan favorite for size.
  • Are the smallest images we publish with glibc compatibility
  • Contain the fewest components, reducing CVE exposure.
  • Are a great choice for matching dev and prod, given the popularity of Ubuntu for dev machines.
  • Have the strongest support offering of any image variant we publish.

These chiseled images drastically cut down the number of components, enhancing security and reducing CVE exposure.

Size and Security Advantages

Chiseled images stand out in size, with a size reduction of over 100MB (uncompressed) compared to existing Ubuntu images. They align in size with Alpine, a popular choice for size optimization, and remain the smallest images we publish with glibc compatibility. Notably, they contain the fewest components, further minimizing CVE exposure.

These chiseled images are particularly advantageous for aligning development and production environments, considering the widespread use of Ubuntu for development machines. Moreover, they boast the strongest support offering among all image variants we publish.

Distroless Form Factor

The Quest for Smaller, More Secure Images

Over nearly a decade of publishing container images, the consistent demand for smaller images, reduced components, and enhanced security prompted a revolutionary approach. While many users advocated for Google Distroless, the .NET team adheres to a philosophy of aligning with upstream distros, such as Alpine, Debian, and Ubuntu.

"Distroless" images, as defined by the distroless repository, exclusively contain the application and its runtime dependencies, omitting package managers, shells, or other unnecessary programs found in standard Linux distributions. Google deconstructs various Linux distros, reconstructing them with only the essential atoms required to run applications.

The .NET team waited for a solution from the upstream provider and found it in Ubuntu chiseled, which embodies the distroless form factor. This approach shares the goals of the original Google Distroless project but originates directly from the distro itself.

Proven Track Record with Mariner Linux

Addressing concerns about the reliability of this new approach, the .NET team has been delivering distroless images within Microsoft for several years. Leveraging Mariner Linux, the .NET team requested the creation of a distroless solution for shared users. Microsoft teams have successfully hosted applications in production using .NET + Mariner distroless images, validating the effectiveness of this approach.

Security Posture of Chiseled Images

Mitigating Attack Vectors

The key strength of chiseled images lies in the deliberate omission of a shell and a package manager, limiting the potential actions of attackers. Additionally, the absence of curl and wget in these images prevents attackers from downloading and executing shell scripts from a controlled server.

$ docker inspect mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled | grep User
            "User": "",
            "User": "1654",

These images are shipped as non-root, further restricting the range of operations permitted within them. New files and directories are created with a User ID (UID) and Group ID (GID) of 0, reinforcing security measures.

Overcoming Operational Challenges

The absence of a package manager database in chiseled images presented an operational challenge for image scanners relying on scanning the package manager database. To overcome this hurdle, Canonical synthesized a package manager database file through alternative means, ensuring effective scanning without compromising security.

The anchore/syft commands demonstrated earlier in this post serve as evidence of the successful scanning solution implemented in chiseled images.

Controlling App Size with Chiseled Containers

Size Optimization Strategies

Controlling the size of container images is crucial, and the .NET team provides multiple strategies to achieve this. The presented slide from our .NET Conf presentation illustrates image sizes with various options for a sample app:

Container Size Improvements

[Img © devblogs.microsoft.com]

Two primary axes influence image size:

  1. Base image for framework-dependent apps: Chiseled variants of aspnet on the left side of the slide result in significant size reductions. The smaller chiseled image, labeled "composite," achieves additional reductions by optimizing parts of the .NET runtime libraries.
  2. Publish option for self-contained apps: On the right side of the slide, self-contained apps with trimming drastically reduce image size by removing unused .NET libraries.

Additionally, Native Ahead-of-Time (AOT) compilation reduces the image size to below 10MB, albeit limited to console apps and services.

Choosing the Right Deployment Option

The choice between framework-dependent deployment and self-contained apps depends on specific requirements:

  • Framework-dependent deployment: Maximizes layer sharing, allowing copies of .NET to be shared within a registry and on a single machine hosting multiple .NET apps. This option also results in shorter build times.
  • Self-contained apps: Excel in size and registry pull efficiency but have more limited sharing capabilities, sharing only the runtime-deps.
  • Native AOT Drastically reduces image size but only applies to console apps and services, not web applications.

Adoption and Recommendations

Embracing the Chiseled Image Revolution

Chiseled images represent a paradigm shift in our container image portfolio, comparable to the introduction of support for Alpine several years ago. Users transitioning to .NET 8 are particularly well-suited for adopting chiseled containers, providing an opportunity for a seamless change with substantial benefits.

For Ubuntu and Debian users, chiseled images offer significant size savings compared to general-purpose images. It is highly recommended to evaluate and consider integrating chiseled images into your containerized workflows.

While Alpine users continue to benefit from their well-established support, the addition of a non-root user in .NET 8 Alpine images provides an extra layer of security. We encourage Alpine users to transition to non-root hosting and explore the additional advantages offered by chiseled images.

Addressing concerns about potential disruptions caused by a shift to chiseled images, we assure users that our commitment to publishing Debian images for existing version tags, such as "8.0," remains unchanged. Users can easily opt for other image types, emphasizing our dedication to compatibility and choice.

Collaborative Future with Chiseled Containers

The journey from the initial demo of Ubuntu chiseled containers to their GA release has been a testament to the collaboration between Canonical and Microsoft. This level of cooperation will persist as we continue to support and enhance these new images. We eagerly await feedback from users, anticipating novel use cases and scenarios we may not have yet considered.

Our positive experience working closely with Canonical on this project has fueled our enthusiasm to extend the benefits of chiseled images to all developers. We encourage other developer ecosystems, including Java, Python, and Node.js, to explore the adoption of chiseled images.

In the aftermath of .NET Conf presentations, inquiries about chiseled images have surged. Looking forward, we anticipate chiseled images becoming a prevalent choice for developers, addressing the growing challenge of operationally managing containers and minimizing the impact of CVE burdens. Chiseled images emerge as a powerful solution, empowering teams to reduce costs and deploy applications with heightened confidence.

Join us in embracing the future of containerization with .NET chiseled containers, where size, security, and operational efficiency converge to redefine the landscape of cloud app deployment.

Reference

Dev Blogs Microsoft.


Ezmata Technologies Pvt Ltd
You manage your core business, while we manage your Infrastructure through ITaaS.