Podman. A brief introduction

Robert Górczyński
Calendar icon
30 stycznia 2023

There is no doubt that Docker is the most popular tool for working with containers. In fact, it has become a standard and almost synonymous with containers. Nevertheless, it is not the only solution designed to manage containers, and certainly not the most secure.

Docker

Many container engines are based on a client-server model, in which the system includes a so-called daemon running in the background, acting as an intermediary between the user and the containers. Unfortunately, in order to function properly, many such daemons - one of which is Docker's daemon, dockerd - require root user privileges, and this can be considered the biggest problem regarding Docker. (It should be added at this point that quite recently an option appeared in Docker that allows the dockerd daemon to run without root privileges.)

The root user has access to the entire system, is given full privileges on the system and can do literally anything on the system, e.g. create and delete system files, install software, run services and so on. As a result, a potential vulnerability in Docker's security can open an attacker's way into the entire system, since the root user owns the dockerd process. A similar danger is associated with a vulnerability-containing container image - since it is run by a process running with root privileges, an attacker can gain access to any component of the system through such an image. Admittedly, it is recommended to change the container user, but this is often forgotten and the user remains root.

Podman

Meet podman, which is an open source tool developed by Red Hat engineers for managing OCI ( open container initiative) compliant containers. With podman, you can easily find, create, run, share and deploy applications based on containers or OCI container images.

Podman does not require a daemon for proper operation, and all operations are done via the shell command, podman, which uses the libpod library to manage the entire container ecosystem. It is worth mentioning that podman interacts with Buildah and Skopeo tools, allowing you to customize your container environment.

Subman architecture

The biggest advantage of podman is the ability to run without root user privileges. As a result, the container will not receive any additional privileges, and you don't need to use the sudo mechanism and enter a password when running it. Of course, it is possible to run containers from the root user or another privileged system user.

Another advantage of the sub-mana approach is that containers can be run by unprivileged users, which is important in multi-user environments and HPC environments, i.e. high-performance computing systems. This has made the creation, use and management of containers accessible to ordinary users, which in turn means more convenience for them and less danger for the system.

The daemon-less architecture is one of the biggest advantages of subman. If the container is "cracked," the attacker will not have full control over the system anyway, because an account with root user privileges was not used to run the container. This is important from the perspective of ensuring system security. Another strong point of the podman is that it works with the SELinux architecture, which provides greater control over the resources that containers access.

Despite its undoubted advantages, the subman architecture also has some disadvantages. First of all, it means the inability to share container images between users. In addition, attaching ports with numbers up to and including 1024 requires root privileges, so running podman without using the sudo command eliminates the possibility of using said ports. In this article you will learn the basics of podman. If you have experience with Docker, you will have no problem using the podman tool, which can be considered a direct replacement for Docker. The two container management systems are so compatible with each other that you can easily define a podman as an alias for Docker. In the Bash shell, the following command is used for this:

1$ alias docker=podman

If you create this alias, then you can use Docker commands when working with podman - they are identical.

Installing podman

The podman tool is available for various Linux distributions and on Mac and Windows platforms. Although the podman service works only on Linux, but thanks to virtual machine-based solutions it is also available for Mac and Windows - in the latter it is based on the windows system for linux(WSL) functionality. If you are using macOS and the Homebrew package manager, in order to install podman, just issue the following command:

1$ brew install podman

On systems like Fedora, CentOS and RHEL, installing podman is done with the command:

1$ dnf install podman

On the other hand, in distributions based on Debian, such as Ubuntu, to install podman, you need to issue the command:

1$ apt install podman

Installing podman on Windows is definitely more difficult and is explained on the link page. The exact installation procedure on different operating systems is explained on the link page.

Working with the podman tool

Although in the examples presented here I will only use the podman command issued in the shell, but it is worth knowing that for container management the podman tool also offers a RESTful API, which provides access to podman's advanced features, such as those designed to handle pods. (A pod is simply a group of containers using the same resources, similar to Kubernetes).

Searching and retrieving containers

To search for containers, use the podman search command with an argument in the form of a search term, such as:

