Intro to Podman (Red Hat Enterprise Linux 7.6 Beta)

Red Hat Enterprise Linux (RHEL) 7.6 Beta was released a few days ago and one of the first new features I noticed is Podman. Podman complements Buildah and Skopeo by offering an experience similar to the Docker command line: allowing users to run standalone (non-orchestrated) containers. And Podman doesn’t require a daemon to run containers and pods, so we can easily say goodbye to big fat daemons.

Podman implements almost all the Docker CLI commands (apart from the ones related to Docker Swarm, of course). For container orchestration, I suggest you take a look at Kubernetes and Red Hat OpenShift.

Podman consists of just a single command to run on the command line. There are no daemons in the background doing stuff, and this means that Podman can be integrated into system services through systemd .

We’ll cover some real examples that show how easy it can be to transition from the Docker CLI to Podman.

Podman installation

If you are running Red Hat Enterprise Linux 7.6 Beta, follow the steps below. If not, you can try Podman online with Katacoda.

You need to enable the extras repo:

$ su - # subscription-manager repos --enable rhel-7-server-extras-beta-rpms

Please note: at the time this was written RHEL 7.6 is still in beta. Once GA occurs, please change the repository name by removing the -beta- .

Then, launch the proper installation command:

# yum -y install podman

This command will install Podman and also its dependencies: atomic-registries , runC , skopeo-containers , and SELinux policies.

That’s all. Now you can now play with Podman.

Develop using Red Hat's most valuable products Your membership unlocks Red Hat products and technical training on enterprise cloud application development. JOIN RED HAT DEVELOPER

Command-line examples

Run a RHEL container

For the first example, suppose we want to just run a RHEL container. We are on a RHEL system and we want to run a RHEL container, so it should work:

[root@localhost ~]# docker run -it rhel sh -bash: docker: command not found

As you can see, there is no docker command on my RHEL 7.6 host. Just replace the docker command with podman :

[root@localhost ~]# podman run -it rhel sh Trying to pull registry.access.redhat.com/rhel:latest...Getting image source signatures Copying blob sha256:367d845540573038025f445c654675aa63905ec8682938fb45bc00f40849c37b 71.46 MB / ? [------------=----------------------------------------------] 23s Copying blob sha256:b82a357e4f15fda58e9728fced8558704e3a2e1d100e93ac408edb45fe3a5cb9 1.27 KB / ? [----=--------------------------------------------------------] 0s Copying config sha256:f5ea21241da8d3bc1e92d08ca4888c2f91ed65280c66acdefbb6d2dba6cd0b29 6.52 KB / 6.52 KB [========================================================] 0s Writing manifest to image destination Storing signatures sh-4.2#

We now have our RHEL container. Let’s play with it, check its status, and then delete it and its source image:

sh-4.2# ps ax PID TTY STAT TIME COMMAND 1 pts/0 Ss 0:00 sh 10 pts/0 R+ 0:00 ps ax sh-4.2# exit [root@localhost ~]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES deda2991f9fd registry.access.redhat.com/rhel:latest sh 3 minutes ago Exited (0) Less than a second ago reverent_torvalds [root@localhost ~]# podman rm deda2991f9fd deda2991f9fd43400566abceaa917ecbd59a2e83354c5c9021ba1830a7ab196d [root@localhost ~]# podman image rm rhel f5ea21241da8d3bc1e92d08ca4888c2f91ed65280c66acdefbb6d2dba6cd0b29

As you can see, we used the same syntax as we’d use with docker . There are no differences at the moment. I didn’t check the Podman documentation and I started working immediately!

Run a MariaDB persistent container

Let’s move forward and try a more complicated test: run MariaDB 10.2 with some custom variables and try to let its “data” be persistent.

First, let’s download the MariaDB container image and inspect its details:

[root@localhost ~]# podman pull registry.access.redhat.com/rhscl/mariadb-102-rhel7Trying to pull registry.access.redhat.com/rhscl/mariadb-102-rhel7...Getting image source signatures Copying blob sha256:367d845540573038025f445c654675aa63905ec8682938fb45bc00f40849c37b 71.46 MB / ? [------------=----------------------------------------------] 10s Copying blob sha256:b82a357e4f15fda58e9728fced8558704e3a2e1d100e93ac408edb45fe3a5cb9 1.27 KB / ? [----=--------------------------------------------------------] 0s Copying blob sha256:ddec0f65683ad89fc27298921921b2f8cbf57f674ed9eb71eef4e23a9dd9bbfe 6.40 MB / ? [--------------=----------------------------------------------] 1s Copying blob sha256:105cfda934d478ffbf65d74a89af55cc5de1d5bc94874c2d163c45e31a937047 58.25 MB / ? [-------------------------------------------=---------------] 10s Copying config sha256:7ac0a23445fec91d4b458f3062e64d1ca4af4755387604f8d8cbec08926867d7 6.79 KB / 6.79 KB [========================================================] 0s Writing manifest to image destination Storing signatures 7ac0a23445fec91d4b458f3062e64d1ca4af4755387604f8d8cbec08926867d7 [root@localhost ~]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/rhscl/mariadb-102-rhel7 latest 7ac0a23445fe 9 days ago 445MB [root@localhost ~]# podman inspect 7ac0a23445fe ...

