Apparently a container does not even need an OS whereas VMs do.
Container != VM, but I never stopped to think about this before. Processes
within the container can directly talk to the kernel on which the container
is running. Most containers are built with a base OS image. Turns out you can
create an image without a base OS by pulling the scratch image, that contains
nothing.
Let’s create a small c program that is statically compiled.
$ cat small.c
#include <unistd.h>
int main()
{
write(1, "Hi!", 3);
}
$ gcc -o small small.c --static
Just 852kB!
$ ls -l small --block-size=k
-rwxrwxr-x 1 username username 852K Aug 5 15:34 small
This executable has everything it needs to run and does not need an OS. There is nothing specific to Ubuntu, for example. It just prints “Hi!”.
$ ./small
Hi!
Let’s build a Docker image with this executable inside it.
# Run this in the same directory where the executable 'small' is.
$ cat Dockerfile
FROM scratch
ADD small /small
CMD ["/small"]
$ docker build -t small-image -f Dockerfile .
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
small-image latest 46ad701a4cce About an hour ago 872kB
It’s about 872kB which is almost the same size as the executable small.
This should convince you that the scratch image has nothing in it
and we can verify this a functional image without a base OS, directly talking
to the kernel.
$ docker run small
Hi!
Hope you found this useful!