1$ podman search python
2NAME                                                                DESCRIPTION
3registry.fedoraproject.org/f31/python-classroom                     
4registry.fedoraproject.org/f31/python3                              
5...                              
6registry.access.redhat.com/ubi9/s2i-base                            rhcc_registry.access.redhat.com_ubi9/s2i-bas...
7docker.io/library/python                                            Python is an interpreted, interactive, objec...
8...
9docker.io/fnndsc/python-poetry                                      Python Poetry
10docker.io/ibmcom/python-ceilometerclient-ppc64le                    Docker image for python-ceilometerclient-ppc...
11quay.io/centos7/python-27-centos7                                   Python 2.7 available as container is a base...
12...
13quay.io/cloudfirst/python-rating-service                            
14quay.io/fedora/python-311

Since podman is a replacement for Docker, so it should come as no surprise that podman can use containers found in the Docker repository at docker.io. The pull command is used to download a container, and its syntax is as follows:

1$ podman pull [opcje] nazwa-obrazu[:tag]

Here the image name can be fully qualified, such as docker.io/library/python, or abbreviated, in which case in the example at hand it boils down to the word python. If you use a fully qualified name, it is written in the form shown here:

1nazwa-rejestru/nazwa-użytkownika/nazwa-obrazu

It is possible to download an image tagged with a specific tag. In this case, the image name should be followed by a colon (without any spaces) and the tag name after it. Suppose you want to download a tagged 3-slim smaller version of a container containing Python version 3.x. Then the command is of the form:

1_(nazwa skrócona)_
2$ podman pull python:3-slim
3_(użyta w pełni kwalifikowana nazwa obrazu)_
4$ podman pull docker.io/library/python:3-slim

The effect of executing any of these commands is to download the desired image from the official Docker container repository. By default, the podman tool checks not only the listed repository, but also others, such as Quay.io. Therefore, it is recommended to specify the full name of the image to be downloaded. If you want to download Python from the Quay.io repository, the syntax of the pull command does not change:

1$ podman pull quay.io/fedora/python-311

Some images have been downloaded this way. To see which ones are available locally, use the podman images command:

1$ podman images
2REPOSITORY                 TAG         IMAGE ID      CREATED     SIZE
3quay.io/fedora/python-311  latest      13fa6ebca8f7  4 days ago  974 MB
4docker.io/library/python   3-slim      9012e93183ab  4 days ago  134 MB

Running a container

Now that we have the images, you can prepare the container and launch it. Similar to Docker, podman also uses the run command to start the container.

1$ podman run --rm -it python:slim
2Resolved "python" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
3Trying to pull docker.io/library/python:slim...
4Getting image source signatures
5Copying blob 69038a8b17e6 skipped: already exists
6Copying blob 5fa7ca705967 skipped: already exists
7Copying blob be80bd1fa6e1 skipped: already exists
8Copying blob a82a83a9446e skipped: already exists
9Copying blob 8740c948ffd4 skipped: already exists
10Copying config 9012e93183 done
11Writing manifest to image destination
12Storing signatures
13Python 3.11.1 (main, Jan 17 2023, 23:45:25) [GCC 10.2.1 20210110] on linux
14Type "help", "copyright", "credits" or "license" for more information.
15>>> credits
16    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
17    for supporting Python development.  See www.python.org for more information.
18>>> exit()
19$

This way, using the podman tool, we have a working Docker container with a Python interpreter running, in which Python commands can be issued. The --rm option automatically removes the container when you're done with it, while the -it option means working with the container in interactive mode. Exactly the same options are used in Docker (remember that podman is a direct replacement for Docker?) In a nutshell, the container's interactive mode means that data entered in the shell used to work with podman is passed to the container's standard input. In turn, the output generated by the container is displayed in the shell in which the podman command was issued. We do not always want to work directly in the container, but use it, for example, to run a service such as a web server. In such a situation, the container should run in the background. Running a container running in the background is possible with the -d option. In the following example, a web server container will be downloaded from the Docker repository, which will then run in the background.

1$ podman pull docker.io/library/httpd
2Trying to pull docker.io/library/httpd:latest...
3Getting image source signatures
4Copying blob 70698c657149 done  
5Copying blob ec2ee6bdcb58 done  
6Copying blob 00df85967755 done  
7Copying blob 8740c948ffd4 skipped: already exists  
8Copying blob 8b4456c99d44 done  
9Copying config 6e794a4832 done  
10Writing manifest to image destination
11Storing signatures
126e794a4832588ca05865700da59a3d333e7daaaf0544619e7f326eed7e72c903
13$ podman images
14REPOSITORY                 TAG         IMAGE ID      CREATED     SIZE
15docker.io/library/httpd    latest      6e794a483258  4 days ago  149 MB
16quay.io/fedora/python-311  latest      13fa6ebca8f7  4 days ago  974 MB
17docker.io/library/python   slim        9012e93183ab  4 days ago  134 MB
18docker.io/library/python   3-slim      9012e93183ab  4 days ago  134 MB
19$ podman run -d httpd
204a2a2fc312f54ad302366976836f4bb9e7848f6a3e1bf8fcd6d1803d1cbf4ff6

