Chapter 2. Working with container images

Using podman, you can run, investigate, start, stop, investigate, and remove container images.

2.1. Pulling images from registries

To get container images from a remote registry (such as Red Hat’s own container registry) and add them to your local system, use the podman pull command:

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

The <registry> is a host that provides a container registry service on TCP <port>. Together, <namespace> and <name> identify a particular image controlled by <namespace> at that registry. Some registries also support raw <name>; for those, <namespace> is optional. When it is included, however, the additional level of hierarchy that <namespace> provides is useful to distinguish between images with the same <name>. For example:

NamespaceExamples (<namespace>/<name>)

organization

redhat/kubernetes, google/kubernetes

login (user name)

alice/application, bob/application

role

devel/database, test/database, prod/database

The registries that Red Hat provides are registry.redhat.io (requiring authentication), registry.access.redhat.com (requires no authentication), and registry.connect.redhat.com (holds Red Hat Partner Connect program images). For details on the transition to registry.redhat.io, see Red Hat Container Registry Authentication . Before you can pull containers from registry.redhat.io, you need to authenticate. For example:

# podman login registry.redhat.io
Username: myusername
Password: ************
Login Succeeded!

Use the pull option to pull an image from a remote registry. To pull the rhel base image and rsyslog logging image from the Red Hat registry, type:

# podman pull registry.redhat.io/ubi8/ubi
# podman pull registry.redhat.io/rhel8/rsyslog

An image is identified by a registry name (registry.redhat.io), a namespace name (ubi8) and the image name (ubi). You could also add a tag (which defaults to :latest if not entered). The repository name ubi, when passed to the podman pull command without the name of a registry preceding it, is ambiguous and could result in the retrieval of an image that originates from an untrusted registry. If there are multiple versions of the same image, adding a tag, such as latest to form a name such as ubi8/ubi:latest, lets you choose the image more explicitly.

To see the images that resulted from the above podman pull command, along with any other images on your system, type podman images:

REPOSITORY                        TAG    IMAGE ID      CREATED     SIZE
registry.redhat.io/ubi8/ubi       latest eb205f07ce7d  2 weeks ago 214MB
registry.redhat.io/rhel8/rsyslog  latest 85cfba5cd49c  2 weeks ago 234MB

The ubi and rsyslog images are now available on your local system for you to work with.

2.2. Investigating images

Using podman images you can see which images have been pulled to your local system. To look at the metadata associated with an image, use podman inspect.

2.2.1. Listing images

To see which images have been pulled to your local system and are available to use, type:

# podman images
REPOSITORY                               TAG      IMAGE ID     CREATED      VIRTUAL SIZE
registry.redhat.io/rhel8/support-tools   latest   b3d6ce4e0043 2 days ago   234MB
registry.redhat.io/ubi8/ubi-init         latest   779a05997856 2 days ago   225MB
registry.redhat.io/ubi8/ubi              latest   a80dad1c1953 3 days ago   210MB

2.2.2. Inspecting local images

After you pull an image to your local system and before you run it, it is a good idea to investigate that image. Reasons for investigating an image before you run it include:

  • Understanding what the image does
  • Checking what software is inside the image

