How to Manage Containers Using Podman and Skopeo in RHEL 8

One of the challenges developers faced in the past is getting applications to run reliably across multiple computing environments. Oftentimes, applications didn’t run as expected or encountered errors and failed altogether. And that’s where the concept of containers was born.

What are Container Images?

Container images are static files that ship with executable code that runs in an isolated environment. A container image comprises system libraries, dependencies & other platform settings needed by the application to run in diverse environments.

Red Hat Linux provides a set of useful container tools that you can leverage to work directly with Linux containers using requiring docker commands. These include:

  • Podman – This is a daemon less container engine for running and managing OCI containers in either root or rootless mode. Podman is similar to Docker and has the same command options except that Docker is a daemon. You can pull, run, and manage container images using podman in much the same way as you would with Docker. Podman comes with lots of advanced features, fully integrates with systems, and offers user Namespace support which includes running containers without the need for a root user.
  • Skopeo: This is a command-line tool used for copying container images from one registry to another. You can use Skopeo to copy images to and from a particular host as well as copy images to another container registry or environment. Apart from copying images, you can use it to inspect images from various registries and use signatures to create and verify images.
  • Buildah: This is a set of command-line tools used for creating and managing container OCI images using Docker files.

In this article, we will focus on Managing containers using podman and Skopeo.

Searching Container Images from a Remote Registry

The podman search command allows you to search selected remote registries for container images. The default list of registries is defined in the registries.conf file located in the /etc/containers/ directory.

The registries are defined by 3 sections.

  • [registries.search] – This section specifies the default registries that podman can search for container images. It searches for the requested image in the registry.access.redhat.com, registry.redhat.io, and docker.io registries.
Default Registries
Default Registries
  • [registries.insecure]– This section specifies registries that do not implement TLS encryption i.e insecure registries. By default, no entries are specified.
Insecure Registries
Insecure Registries
  • [registries.block] – This blocks or denies access to the specified registries from your local system. By default, no entries are specified.
Blocks Registries
Blocks Registries

As a regular (non-root) user running the podman command, you can define your own registries.conf file on your home directory ($HOME/.config/containers/registries.conf) to override system-wide settings.

Rules When Specifying Registries

As you specify the registries, keep in mind the following:

  • Every registry should be enclosed by single quotes.
  • Registries can be specified using either a hostname or IP address.
  • If multiple registries are specified, then they should be separated by commas.
  • If a registry uses a non-standard port – either port TCP ports 443 for secure and 80 for insecure, – the port number should be specified alongside the registry name e.g. registry.example.com:5566.

To search a registry for a container image using the syntax:

# podman search registry/container_image

For example, to search for a Redis image in the registry.redhat.io registry, invoke the command:

# podman search registry.redhat.io/redis
Search Registry for Container Image
Search Registry for Container Image

To search for a MariaDB container image run.

# podman search registry.redhat.io/mariadb
Search MariaDB Container Image
Search MariaDB Container Image

To obtain an elaborate description of a container image, use the --no-trunc option before the name of the container image from the results that you get. For instance, we will try to obtain a detailed description of the MariaDB container image as shown:

# podman search --no-trunc registry.redhat.io/rhel8/mariadb-103
List Description of MariaDB Container Image
List Description of MariaDB Container Image

Pulling Container Images

Pulling or retrieving container images from a remote registry requires that you first authenticate before anything else. For example, to retrieve the MariaDB container image, first log in to the Redhat registry:

# podman login

Provide your username and password and hit ‘ENTER‘ on your keyboard. If all goes well, you should get a confirmation message that the login to the registry was successful.

Login Succeeded!

Now, you can pull the image using the syntax shown:

# podman pull <registry>[:<port>]/[<namespace>/]<name>:<tag>

The <registry> refers to the remote host or registry that provides a repository of container images on the TCP <port>. The <namespace> and the <name> collectively specify a container image based on the <namespace> at the registry. Finally, the <tag> option specifies the version of the container image. If none is specified, the default tag – latest – is used.

It’s always recommended to add trusted registries, that is those that provide encryption and don’t allow anonymous users to spawn accounts with random names.

To pull the MariaDB image, run the command:

# podman pull registry.redhat.io/rhel8/mariadb-103
  • The <registry> – registry.redhat.io
  • The <namespace> – rhel8
  • The <name> – MariaDB
  • The <tag> – 103
Pull MariaDB Image
Pull MariaDB Image

For subsequent container images pull, no further logging in is required since you are already authenticated. To pull a Redis container image, simply run:

# podman pull registry.redhat.io/rhscl/redis-5-rhel7
Pull Redis Container Image
Pull Redis Container Image

Listing Container Images

Once you are done pulling the images, you can view the images currently existing on your host by running the podman images command.

# podman images
List Container Images
List Container Images

Inspecting Container Images

Before running a container, it’s always a good idea to probe the image and get to understand what it does. The podman inspect command prints out a sea of metadata about the container such as the OS and Architecture.

To inspect an image, run the podman inspect command followed by the image ID or repository.

# podman inspect IMAGE ID
OR
# podman inspect REPOSITORY

In the example below, we’re inspecting the MariaDB container.

# podman inspect registry.redhat.io/rhel8/mariadb-103
Inspecting MariaDB Container Images
Inspecting MariaDB Container Images

To pull specific metadata for a container pass the --format option followed by the metadata and the container identity ( Image ID or name ).

In the example below, we’re retrieving information about the architecture and description of the RHEL 8 base container which falls under the ‘Labels’ section.

# podman inspect --format=’{{.Labels.architecture}}’ image ID
# podman inspect --format=’{{.Labels.description}}’ image ID
Get Info About Container Architecture
Get Info About Container Architecture

To inspect a remote image from another registry, use the skopeo inspect command. In the example below, we are inspecting an RHEL 8 init image hosted on Docker.

# skopeo inspect docker://registry.redhat.io/rhel8-beta/rhel-init
Inspect Remote Image from Docker Registry
Inspect Remote Image from Docker Registry

Tagging Container Images

As you might have noted, image names are usually generic in nature. For example, the redis image is labeled:

registry.redhat.io/rhscl/redis-5-rhel7

Tagging images gives them a more intuitive name to better understand what they contain. Using the podman tag command, you can create an image tag which is essentially an alias to an image name that comprises different parts.

These are:

registry/username/NAME:tag

For example, to change the generic name of the Redis image which has an ID of 646f2730318c , we will execute the command:

# podman tag 646f2730318c myredis

To add a tag at the end append a full colon followed by the tag number:

# podman tag 646f2730318c myredis:5.0

Without adding the tag number, it will just be assigned the attribute latest.

Set Name for Redis Container Image
Set Name for Redis Container Image

Running Container Images

To run a container, use the podman run command. For example:

# podman run image_id

To run a container silently in the background as a daemon service use the -d option as shown.

# podman run -d image_id

For example, to run the redis image with ID 646f2730318c, we will invoke the command:

# podman run -d 646f2730318c
Run Redis Container Images
Run Redis Container Images

If you are running a container based on an operating system such as RHEL 8 base image, you can gain access to the shell using the -it directive. The -i option creates an interactive session while the -t spawns a terminal session. The --name option sets the container name to mybash while is the ecbc6f53bba0 image id of the base image.

# podman run -it --name=mybash ecbc6f53bba0

Thereafter, you can run any shell commands. In the example below, we are verifying the OS version of the container image.

# cat /etc/os-release
Verify Container Image OS Version
Verify Container Image OS Version

To exit the container, simply invoke the exit command.

# exit

Once the container is exited, it automatically stops. To start the container again, use the podman start command with the -ai flag as shown.

# podman start -ai mybash

Once again, this gives you access to the shell.

Start Container Images
Start Container Images

Listing Running Container Images

To list currently running containers, use the podman ps command as shown.

# podman ps
List Running Container Images
List Running Container Images

To view all containers including those ones that have exited after running, use the command:

# podman ps -a
View All Container Images
View All Container Images

Configure Container Images to Auto Start Under Systemd Service

In this section, we focus on how a container can be configured to run directly on an RHEL system as a systemd service.

First, get your preferred image. In this case, we have pulled the Redis image from docker hub:

# podman pull docker.io/redis

If you have SELinux running on your system, you need to activate the container_manage_cgroup boolean to run containers with systemd.

# setsebool -p container_manage_cgroup on

