CORE STUDY: Docker – Containers vs Images

Reading Time: 4 minutes

In this segment we are going to dive into an important area for Docker. It should help provide some skills to get you on your feet.

The generic description might be that a “Container” is a standard unit of software that packages up code. Your container is a decedent of the host OS and and IMAGE (think of it as an overlay) that runs, A container image becomes a “Container” at runtime. Remember that Containers are isolated from each other. So running an image on a host produces a running container.

The first time you run the “ubuntu” image the system will have to go out and get it. That might look like this.

root@node:/# docker run -it ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
405f018f9d1d: Pull complete
Digest: sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
Status: Downloaded newer image for ubuntu:latest
root@76cdfe8e9f52:/#

If you “escape” ( Using ^p ^q – don’t worry you can get back to here) and do a “docker image ls” all you might see is something like the following. This just indicates that there is an Image (27941809078c) it has a tag and it has a repository.

root@node:/# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    27941809078c   5 weeks ago   77.8MB

The following information might be helpful to get a handle on what started

root@node:/# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
76cdfe8e9f52   ubuntu    "bash"    11 minutes ago   Up 10 minutes             adoring_goldwasser

So from these two we learn that the system we are on has an image named “ubuntu” with a given IMAGE ID and that the container is still running (Up 10 minutes) and is running in a container with a given CONTAINER ID. Please note in the following I used a few identifying characters for the container ID and the system found and attached me to that interactive session.

root@node:/# docker attach 76c
root@76cdfe8e9f52:/#

We have to remember that this particular IMAGE started out with no history. So it’s APT catalog is not up to date yet. If we wanted to run “ip a” that command hasn’t been installed yet. So we might.

root@76cdfe8e9f52:/# apt update
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]

So – for examples sake – we might want to install the “ip” command which is from the “iproute2” package.

root@76cdfe8e9f52:/# apt install iproute2
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libatm1 libbpf0 libbsd0 libcap2-bin libelf1 libmd0 libmnl0 libpam-cap
  libxtables12
Suggested packages:
  iproute2-doc
The following NEW packages will be installed:
  iproute2 libatm1 libbpf0 libbsd0 libcap2-bin libelf1 libmd0 libmnl0
  libpam-cap libxtables12
0 upgraded, 10 newly installed, 0 to remove and 9 not upgraded.
Need to get 1430 kB of archives.

We could then run.

root@76cdfe8e9f52:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

And for just for kicks we might add one more familiar package. This will (at least) present the “ping” command. Remember not even VI has been installed yet.

root@76cdfe8e9f52:/# apt install iputils-ping
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  iputils-ping
0 upgraded, 1 newly installed, 0 to remove and 9 not upgraded.

You will recount that we started and launched a container “ubuntu”. We updated that environment with the simple act of updating the APT catalog and then installing 2 modules (and resulting dependencies). The running container is obviously now different from what we started with. What if we wanted to save “this version” and build our own “image”? We can “commit” a container to an image.

root@node:/# docker commit 76c my-image
sha256:570b6d9400f57074e948e7acbdadbbe20cfcf2d866dd3488413b9ae5c5f8898a

This committed the “container” to form a new image.

root@node04:/# docker images
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
my-image     latest    570b6d9400f5   About a minute ago   118MB
ubuntu       latest    27941809078c   5 weeks ago          77.8MB

Please note that the “image” size of the image is now 118MB or larger than the initial 88.8MB. This makes sense as we should expect it to be larger as we changed the environment by updating the APT catalogs and installing two modules. You could then re-attach to the running container and then exit

root@node04:/home/ubuntu# docker attach 76c
root@76cdfe8e9f52:/# exit

You can make sure that all running containers are stopped.

root@node04:/home/ubuntu# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

We can then choose to “run” the image we created to test if it does indeed have the additions.

root@node:/home/ubuntu# docker run -it  my-image
root@672c87426161:/#

When we test using the “ip” command you confirm that this image did in fact retain what had happened. We can also test the ping command as well.

root@672c87426161:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

This is a start to to reviewing docker, containers, and images. To explore further you will want to know how to re-direct IP address, share disk space with the underlying host and other items.

end-of-article

References:
https://phoenixnap.com/kb/docker-image-vs-container
https://www.docker.com/resources/what-container/
https://docs.docker.com/engine/reference/commandline/ps/

This entry was posted in Docker. Bookmark the permalink.