Then we can set up a folder that will handle MariaDB’s data once we start our container:

[root@localhost ~]# mkdir mysql-data [root@localhost ~]# chown 27:27 mysql-data

Please note: “27” is the ID of the mysql user that will run the MariaDB’s processes in the container. For this reason, we have to allow it to read from and write to the directory.

And finally, run it:

[root@localhost ~]# podman run -d -v /root/mysql-data:/var/lib/mysql/data:Z -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -p 3306:3306 registry.access.redhat.com/rhscl/mariadb-102-rhel7 71da2bb210b36aaab28a2dc81b8e77da4e1024d1f2d025c0a7b97b075dec1425 [root@localhost ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 71da2bb210b3 registry.access.redhat.com/rhscl/mariadb-102-rhel7:latest container-entrypoin... 3 seconds ago Up 3 seconds ago 0.0.0.0:3306->3306/udp, 0.0.0.0:3306->3306/tcp cranky_mahavira

As you can see, the container is up and running, but what is it doing? Let’s check:

[root@localhost ~]# podman logs 71da2bb210b3 | head => sourcing 20-validate-variables.sh ... => sourcing 25-validate-replication-variables.sh ... => sourcing 30-base-config.sh ... ---> 13:12:43 Processing basic MySQL configuration files ... => sourcing 60-replication-config.sh ... => sourcing 70-s2i-config.sh ... ---> 13:12:43 Processing additional arbitrary MySQL configuration provided by s2i ... => sourcing 40-paas.cnf ... => sourcing 50-my-tuning.cnf ... ---> 13:12:43 Initializing database ...

Ah! It’s just started and initialized its database. Let’s play with it:

[root@localhost ~]# mysql --user=user --password=pass -h 127.0.0.1 -P 3306 -t Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8 Server version: 10.2.8-MariaDB MariaDB Server Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | db | | information_schema | | test | +--------------------+ 3 rows in set (0.00 sec) MariaDB [(none)]> use test; Database changed MariaDB [test]> show tables; Empty set (0.00 sec)

Perfect. Now we’ll create at least a table and then we’ll terminate the container:

MariaDB [db]> CREATE TABLE mytest (username VARCHAR(20), date DATETIME); Query OK, 0 rows affected (0.02 sec) MariaDB [db]> show tables; +--------------+ | Tables_in_db | +--------------+ | mytest | +--------------+ 1 row in set (0.00 sec) MariaDB [db]> Bye [root@localhost ~]# podman kill 71da2bb210b3 71da2bb210b36aaab28a2dc81b8e77da4e1024d1f2d025c0a7b97b075dec1425

Inspecting the content of the folder, we can see that data is still there, but let’s start a new container for checking the data persistence:

[root@localhost ~]# ls -la mysql-data/ total 41024 drwxr-xr-x. 6 27 27 4096 Aug 24 09:12 . dr-xr-x---. 4 root root 219 Aug 24 09:28 .. -rw-rw----. 1 27 27 2 Aug 24 09:12 71da2bb210b3.pid -rw-rw----. 1 27 27 16384 Aug 24 09:12 aria_log.00000001 -rw-rw----. 1 27 27 52 Aug 24 09:12 aria_log_control drwx------. 2 27 27 56 Aug 24 09:27 db -rw-rw----. 1 27 27 2799 Aug 24 09:12 ib_buffer_pool -rw-rw----. 1 27 27 12582912 Aug 24 09:27 ibdata1 -rw-rw----. 1 27 27 8388608 Aug 24 09:27 ib_logfile0 -rw-rw----. 1 27 27 8388608 Aug 24 09:12 ib_logfile1 -rw-rw----. 1 27 27 12582912 Aug 24 09:12 ibtmp1 -rw-rw----. 1 27 27 0 Aug 24 09:12 multi-master.info drwx------. 2 27 27 4096 Aug 24 09:12 mysql -rw-r--r--. 1 27 27 14 Aug 24 09:12 mysql_upgrade_info drwx------. 2 27 27 20 Aug 24 09:12 performance_schema -rw-rw----. 1 27 27 24576 Aug 24 09:12 tc.log drwx------. 2 27 27 6 Aug 24 09:12 test [root@localhost ~]# podman run -d -v /root/mysql-data:/var/lib/mysql/data:Z -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -p 3306:3306 registry.access.redhat.com/rhscl/mariadb-102-rhel7 0364513f6b6ae1b86ea3752ec732bad757770ca14ec1f879e7487f3f4293004d [root@localhost ~]# podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0364513f6b6a registry.access.redhat.com/rhscl/mariadb-102-rhel7:latest container-entrypoin... 3 seconds ago Up 2 seconds ago 0.0.0.0:3306->3306/udp, 0.0.0.0:3306->3306/tcp heuristic_northcutt [root@localhost ~]# mysql --user=user --password=pass -h 127.0.0.1 -P 3306 -t Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8 Server version: 10.2.8-MariaDB MariaDB Server Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> use db; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [db]> show tables; +--------------+ | Tables_in_db | +--------------+ | mytest | +--------------+ 1 row in set (0.00 sec) MariaDB [db]> Bye [root@localhost ~]# podman kill 0364513f6b6a 0364513f6b6ae1b86ea3752ec732bad757770ca14ec1f879e7487f3f4293004d