The container was run in the background, so the only visible result on the screen of executing the podman run command is the displayed container ID. You can confirm that the container is running in the background using the podman ps command.

1$ podman ps
2CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS       NAMES
34a2a2fc312f5  docker.io/library/httpd:latest  httpd-foreground  6 seconds ago  Up 6 seconds ago              elated_fermat
4$

Although the container is running, but no IP address has been assigned to it, so it is difficult to access the functionality offered by the web server. As you can see in the example in question, the podman command was issued without using the sudo mechanism, and thus the container's permissions are not raised. Earlier I mentioned that the use of ports with numbers up to and including 1024 requires root privileges, and the web server listens to requests on port 80. In view of this, will our server not perform its role? No worries, just map the container's ports and the web server will work as expected. Port mapping is configured using the -p option, a modified version of the podman run command is as follows:

1$ podman run -dt -p 8080:80/tcp docker.io/library/httpd
2d90b6bfad6d9b18cd9830761cca0b3fe6923ed84109383aee86a3089e50ea0a4

The operation of the -p option is to connect the external port - that is, the port on the host where the container is running - to the container's internal port. In this case, using port 8080 on the local computer, we access port 80 on the running container. Thus, the mapping avoided the need to elevate the container's permissions, while still allowing the web server in the container to listen for requests on port 80. To find out, for example, just launch a web browser and go to http://localhost:8080. When you type in the address, a message appears: IT WORKS!

Alternatively, you can use the curl command:

1$ curl http://localhost:8080
2<html><body><h1>It works!</h1></body></html>

The content shown earlier in the Web browser window was displayed in the shell by the curl command. Our web server in the subman container is working! A list of all running containers can be displayed using the podman ps command mentioned earlier.

1$ podman ps
2CONTAINER ID  IMAGE                           COMMAND           CREATED             STATUS                 PORTS                 NAMES
3d90b6bfad6d9  docker.io/library/httpd:latest  httpd-foreground  About a minute ago  Up About a minute ago  0.0.0.0:8080->80/tcp  unruffled_napier

The output of this command contains various details about the running containers, such as the container's shortened ID, the image used to open it, the mapped ports, etc.

Stopping and deleting a container

When you have finished working with a container, you need to stop it. The following command is used for this purpose:

1podman stop [nazwa-kontenera] lub [identyfikator-kontenera]

Since no name has been given to the container in this example, use identifier. There is also a convenient -l option to mark the last container used. Therefore, the two commands presented here will stop our container with the web server running:

1$ podman stop d90b6bfad6d9

or

1$ podman stop -l

With the podman ps command, we confirm that the container is stopped:

1$ podman ps
2CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES
3$ 

If you didn't use the --rm option during container startup that causes the container to be automatically deleted when you finish working with it, you can delete the recently stopped container by issuing the podman rm -l command.

Summary

Podman is a daemon-less container engine with capabilities not inferior to those offered by Docker. Its biggest advantage is the ability to run containers with standard permissions, which provides more security to the host system. Of course, if necessary, a container can be run with root privileges. Thanks to its full compatibility with Docker, the podman can be used to work with Testcontainers. In most cases, this will not require any special configuration.

Read also

Calendar icon

28 marzec

RABATKA Action - Discover the spring promotion!

The annual spring promotion is underway: RABATKA Action, thanks to which you can save on open training from our proprietary offer.

Calendar icon

8 marzec

Don’t miss the opportunity - register for the IREB exploRE 2024 conference and meet the best experts in the field of requirements

We invite you to the IREB exploRE 2024 conference dedicated to requirements engineering and business analysis. The conference will ta...

Calendar icon

18 styczeń

How to prepare for the ISTQB® Foundation Level exam?

How toprepare for the ISTQB® Foundation Level exam? Check valuable tips before taking the test.