Thereafter, run the container image in the background and assign it to your preferred image name. In this example, we have named our image redis_server and mapped the port 6379 from the container to our RHEL 8 host

# podman run -d --name redis_server -p 6379:6379 redis
Run Container Image in Background
Run Container Image in Background

Next, we are going to create a systemd unit configuration file for redis in the /etc/systemd/system/ directory.

# vim /etc/systemd/system/redis-container.service

Paste the content below to the file.

[Unit]
Description=Redis container

[Service]
Restart=always
ExecStart=/usr/bin/podman start -a redis_server
ExecStop=/usr/bin/podman stop -t 2 redis_server

[Install]
WantedBy=local.target

Save and exit the file.

Next, configure the container to start automatically on bootup.

# systemctl enable redis-container.service

Next, start the container and verify its running status.

# systemctl start redis-container.service
# systemctl status redis-container.service
Verify Container Image Status
Verify Container Image Status

Configure Persistent Storage for Container Images

When running containers, it’s prudent to configure persistent external storage on the host. This provides a backup in case the container crashes or gets removed accidentally.

To persist the data, we are going to map a directory located in the host to a directory inside the container.

$ podman run --privileged -it -v /var/lib/containers/backup_storage:/mnt registry.redhat.io/ubi8/ubi /bin/bash

The --privileged option is passed when SELinux is set to enforcing. The -v option specifies the external volume which is located on the host. The container volume here is the /mnt directory.

Once we have accessed the shell, we are going to create a sample file testing.txt in the /mnt directory as shown.

$ echo "This tests persistent external storage" > /mnt/testing.txt

We will then exit the container and check whether the file exists in the external storage residing on the host

# exit
# cat /var/lib/containers/backup_storage/testing.txt

OutputThis tests persistent external storage.

Configure Persistent Storage for Containers
Configure Persistent Storage for Containers

Stopping and Removing Containers

Once you are done with running your container, you can stop it using the podman stop command followed by the container-id which you can obtain from the podman ps command.

# podman stop container-id
Stop Container Image
Stop Container Image

To remove the containers that you no longer need, first, ensure that you stop it and then invoke the podman rm command followed by the container id or name as an option.

# podman rm container-id

To remove multiple containers at a go in one command, specify the container ids separated by a space.

# podman rm container-id-1 container-id-2 container-id-3
Remove Container Image
Remove Container Image

To clear all your containers, run the command:

# podman rm -a
Clear All Containers
Clear All Containers

Removing an Image

To remove an image, first, ensure that all containers spawned from the images are stopped and removed as discussed in the previous sub-topic.

Next, proceed and run the podman -rmi command followed by the ID of the image as shown:

# podman -rmi image-id
Remove Image
Remove Image

Conclusion

This wraps up this chapter on managing and working with containers in RHEL 8. We hope this guide provided a decent understanding of containers and how you can interact and manage them on your RHEL system using podman and Skopeo.

Hey TecMint readers,

Exciting news! Every month, our top blog commenters will have the chance to win fantastic rewards, like free Linux eBooks such as RHCE, RHCSA, LFCS, Learn Linux, and Awk, each worth $20!

Learn more about the contest and stand a chance to win by sharing your thoughts below!

James Kiarie
This is James, a certified Linux administrator and a tech enthusiast who loves keeping in touch with emerging trends in the tech world. When I'm not running commands on the terminal, I'm taking listening to some cool music. taking a casual stroll or watching a nice movie.

Each tutorial at TecMint is created by a team of experienced Linux system administrators so that it meets our high-quality standards.

Join the TecMint Weekly Newsletter (More Than 156,129 Linux Enthusiasts Have Subscribed)
Was this article helpful? Please add a comment or buy me a coffee to show your appreciation.

3 Comments

Leave a Reply
  1. We can also use the podman to generate commands instead of creating the file manually.

    # podman generate systemd --new --files --name redis-server
    
    Reply

Got Something to Say? Join the Discussion...

Thank you for taking the time to share your thoughts with us. We appreciate your decision to leave a comment and value your contribution to the discussion. It's important to note that we moderate all comments in accordance with our comment policy to ensure a respectful and constructive conversation.

Rest assured that your email address will remain private and will not be published or shared with anyone. We prioritize the privacy and security of our users.