Great! MariaDB’s data is still there and the new container read it and showed it once as requested.

Manage containers as system services through systemd and Podman

Finally, we’ll create a simple systemd resource for handling the previously created MariaDB container.

First, we need to create a systemd resource file for handling the brand new container service:

[root@localhost ~]# cat /etc/systemd/system/mariadb-podman.service [Unit] Description=Custom MariaDB Podman Container After=network.target [Service] Type=simple TimeoutStartSec=5m ExecStartPre=-/usr/bin/podman rm "mariadbpodman" ExecStart=/usr/bin/podman run --name mariadbpodman -v /root/mysql-data:/var/lib/mysql/data:Z -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -p 3306:3306 registry.access.redhat.com/rhscl/mariadb-102-rhel7 ExecReload=-/usr/bin/podman stop "mariadbpodman" ExecReload=-/usr/bin/podman rm "mariadbpodman" ExecStop=-/usr/bin/podman stop "mariadbpodman" Restart=always RestartSec=30 [Install]

Then we can reload the systemd catalog and start the service:

[root@localhost ~]# systemctl daemon-reload [root@localhost ~]# systemctl start mariadb-podman [root@localhost ~]# systemctl status mariadb-podman mariadb-podman.service - Custom MariaDB Podman Container Loaded: loaded (/etc/systemd/system/mariadb-podman.service; static; vendor preset: disabled) Active: active (running) since Fri 2018-08-24 10:14:36 EDT; 3s ago Process: 19147 ExecStartPre=/usr/bin/podman rm mariadbpodman (code=exited, status=0/SUCCESS) Main PID: 19172 (podman) CGroup: /system.slice/mariadb-podman.service └─19172 /usr/bin/podman run --name mariadbpodman -v /root/mysql-data:/var/lib/mysql/data:Z -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DA... Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140578968823552 [Note] InnoDB: Buffer pool(s) load completed at 180824 14:14:39 Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Note] Plugin 'FEEDBACK' is disabled. Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Note] Server socket created on IP: '::'. Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Warning] 'user' entry 'root@71da2bb210b3' ignored in --sk...ve mode. Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Warning] 'user' entry '@71da2bb210b3' ignored in --skip-n...ve mode. Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Warning] 'proxies_priv' entry '@% root@71da2bb210b3' igno...ve mode. Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Note] Reading of all Master_info entries succeded Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Note] Added new Master_info '' to hash table Aug 24 10:14:39 localhost.localdomain podman[19172]: 2018-08-24 14:14:39 140579889719488 [Note] /opt/rh/rh-mariadb102/root/usr/libexec/mysqld: read...ections. Aug 24 10:14:39 localhost.localdomain podman[19172]: Version: '10.2.8-MariaDB' socket: '/var/lib/mysql/mysql.sock' port: 3306 MariaDB Server Hint: Some lines were ellipsized, use -l to show in full. [root@localhost ~]# systemctl stop mariadb-podman [root@localhost ~]#

Awesome! We just set up a custom system service based on a container managed through Podman.

Further resources

Do you want an easy and fast way to experiment with Podman? Katacoda is the answer. Katacoda is an interactive learning and training platform that lets you learn new technologies using real environments right in your browser!

Check it out here: katacoda.com/courses/containers-without-docker/running-containers-with-podman

To get a better understanding of Podman, see these two blog articles by Dan Walsh:

That’s all! May the containers be with you! 🙂

About Alessandro

Alessandro Arrichiello is a Solution Architect for Red Hat Inc. He has a passion for GNU/Linux systems, which began at age 14 and continues today. He works with tools for automating enterprise IT: configuration management and continuous integration through virtual platforms. He’s now working on a distributed cloud environment involving PaaS (OpenShift), IaaS (OpenStack) and processes management (CloudForms), container building, instance creation, HA services management, and workflow builds.