Why are containers more portable?

21 Oct.,2024

 

Understanding the difference between portability ...

Portability alone does not offer the entire promise of Linux containers. You also need Compatibility and Supportability. Here&#;s why:

Hongyu Dinghao supply professional and honest service.

Portability

The standardized format of containers is what makes them portable between registry servers and container hosts. Since the recent wave of containers are governed by open standards, essentially any container host can push or pull images to and from any container registry. This is foundational to the vision of hybrid and multi cloud.

Red Hat named a Leader in the Gartner® Magic Quadrant&#; for second consecutive year

Red Hat was named a Leader in the Gartner Magic Quadrant for Container Management. This year, Red Hat was positioned furthest on the Completeness of Vision axis.

Since the Open Containers Initiative defines the image and distribution specifications, a Container Image can be created with Podman, pushed to any container registry with Skopeo, shared with the world, and consumed by any OCI compatible container engine including Docker, RKT, CRI-O, containerd and, of course Podman or Skopeo. Standardizing on image and distribution formats lets us build infrastructure like registry servers, which can be used to store container images that have many different types of binaries in them including:

  • Linux on x86

  • Linux on ARM

  • Linux on POWER

  • Linux on Z

  • WindowsMore

In fact, registry servers based on the OCI distribution specification are so popular that there&#;s a proposal to extend them to include almost any artifact: opencontainers/artifacts. If you wanted to, you could even mix binaries from multiple different hardware architectures or operating systems in the same container image.

Let&#;s demonstrate that the container image format is the same no matter which type of artifact we pull by pulling a Windows Nano image down on a RHEL 8 container host. Notice that Skopeo can pull the Windows Nano container image, uncompress it, and store it locally even though this is on a RHEL 8 container host:

skopeo --override-os windows copy \

docker://mcr.microsoft.com/windows/nanoserver: \

containers-storage:mcr.microsoft.com/windows/nanoserver:

The image is now stored in .local/share/containers/storage/ because it&#;s running rooteless in this case. You can inspect it with the following command:

skopeo inspect containers-storage:mcr.microsoft.com/windows/nanoserver:

Output:

{

"Name": "mcr.microsoft.com/windows/nanoserver",

"Digest": "sha256:65d0f8a710e5add87e539b6eb25c724d73fba7cff7c5aea5",

"RepoTags": [],

"Created": "-06-03T11:03:30.541Z",

"DockerVersion": "",

"Labels": null,

"Architecture": "amd64",

"Os": "windows",

"Layers": [

"sha256:c40da4de5e84fba9e2c0f302d2db4a2d4ae5ae2dfca2"

],

"Env": null

}

You can also see the image with podman by running the `podman images` command:

$ podman images | grep nano

Output:

mcr.microsoft.com/windows/nanoserver 8b8ec38e0f40 7 days ago 263 MB

Before we try and run this image, let&#;s discuss compatibility a bit...

Compatibility

This is what determines if the binaries in the container image can actually run on the container host. ARM binaries in a container image will not run on POWER container hosts - Windows Nano binaries in a container image will not run on a RHEL 8 container host. Containers don't offer the ability to run cross-platform binaries, you'd need to use virtualization or emulation for that (example: QEMU System Emulator Targets). This compatibility problem extends to processor architecture, and also versions of the operating system. 

Try running a RHEL 8 container image on a RHEL 4 container host -- that isn't going to work very well. However, as long as the operating systems are reasonably similar, the binaries in the container image will usually run. To demonstrate the limits, let's try and execute this Windows Nano container image on a RHEL 8 container host:

podman run -it --log-level=debug \

containers-storage:mcr.microsoft.com/windows/nanoserver:

The first thing you&#;ll notice is that the image fails to run. Let&#;s analyze a few key log messages to see why. First, notice that Podman is able to mount the container image. As mentioned before, this is to be expected because container images are platform neutral (they&#;re just tar files) and governed by open standards, so Linux can uncompress it and mount it: 

DEBU[] mounted container "8be871d404f1ac63bf7b39f13a87aff4d87fbaccc802c" at "/home/fatherlinux/.local/share/containers/storage/overlay/caaaf49dc11b113ba33eeaf/merged"

Now, notice the exit error:

DEBU[] ExitCode msg: "unable to find user containeruser: no matching entries in passwd file"

For more Foldable 20ft Containerinformation, please contact us. We will provide professional answers.

ERRO[] unable to find user ContainerUser: no matching entries in passwd file

The ContainerUser is a Windows user which Podman doesn't find in a passwd file in the image. Even if we added an /etc/passwd file, the binaries would fail to run because they are Windows binaries, not Linux ELF binaries. This is a compatibility problem, even though the image is portable and can be copied to a Linux container host.

If you would like to see another example of compatibility problems, even between very similar Linux distros, see The limits of compatibility and supportability with containers. Now, let's discuss how Red Hat manages support of container images...

Supportability

This is what vendors can support. This is about investing in testing, security, performance, architecture, a support team, testing that images and binaries are built in a way that they run correctly on a given set of container hosts  as well as updating the code should security, performance or bugs crop up. 

For example, Red Hat supports RHEL 6, UBI 7, and UBI 8 container images on both RHEL 7 and RHEL 8 container hosts (note that RHEL CoreOS in OpenShift is built from RHEL 8 bits). Red Hat cannot guarantee that every permutation of Linux container image and host combination on the planet will run on RHEL container hosts. Nor can Red Hat go patch and update every Linux container image that&#;s out there.  

Supportability is about putting a reasonable scope around what is and isn&#;t covered by a Red Hat subscription. Expanding the scope of container images which are supported, increases the testing, analysis, and repair matrix at a non-linear growth rate. Stated another way, scoping support for container images can be very expensive. 

To demonstrate supportability, let&#;s run some tests with a container image called Red Hat Universal Base Image 8 (UBI) and a container host based on RHEL 8 Server:

cat /etc/os-release | head -n 4

Output:

NAME="Red Hat Enterprise Linux"

VERSION="8.2 (Ootpa)"

ID="rhel"

ID_LIKE="fedora"

Now, run it in a container:

podman run -it --rm ubi8 cat /etc/os-release | head -n 4

Output:

NAME="Red Hat Enterprise Linux"
VERSION="8.2 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"

This demonstrates a completely supportable image and host combination, which is also compatible, and portable.

Conclusion

If you are running production grade workloads that need reliability over a long lifecycle, run RHEL container images on RHEL container hosts, as this is engineered for portability, compatibility, and scoped for support.

To summarize, with Podman on a RHEL 8 container host, running a UBI 8 container image, you get:

  1. Portability - you can move the image where you want. This means you can share infrastructure like registry servers between cloud providers or on premise.

  2. Compatibility - the container images and hosts are designed and engineered to work together (See: Engineering compatibility with the Red Hat Universal Base Image). Compatibility is based on hardware architecture (x86 versus ARM), operating system (Linux versus Windows), Linux distribution (RHEL versus other distro), and even age of the Linux distro in the container image - for example, very old images may not work on newer hosts, while very new images may not work on older hosts.

  3. Supportability - Red Hat can fix problems in the Container Image, Container Host, Container Engine, and the Linux kernel to make sure that these components work together over a defined life cycle. Supportability is based on a vendor's ability to release, patch, version, and test a set of components together. Also, high quality support is based on a well defined and scoped set of components that are designed and engineered to work together.

So, if you are using Red Hat Enterprise Linux today, and just getting started with containers, check out Red Hat Universal Base Image &#; it&#;s portable, compatible, and the most supportable base image available for RHEL and RHEL CoreOS. Learn how to get started with our official documentation.

The pros and cons of container platforms for portability

In today's software world, portability is king. Applications that are only able to run on one type of host server, OS or software environment no longer meet business needs. They lack agility, constrict your ability to upgrade software and hardware and are more difficult to maintain.

Container platforms provide a solution to this portability challenge. Containers help you take an application that is not portable and turn it into one that can be deployed almost anywhere with ease -- albeit with a few particular caveats.

Defining portability

In the software world, portability means the ability of an application to run in different types of host environments. There are different degrees of portability. An application that can run on any type of Linux distribution, but not on Windows, would be considered somewhat portable. But it is not as portable as an application that supports Linux as well as Windows.

Portability is also measured in terms of the amount of tweaking required to move an application from one environment to another. A highly portable application is able to be deployed on any platform without the need to make significant modifications to configuration files.