The podman inspect command displays basic information about what an image does. You also have the option of mounting the image to your host system and using tools from the host to investigate what’s in the image. Here is an example of investigating what a container image does before you run it:

  1. Inspect an image: Run podman inspect to see what command is executed when you run the container image, as well as other information. Here are examples of examining the ubi8/ubi and rhel8/rsyslog container images (with only snippets of information shown here):

    # podman pull registry.redhat.io/ubi8/ubi
    # podman inspect registry.redhat.io/ubi8/ubi | less
    ...
       "Cmd": [
           "/bin/bash"
       ],
       "Labels": {
           "License": "GPLv3",
           "architecture": "x86_64",
           "authoritative-source-url": "registry.redhat.io",
           "build-date": "2018-10-24T16:46:08.916139",
           "com.redhat.build-host": "cpt-0009.osbs.prod.upshift.rdu2.redhat.com",
           "com.redhat.component": "rhel-server-container",
           "description": "The Red Hat Enterprise Linux Base image is designed to be a fully supported...
    ...
    # podman pull registry.redhat.io/rhel8/rsyslog
    # podman inspect registry.redhat.io/rhel8/rsyslog
       "Cmd": [
         "/bin/rsyslog.sh"
       ],
       "Labels": {
         "License": "GPLv3",
         "architecture": "x86_64",
    ...
         "install": "podman run --rm --privileged -v /:/host -e HOST=/host -e IMAGE=IMAGE -e NAME=NAME IMAGE /bin/install.sh",
    ...
         "run": "podman run -d --privileged --name NAME --net=host --pid=host -v /etc/pki/rsyslog:/etc/pki/rsyslog -v /etc/rsyslog.conf:/etc/rsyslog.conf -v /etc/sysconfig/rsyslog:/etc/sysconfig/rsyslog -v /etc/rsyslog.d:/etc/rsyslog.d -v /var/log:/var/log -v /var/lib/rsyslog:/var/lib/rsyslog -v /run:/run -v /etc/machine-id:/etc/machine-id -v /etc/localtime:/etc/localtime -e IMAGE=IMAGE -e NAME=NAME --restart=always IMAGE /bin/rsyslog.sh",
         "summary": "A containerized version of the rsyslog utility
    ...

    The ubi8/ubi container will execute the bash shell, if no other argument is given when you start it with podman run. If an Entrypoint were set, its value would be used instead of the Cmd value (and the value of Cmd would be used as an argument to the Entrypoint command).

    In the second example, the rhel8/rsyslog container image has built-in install and run labels. Those labels give an indication of how the container is meant to be set up on the system (install) and executed (run).

  2. Mount a container: Using the podman command, mount an active container to further investigate its contents. This example runs and lists a running rsyslog container, then displays the mount point from which you can examine the contents of its file system:

    # podman run -d registry.redhat.io/rhel8/rsyslog
    # podman ps
    CONTAINER ID IMAGE             COMMAND         CREATED        STATUS      PORTS NAMES
    1cc92aea398d ...rsyslog:latest /bin/rsyslog.sh 37 minutes ago Up 1 day ago      myrsyslog
    # podman mount 1cc92aea398d
    /var/lib/containers/storage/overlay/65881e78.../merged
    # ls /var/lib/containers/storage/overlay/65881e78*/merged
    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

    After the podman mount, the contents of the container are accessible from the listed directory on the host. Use ls to explore the contents of the image.

  3. Check the image’s package list: To check the packages installed in the container, tell the rpm command to examine the packages installed on the container’s mount point:

    # rpm -qa --root=/var/lib/containers/storage/overlay/65881e78.../merged
    redhat-release-server-7.6-4.el7.x86_64
    filesystem-3.2-25.el7.x86_64
    basesystem-10.0-7.el7.noarch
    ncurses-base-5.9-14.20130511.el7_4.noarch
    glibc-common-2.17-260.el7.x86_64
    nspr-4.19.0-1.el7_5.x86_64
    libstdc++-4.8.5-36.el7.x86_64

2.2.3. Inspecting remote images

To inspect a container image before you pull it to your system, you can use the skopeo inspect command. With skopeo inspect, you can display information about an image that resides in a remote container registry.

The following command inspects the ubi8-init image from the Red Hat registry:

# skopeo inspect docker://registry.redhat.io/ubi8/ubi8-init
{
    "Name": "registry.redhat.io/ubi8/ubi8-init",
    "Digest": "sha256:53dfe24...",
    "RepoTags": [
        "8.0.0-9",
        "8.0.0",
        "latest"
    ],
    "Created": "2019-05-13T20:50:11.437931Z",
    "DockerVersion": "1.13.1",
    "Labels": {
        "architecture": "x86_64",
        "authoritative-source-url": "registry.access.redhat.com",
        "build-date": "2019-05-13T20:49:44.207967",
        "com.redhat.build-host": "cpt-0013.osbs.prod.upshift.rdu2.redhat.com",
        "com.redhat.component": "ubi8-init-container",
        "description": "The Red Hat Enterprise Linux Init image is designed to be...

2.3. Searching for images

The podman search command lets you search selected container registries for images. The registries searched come from those listed in the registries.conf file.

Note

Another, more intuitive way, to search for images maintained by Red Hat is to search the Red Hat Container Registry. Included with each image listed in the Red Hat Container Catalog are descriptions of the image, its contents, health index, and other pertinent information.

By default, podman search searches the following registries:

  • registry.redhat.io
  • registry.access.redhat.com
  • quay.io
  • docker.io

As root user, you can edit the /etc/containers/registries.conf file to change the default, system-wide search settings. As a regular (rootless) user of podman, you can create your own registries.conf file in your home directory ($HOME/.config/containers/registries.conf) to override the system-wide settings.

The following are some podman search command examples. The first example illustrates trying, but failing, to search all images accessible to you from quay.io. The backslash at the end says to search the whole registry for all images accessible to you:

# podman search quay.io/
ERRO[0000] error searching registry "quay.io": couldn't search registry "quay.io":
unable to retrieve auth token: invalid username/password

Try again, but this time log in first:

# podman login quay.io
Username: johndoe
Password: ***********
Login Succeeded!
# podman search quay.io/
INDEX     NAME                                       DESCRIPTION   STARS   OFFICIAL   AUTOMATED
quay.io   quay.io/test/myquay                                      0
quay.io   quay.io/test/redistest                                   0
quay.io   quay.io/johndoe/websrv21                                 0
quay.io   quay.io/johndoe/mydbtest                                 0
quay.io   quay.io/johndoe/newbuild-10                              0

Search all available registries for postgresql (resulting in more than 40 images found):

# podman search postgresql-10
INDEX       NAME                                            DESCRIPTION                    STARS OFFICIAL AUTOMATED
redhat.io   registry.redhat.io/rhel8/postgresql-10          This container image ...       0
redhat.io   registry.redhat.io/rhscl/postgresql-10-rhel7    PostgreSQL is an advanced ...  0
quay.io     quay.io/mettle/postgresql-database-provisioning
docker.io   docker.io/centos/postgresql-10-centos7          PostgreSQL is an advanced ... 13
...

To limit your search for postgresql to images from registry.redhat.io, type the following. Notice that by entering the registry and the image name, any repository in the registry can be matched:

# podman search registry.redhat.io/postgresql-10
INDEX       NAME                                           DESCRIPTION           STARS   OFFICIAL   AUTOMATED
redhat.io   registry.redhat.io/rhel8/postgresql-10         This container image ...  0
redhat.io   registry.redhat.io/rhscl/postgresql-10-rhel7   PostgreSQL is an  ...     0

To get longer descriptions, add --no-trunc:

# podman search --no-trunc registry.redhat.io/rhel8/postgresql-10
INDEX       NAME   DESCRIPTION              STARS   OFFICIAL   AUTOMATED
redhat.io   registry.redhat.io/rhel8/postgresql-10
                   This container image provides a containerized
                   packaging of the PostgreSQL postgres daemon and
                   client application. The postgres server daemon
                   accepts connections from clients and provides
                   access to content from PostgreSQL databases on
                   behalf of the clients.   0

If you want to change your search to use a registry that is not currently set up to search, edit the [registries.search] section of the /etc/containers/registries.conf file. One reason you might want to do this is to find a Red Hat partner-supported image (such as crunchy-postgres) instead of a public one from docker.io or quay.io. To do that, change this:

[registries.search]
registries = ['registry.redhat.io', 'registry.access.redhat.com', 'quay.io', 'docker.io']

To this:

[registries.search]
registries = ['registry.connect.redhat.com']

Now search for crunchy-postgres:

# podman search crunchy-postgres
INDEX      NAME
   DESCRIPTION                                       STARS  OFFICIAL  AUTOMATED
redhat.com registry.connect.redhat.com/crunchydata/crunchy-postgres
   The crunchy-postgres container executes the ...   0
redhat.com   registry.connect.redhat.com/crunchydata/crunchy-postgres-gis
   The crunchy-postgres-gis container executes ...   0

Instead of choosing from random Crunchy postgres database images, you can see a list of images supported by an official Red Hat partner.

2.4. Tagging images

You can add names to images to make it more intuitive to understand what they contain. Tagging images can also be used to identify the target registry for which the image is intended. Using the podman tag command, you essentially add an alias to the image that can consist of several parts. Those parts can include:

registryhost/username/NAME:tag

You can add just NAME if you like. For example:

# podman tag 474ff279782b myrhel8

In the previous example, the rhel8 image had an image ID of 474ff279782b. Using podman tag, the name myrhel8 now also is attached to the image ID. So you could run this container by name (rhel8 or myrhel8) or by image ID. Notice that without adding a :tag to the name, it was assigned :latest as the tag. You could have set the tag to 8.0 as follows:

# podman tag 474ff279782b myrhel8:8.0

To the beginning of the name, you can optionally add a user name and/or a registry name. The user name is actually the repository on Docker.io that relates to the user account that owns the repository. Tagging an image with a registry name was shown in the "Tagging Images" section earlier in this document. Here’s an example of adding a user name:

# podman tag 474ff279782b jsmith/myrhel8
# podman images | grep 474ff279782b
rhel8           latest  474ff279782b  7 days ago  139.6 MB
myrhel8         latest  474ff279782b  7 months ago  139.6 MB
myrhel8         7.1     474ff279782b  7 months ago  139.6 MB
jsmith/myrhel8  latest  474ff279782b  7 months ago  139.6 MB

Above, you can see all the image names assigned to the single image ID.

2.5. Saving and loading images

If you want to save a container image you have stored locally, you can use podman save to save the image to an archive file or directory and restore it later to another container environment. The archive you save can be in any of several different container image formats: docker-archive, oci-archive, oci-dir (directory with oci manifext type), or docker-dir (directory with v2s2 manifest type). After you save an image, you can store it or send it to someone else, then load the image later to reuse it. Here is an example of saving an image as a tarball in the default docker-archive format:

# podman save -o myrsyslog.tar registry.redhat.io/rhel8/rsyslog:latest
# file myrsyslog.tar
myrsyslog.tar: POSIX tar archive

The myrsyslog.tar file is now stored in your current directory. Later, when you are ready to reuse the tarball as a container image, you can import it to another podman environment as follows:

# podman load -i myrsyslog.tar
# podman images
REPOSITORY                       TAG    IMAGE ID      CREATED     SIZE
registry.redhat.io/rhel8/rsyslog latest 1f5313131bf0  7 weeks ago 235 MB

Instead of using save and load to store and reload an image, you can make a copy of a container instead, using podman export and podman import.

2.6. Removing Images

To see a list of images that are on your system, run the podman images command. To remove images you no longer need, use the podman rmi command, with the image ID or name as an option. (You must stop any containers run from an image before you can remove the image.) Here is an example:

# podman rmi ubi8-init
7e85c34f126351ccb9d24e492488ba7e49820be08fe53bee02301226f2773293

You can remove multiple images on the same command line:

# podman rmi registry.redhat.io/rhel8/rsyslog support-tools
46da8e23fa1461b658f9276191b4f473f366759a6c840805ed0c9ff694aa7c2f
85cfba5cd49c84786c773a9f66b8d6fca04582d5d7b921a308f04bb8ec071205

If you want to clear out all your images, you could use a command like the following to remove all images from your local registry (make sure you mean it before you do this!):

# podman rmi -a
1ca061b47bd70141d11dcb2272dee0f9ea3f76e9afd71cd121a000f3f5423731
ed904b8f2d5c1b5502dea190977e066b4f76776b98f6d5aa1e389256d5212993
83508706ef1b603e511b1b19afcb5faab565053559942db5d00415fb1ee21e96

To remove images that have multiple names (tags) associated with them, you need to add the force option to remove them. For example:

# podman rmi -a
A container associated with containers/storage, i.e. via Buildah, CRI-O, etc., may be associated with this image: 1de7d7b3f531

# podman rmi -f 1de7d7b3f531
1de7d7b3f531...