How do they create so small OS images? - docker

Apparently OS distributions come in stripped down versions. E.g. ubuntu for docker is ~150MB which is quite small. But I don’t understand how can it be so small. Do they ship the most minimal functionality and expose fake APIs that delegate to the host kernel? How do they make it so small?

Related

Why use another person Docker Image?

I'm learning about Docker architecture.
I know that images are made to run applications in containers (virtualization). One thing that I stepped on was that there is an entire community hub for posting images. But what is actually the point of doing that?
Isn't the idea of images contain a very specific enviroment with very specific configurations that runs very specific applications?
The idea of images is to have a well-defined environment. The images by the community serve mostly as building blocks or base images for your own, more specific, images. For some applications, you can use an image as-is with maybe a little configuration parameters, but I would guess the more common use case is to start building your specific image based on an already existing, more general image.
Example:
You want to create an image with a certain Java application. So you look for an image that already has the Java version you want, and create an image based on that more general image.
You want to test your application on different OS versions (maybe different Linux versions). So you create a couple of images, each based on a different base image that already has the OS installed that you are interested in.

Do I need nvidia-container-runtime, and why? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I want to access my NVIDIA GPUs from inside containers. Can I do this without nvidia-container-runtime?
Requiring a custom Docker runtime just to talk to one device seems very strange. There is a whole universe of PCI devices out there. Why does this one need its own runtime? For example, suppose I had both NVIDIA and AMD GPUs. Would I be unable to access both from inside one container?
I understand that nvidia-container-runtime lets me control which GPUs are visible via NVIDIA_VISIBLE_DEVICES. But I do not care about this. I am not using containers to isolate devices; I am using containers to manage CUDA/CUDNN/TensorFlow version h*ll. And if I did want to isolate devices, I would use the same mechanism as forever: By controlling access to nodes in /dev.
In short, the whole "custom runtime" design looks flawed to me.
So, questions:
What am I missing?
Can I obtain access to my NVIDIA GPUs using the stock Docker (or podman) runtime?
If not, why not?
I certainly won't be able to answer every conceivable question related to this. I will try to give a summary. Some of what I write here is based on what's documented here and here. My discussion here will also be focused on linux, and docker (not windows, not singularity, not podman, etc.). I'm also not likely to be able to address in detail questions like "why don't other PCI devices have to do this?". I'm also not trying to make my descriptions of how docker works perfectly accurate to an expert in the field.
The NVIDIA GPU driver has components that run in user space and also other components that run in kernel space. These components work together and must be in harmony. This means the kernel mode component(s) for driver XYZ.AB must be used only with user-space components from driver XYZ.AB (not any other version), and vice-versa.
Roughly speaking, docker is a mechanism to provide an isolated user-space linux presence that runs on top of, and interfaces to, the linux kernel (where all the kernel space stuff lives). The linux kernel is in the base machine (outside the container) and much/most of linux user space code is inside the container. This is one of the architectural factors that allow you to do neato things like run an ubuntu container on a RHEL kernel.
From the NVIDIA driver perspective, some of its components need to be installed inside the container and some need to be installed outside the container.
Can I obtain access to my NVIDIA GPUs using the stock Docker (or podman) runtime?
Yes, you can, and this is what people did before nvidia-docker or the nvidia-container-toolkit existed. You need to install the exact same driver in the base machine as well as in the container. Last time I checked, this works (although I don't intend to provide instructions here.) If you do this, the driver components inside the container match those outside the container, and it works.
What am I missing?
NVIDIA (and presumably others) would like a more flexible scenario. The above description means that if a container was built with any other driver version (than the one installed on your base machine) it cannot work. This is inconvenient.
The original purpose of nvidia-docker was to do the following: At container load time, install the runtime components of the driver, which are present in the base machine, into the container. This harmonizes things, and although it does not resolve every compatibility scenario, it resolves a bunch of them. With a simple rule "keep your driver on the base machine updated to the latest" it effectively resolves every compatibility scenario that might arise from a mismatched driver/CUDA runtime. (The CUDA toolkit, and anything that depends on it, like CUDNN, need only be installed in the container.)
As you point out, the nvidia-container-toolkit has picked up a variety of other, presumably useful, functionality over time.
I'm not spending a lot of time here talking about the compatibility strategy ("forward") that exists for compiled CUDA code, and the compatibility strategy ("backward") that exists when talking about a specific driver and the CUDA versions supported by that driver. I'm also not intending to provide instructions for use of the nvidia-container-toolkit, that is already documented, and many questions/answers about it already exist also.
I won't be able to respond to follow up questions like "why was it architected that way?" or "that shouldn't be necessary, why don't you do this?"
To answer my own question: No, we do not need nvidia-container-runtime.
The NVIDIA shared libraries are tightly coupled to each point release of the driver. NVIDIA likes to say "the driver has components that run in user space", but of course that is a contradiction in terms. So for any version of the driver, you need to make the corresponding release of these shared libraries accessible inside the container.
A brief word on why this is a bad design: Apart from the extra complexity, the NVIDIA shared libraries have dependencies on other shared libraries in the system, in particular C and X11. If a newer release of the NVIDIA libraries ever required features from newer C or X11 libraries, a system running those newer libraries could never host an older container. (Because the container would not be able to run the newer injected libraries.) The ability to run old containers on new systems is one of the most important features of containers, at least in some applications. I guess we have to hope that never happens.
The HPC community figured this out and made it work some time ago. Here are some old instructions for creating a portable Singularity GPU container which injects the required NVIDIA shared libraries when the container runs. You could easily follow a similar procedure to create a portable OCI or Docker GPU container.
These days, Singularity supports a --nv flag to inject the necessary shared libraries automatically. It also supports a --rocm flag for AMD GPUs. (Yes, AMD chose the same bad design.) Presumably you could combine these flags if you needed both.
All of these details are pretty well-documented in the Singularity manual.
Bottom line: If you are asking the same question I was, try Singularity.

How should I pick the right Docker image? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 3 years ago.
Improve this question
Docker images are often available with different base OS images.
I am not going to install other applications in that container. I will have separate container for each application I need.
Does it matter which base image I choose? If not why would I choose a larger image instead of a smaller one? What would I be giving away?
For example, Kong image is available in two variants with very different sizes:
CentOS based - 143.23 MB
Alpine based - 42.71 MB
https://hub.docker.com/_/kong?tab=tags
BTW, I am going to run the docker on Ubuntu.
As mentioned in the comment it totally depends upon your need, but in the mentioned two images I will go for alpine.
Does it matter which base image I choose?
Yes its matter, there are a different reason to choose smaller one, some advantage may be
Smaller in size (build, pull, push is fast)
Take little space as the compared large image
Consume less MEMORY by the OS itself as compared to CentOS
Alpine is considered secure and fast
Alpine is an offical image for docker registry
You can read the experimental base article here.
SMALL
Alpine Linux is built around musl libc and busybox. This makes it
smaller and more resource efficient than traditional GNU/Linux
distributions. A container requires no more than 8 MB and a
minimal installation to disk requires around 130 MB of storage.
Not only do you get a fully-fledged Linux environment but a large
selection of packages from the repository.
Binary packages are thinned out and split, giving you even more
control over what you install, which in turn keeps your environment as
small and efficient as possible.
alpinelinux
If you're only going to run the image as-is, as I assume from
I am not going to install other applications in that container. I will have separate container for each application I need.
then it doesn't matter (unless the image's developer notes it does, of course!).
If you're going to use one of those images as a base image, then it does matter some – as noted here in comments and answers, the different distributions these images are based on have different tools and capabilities (Ubuntu/Debian has apt for a package manager, Alpine uses musl libc and has apk).
At that point, you'll want to choose a base image that has the tooling you're comfortable with and supports the changes you'll be enacting on top of the base image.