Other, less portable applications are able to run on different systems but require extensive configuration tweaks within the different environments.

Conventional approaches to portability

Traditionally, portability has been achieved at the application level. Applications that were portable were designed by their developers in ways that allowed them to run in any type of environment and with configurations that were more or less universal across all types of host environments.

In this context, choosing the right programming language was an important factor. Some languages, such as Java, are easy to support in any type of environment without many changes to the code. Others, like .NET, are more difficult to support on multiple types of OSes.

In addition, designing configuration systems that do not depend on special OS features or tools was traditionally an important factor in making applications portable. For example, if your application stored its configuration in the Windows registry, it would be difficult to port to Linux. It would be more portable if it stored its configuration in plain text files.

Virtual machines (VMs) are another way to achieve a level of portability. For instance, an application that runs only on Linux could be hosted on a Windows server using a VM. While this type of solution gives you enough portability to make your host environment cross-platform, the portability is still relatively limited. It gives you flexibility at the level of your hosting infrastructure, since you could use either Windows- or Linux-based physical servers. But, at the same time, it requires you to use a specific type of guest OS in order to deploy your application.

Using containers to achieve portability

Thanks to the advent of container platforms like Docker, it's now possible to make applications highly portable without having to modify the application itself or rely on VMs. With containers, you can take an application written for one type of host environment and deploy it almost anywhere. In most cases, you don't have to make any changes to the application's configuration.

This is because containers allow you to "build once and run anywhere." In other words, with containers, you compile your code and place it into a container image. You can then deploy that image on any type of host environment that has a daemon installed to support your container. This works because all of your application's binaries and configuration files are stored inside the container. As a result, environment variables outside the container shouldn't impact the application.

Container portability limitations

It's important to note, however, that container platforms are not a panacea for application portability. They are still subject to certain limitations, including limitations around persistent storage and the portability of the containers themselves.

Container platforms -- especially Docker -- make applications much easier to move from one host platform to another.

Persistent storage configurations for containerized applications may need to be changed when you move containers from one environment to a different one. This is because there are different ways to implement persistent storage for containers, and the storage setup in one environment may not work for containers that were designed with a different environment in mind. Of course, this consideration doesn't apply if your containerized applications are stateless and don't require storage.

While containers are highly portable on the same type of container platform, you generally can't take a container built for one type of platform, like Docker, and run it on a different one, like Linux Containers (LXC). Also, containers designed for modern versions of Docker may not work on older versions. Like other technologies, Docker is not immune to backwards compatibility issues.

Crossing the Linux-Windows divide

Porting containers from one family of OS (e.g., Windows) to another (e.g., Linux) is also complicated. One big portability drawback of containers compared to VMs is that, traditionally, a containerized Linux application required a Linux host, and vice versa for Windows.

In this respect, containers are less portable than VMs. A Linux-based VM can typically run on a Windows host, and vice versa. In addition, containers have never supported platforms other than Linux and Windows. As a result, there was no native way to deploy a Dockerized application on macOS, for example. You could solve this problem by using a Linux-based VM to serve as the middleman between your macOS host system and your Docker containers, but that comes at the cost of higher resource utilization and management burden.

Recently, however, this has changed in the case of Docker. In spring , Docker announced LinuxKit, a set of tools that allow developers to create what Docker calls a "Linux subsystem" within their containers. The Linux subsystem provides a tiny Linux-based OS that runs inside a container and makes it possible to run Docker applications, even if the containers are running on a different type of OS. This approach doesn't require VMs.

With LinuxKit, Docker has now achieved maximum portability -- at least for Linux applications. Containerized Linux applications can be packaged with LinuxKit and run on any type of host OS, without requiring any special configuration changes when they move from one environment to another.

There are just two caveats. First, LinuxKit only works with the Docker framework. Other types of container platforms, like LXC, remain Linux-only. Second, LinuxKit only applies to Linux applications. There is still no way to take a containerized Windows application and run it on a Linux host.

Conclusion

Although containers are subject to certain portability limitations, container platforms -- especially Docker -- make applications much easier to move from one host platform to another. This has become even more true since the release of LinuxKit, which brings complete portability to containerized Linux applications.

If you want to learn more, please visit our website Container Home Supplier.