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!