Docker Container compared with Unikernel

I recently deployed a tiny Haskell app with docker, using "scratch-haskell" as a base image.
Then I read about Unikernels and HALVM. And I got a little confused.
My docker container is about 6MB large. A Unikernel (with the same haskell app) would be roughly the same size I guess.
The Unikernel runs directly on the Xen hypervisor, whereas the docker Image (or general LXC) runs on a normal Linux distribution, which runs on bare metal.
Now I have the "choice" of running Linux with multiple minimal containers OR a Xen machine with multiple small Unikernels.
But what are the advantages and disadvantages of those two solutions? Is one more secure than the other? And are there any significant performance differences between them?
from http://wiki.xenproject.org/wiki/Unikernels
What do Unikernels Provide?
Unikernels normally generate a singular runtime environment meant to
enable single applications built solely with that environment.
Generally, this environment lacks the ability to spawn subprocesses,
execute shell commands, create multiple threads, or fork processes.
Instead, they provide a pure incarnation of the language runtime
targetted, be it OCaml, Haskell, Java, Erlang, or some other
environment.
Unikernels Versus Linux Containers
Much has been made recently of the advantages of Linux Container
solutions over traditional VMs. It is said by container advocates that
their lightweight memory footprint, quick boot time, and ease of
packaging makes containers the future of virtualization. While these
aspects of containers are certainly notable, they do not spell the end
of the world of the hypervisor. In fact, Unikernels may reduce the
long-term usefulness of containers.
Unikernels facilitate the very same desirable attributes described by
the container proponents, with the addition of an absolutely splendid
security story which few other solutions can match.
So if you want just run Haskell application Unikernels may work for you, and they should have even less overhead than docker (and docker overhead is very small anyway), but if your application will need some prepared environment, need to communicate with non Unikernels software docker is a better choice. I guess it is too early to say will Unikernels be useful or widespread or not, only time will tell.
Unikernals are great for things that are stateless. When you start needing disk access you are better off using Docker.
That's why all the "killer" apps for unikernals are statically configured kernels, like static web pages or software defined networking stacks.
There are many good explations heres a simple one :
Unikernel are VMs but specialized and optimized for the particular application.

Docker best practice on base images and host os

I have a questition about the best pratices on using docker in production.
In my company we use SLES12 as host os. Should we use SLES also as base for our docker containers?
In my opinion SLES image is too big to follow the ddocker recommendation for small base images.
My questition is: Has anyone experience in using docker in production with different host and container os? Are there any disadvantages if we use a small debian/ubuntu base image for our containers? (overhead, security, ...)
I agree with your assessment that for dockerized applications, smaller base images are preferred. This will save on disk space, reduce network transfer, offer a smaller software surface to worry about security vulnerabilities and general complexity. To my knowledge different host/container distributions is the norm and when they align it's more of a coincidence than an intentional design. Since the way you interact with the host OS and the container are so very different, even if they were identical, you procedures for keeping things patched would be different. That said, depending on your staff skill set, sticking to the same package manager ecosystem (rpm vs deb) may have some benefit in terms of familiarity of tooling, so finding a small base RPM distro might be a good choice.

Resources