Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 3. Working with container images

This explains how to work with container images. How to pull the image, inspect, tag, save, load, redistribute, define the image signature.

3.1. Configuring container registries

Using the podman search command you can search selected container registries for images. You can also search for images in the Red Hat Container Registry. The Red Hat Container Registry includes the image description, contents, health index, and other information.

You can find the list of registries in the configuration file registries.conf. As a root user, edit the /etc/containers/registries.conf file to change the default, system-wide search settings.

As a user create the $HOME/.config/containers/registries.conf file to override the system-wide settings.

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

[registries.insecure]
registries = []

[registries.block]
registries = []
  • By default, the podman search command searches for container images from registries listed in the [registries.search] section in the given order. In this case, the command searches the requested image in registry.access.redhat.com, registry.redhat.io, and docker.io in this order.
  • The [registries.insecure] section defines registries that do not use TLS encryption for the communication with the registry, what makes them insecure.
  • The [registries.block] section defines registries the local system is not allowed to access.

Make sure that you follow the conditions when configuring container registries:

  • Each registry must be surrounded by single quotes.
  • If there are multiple registries set for the registries = key, you must separate those registries by commas.
  • You can identify registries by either IP address or host name.
  • If the registry uses a non-standard port - other than the TCP ports 443 for encrypted and 80 for unencrypted connections, enter that port number with the registry name. For example: host.example.com:9999.
  • The system searches for registries in the order in which they appear in the registries.search list.

To access insecure registries, add the fully-qualified name (FQDN) of the registry to the [registries.insecure] section of the /etc/containers/registries.conf file. For example:

[registries.insecure]
registries = ['insecure-registry.example.com']

3.2. Searching for container images

This section explains how to search for the postresql-10 images in the quay.io registry.

Prerequisites

  • The registry is configured.

Procedure

  1. Authenticate to the registry:

    # podman login quay.io
  2. Search for the image:

    • To search for a particular image on a specific registry, enter:

      podman search quay.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
    • Alternatively, to display all images provided by a particular registry, enter:

      # podman search quay.io/
    • To search for the image name in all registries, enter:

      # podman search postgresql-10

      To display the full descriptions, pass the --no-trunc option to the command.

3.3. 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>

For example, the registry.redhat.io/ubi8/ubi container image is identified by:

  • Registry server (registry.redhat.io)
  • Namespace (ubi8)
  • Image name (ubi)

If there are multiple versions of the same image, add a tag to explicitly specify the image name. By default, podman uses :latest, for example ubi8/ubi:latest.

Procedure

  1. Log in to the registry.redhat.io registry:

    $ podman login registry.redhat.io
    Username: username
    Password: **********
    Login Succeeded!
  2. Pull the registry.redhat.io/ubi8/ubi container image:

    $ podman pull registry.redhat.io/ubi8/ubi

Verification steps

  • To list all images pulled to your local system:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED      SIZE
    registry.redhat.io/ubi8/ubi          latest  3269c37eae33  7 weeks ago  208 MB

3.4. Pulling an image using Podman

Always use fully qualified image names including registry, namespace, image name, and tag. When using short names, there is always an inherent risk of spoofing. Add registries that are trusted, that is, registries that do not allow unknown or anonymous users to create accounts with arbitrary names.

For example, a user wants to pull the example container image from example.registry.com registry. If example.registry.com is not first in the search list, an attacker could place a different example image at a registry earlier in the search list. The user would accidentally pull and run the attacker image rather than the intended content.

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)
  • 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 using your RHEL Subscription credentials.

3.5. Listing images

Use the podman images command to list images in your local storage.

Prerequisites

  • A pulled image is available on the local system.

Procedure

  • List all images in the local storage:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED      SIZE
    registry.access.redhat.com/ubi8/ubi  latest  3269c37eae33  6 weeks ago  208 MB

3.6. Inspecting local images

After you pull an image to your local system and run it, you can use the podman inspect command to investigate the image. For example, use it to understand what the image does and check what software is inside the image. The podman inspect command displays information on containers and images identified by name or ID.

Prerequisites

  • A pulled image is available on the local system.

Procedure

  • Inspect the registry.redhat.io/ubi8/ubi image:

    $ podman inspect registry.redhat.io/ubi8/ubi
    …
     "Cmd": [
            "/bin/bash"
        ],
        "Labels": {
            "architecture": "x86_64",
            "build-date": "2020-12-10T01:59:40.343735",
            "com.redhat.build-host": "cpt-1002.osbs.prod.upshift.rdu2.redhat.com",
            "com.redhat.component": "ubi8-container",
            "com.redhat.license_terms": "https://www.redhat.com/...,
        "description": "The Universal Base Image is ...
        }
    ...

    The "Cmd" key specifies a default command to run within a container. You can override this command by specifying a command as an argument to the podman run command. This ubi8/ubi container will execute the bash shell, if no other argument is given when you start it with podman run. If an "Entrypoint" key was set, its value would be used instead of the "Cmd" value, and the value of "Cmd" is used as an argument to the Entrypoint command.

3.7. Inspecting remote images

Use skopeo inspect to display information about an image from a remote container registry before you pull the image to your system.

Procedure

  1. Inspect the registry.redhat.io/ubi8/ubi-init image:

    # skopeo inspect docker://registry.redhat.io/ubi8/ubi-init
    {
        "Name": "registry.redhat.io/ubi8/ubi8-init",
        "Digest": "sha256:c6d1e50ab...",
        "RepoTags": [
            "8.2-13-source",
            "8.0-15",
            "8.1-28",
            ...
            "latest"
        ],
       "Created": "2020-12-10T07:16:37.250312Z",
        "DockerVersion": "1.13.1",
        "Labels": {
            "architecture": "x86_64",
            "build-date": "2020-12-10T07:16:11.378348",
            "com.redhat.build-host": "cpt-1007.osbs.prod.upshift.rdu2.redhat.com",
            "com.redhat.component": "ubi8-init-container",
            "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI",
            "description": "The Universal Base Image Init is designed to run an init system as PID 1 for running multi-services inside a container
            ...

3.8. Tagging images

Use the podman tag command to add an additional name to a local image. This additional name can consist of several parts: registryhost/username/NAME:tag.

Prerequisites

  • A pulled image is available on the local system.

Procedure

  1. List all images:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED      SIZE
    registry.redhat.io/ubi8/ubi          latest  3269c37eae33  7 weeks ago  208 MB
  2. Assign the myubi name to the registry.redhat.io/ubi8/ubi image using either:

    • The image name:

      $ podman tag registry.redhat.io/ubi8/ubi myubi
    • The image ID:

      $ podman tag 3269c37eae33 myubi

      Both commands give you the same result.

  3. List all images:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED       SIZE
    registry.redhat.io/ubi8/ubi          latest  3269c37eae33  2 months ago  208 MB
    localhost/myubi                      latest  3269c37eae33  2 months ago  208 MB

    Notice that the default tag is latest for both images. You can see all the image names are assigned to the single image ID 3269c37eae33.

  4. Add the 8.4 tag to the registry.redhat.io/ubi8/ubi image using either:

    • The image name:

      $ podman tag registry.redhat.io/ubi8/ubi myubi:8.4
    • The image ID:

      $ podman tag 3269c37eae33 myubi:8.4

      Both commands give you the same result.

  5. List all images:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED       SIZE
    registry.redhat.io/ubi8/ubi          latest  3269c37eae33  2 months ago  208 MB
    localhost/myubi                      latest  3269c37eae33  2 months ago  208 MB
    localhost/myubi                      8.4     3269c37eae33  2 months ago  208 MB

    Notice that the default tag is latest for both images. You can see all the image names are assigned to the single image ID 3269c37eae33.

After tagging the registry.redhat.io/ubi8/ubi image, you have three options to run the container:

  • by ID (3269c37eae33)
  • by name (localhost/myubi:latest)
  • by name (localhost/myubi:8.4)

3.9. Saving and loading images

Use the podman save command to save an image to a container archive. You can restore it later to another container environment or send it to someone else. You can use --format option to specify the archive format. The supported formats are:

  • docker-archive
  • oci-archive
  • oci-dir (directory with oci manifest type)
  • docker-dir (directory with v2s2 manifest type)

The default format is the docker-dir format.

Use the podman load command to load an image from the container image archive into the container storage.

Prerequisites

  • A pulled image is available on the local system.

Procedure

  1. Save the registry.redhat.io/rhel8/rsyslog image as a tarball:

    • In the default docker-dir format:

      $ podman save -o myrsyslog.tar registry.redhat.io/rhel8/rsyslog:latest
    • In the oci-archive format, using the --format option:

      $ podman save -o myrsyslog-oci.tar --format=oci-archive registry.redhat.io/rhel8/rsyslog

      The myrsyslog.tar and myrsyslog-oci.tar archives are stored in your current directory. The next steps are performed with the myrsyslog.tar tarball.

  2. Check the file type of myrsyslog.tar:

    $ file myrsyslog.tar
    myrsyslog.tar: POSIX tar archive
  3. To load the registry.redhat.io/rhel8/rsyslog:latest image from the myrsyslog.tar:

    $ podman load -i myrsyslog.tar
    ...
    Loaded image(s): registry.redhat.io/rhel8/rsyslog:latest

3.10. Redistributing UBI images

Use podman push command to push a UBI image to your own, or a third party, registry and share it with others. You can upgrade or add to that image from UBI yum repositories as you like.

Prerequisites

  • A pulled image is available on the local system.

Procedure

  1. Optional: Add an additional name to the ubi image:

    # podman tag registry.redhat.io/ubi8/ubi registry.example.com:5000/ubi8/ubi
  2. Push the registry.example.com:5000/ubi8/ubi image from your local storage to a registry:

    # podman push registry.example.com:5000/ubi8/ubi
    IMPORTANT
    While there are few restrictions on how you use these images, there are some restrictions about how you can refer to them. For example, you cannot call those images Red Hat certified or Red Hat supported unless you certify it through the Red Hat Partner Connect Program, either with Red Hat Container Certification or Red Hat OpenShift Operator Certification.

3.11. Defining the image signature verification policy

Red Hat delivers signatures for the images in the Red Hat Container Registry. The YAML files in the /etc/containers/registries.d/ directory and the /etc/containers/policy.json file define the signature verification policy when running as root.

The trust policy in the /etc/containers/policy.json file describes a registry scope (registry and or or repository) for the trust.

By default, the container tool reads the policy from the $HOME/.config/containers/policy.json file if it exists. Otherwise, the container tool reads the policy from the /etc/containers/policy.json file.

Trust is defined using three parameters:

  1. The registry or registry/repository name
  2. One or more public GPG keys
  3. A signature server

Red Hat distributes signatures from these URIs:

Procedure

  1. Display the /etc/containers/policy.json file:

    # cat /etc/containers/policy.json
    {
        "default": [
            {
                "type": "insecureAcceptAnything"
            }
        ],
        "transports":
        {
            "docker-daemon":
            {
                "": [{"type":"insecureAcceptAnything"}]
            }
        }
    }
  2. To update an existing trust scope for the registries registry.access.redhat.com and registry.redhat.io, enter:

    # podman image trust set -f /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release registry.access.redhat.com
    # podman image trust set -f /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release registry.redhat.io
  3. To verify trust policy configuration, display the /etc/containers/policy.json file:

           "docker": {
                "registry.access.redhat.com": [
                    {
                        "type": "signedBy",
                        "keyType": "GPGKeys",
                        "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                ],
                "registry.redhat.io": [
                    {
                        "type": "signedBy",
                        "keyType": "GPGKeys",
                        "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"
                    }
                ]
            },

    You can see that sections "registry.access.redhat.com" and "registry.redhat.io" are added.

  4. Create the /etc/containers/registries.d/registry.access.redhat.com.yaml file with the following content to identify the signature store for container images from the registry.access.redhat.com registry:

    docker:
         registry.access.redhat.com:
             sigstore: https://access.redhat.com/webassets/docker/content/sigstore
  5. Create the etc/containers/registries.d/registry.redhat.io.yaml file with the following content:

    docker:
         registry.redhat.io:
             sigstore: https://registry.redhat.io/containers/sigstore
  6. To display the trust configuration, enter:

    # podman image trust show                                                          default                     accept
    registry.access.redhat.com  signedBy                security@redhat.com, security@redhat.com  https://access.redhat.com/webassets/docker/content/sigstore
    registry.redhat.io          signedBy                security@redhat.com, security@redhat.com  https://registry.redhat.io/containers/sigstore
                                insecureAcceptAnything
  7. To reject the default trust policy, type:

    # podman image trust set -t reject default
  8. To verify the trust policy configuration, display the /etc/containers/policy.json file:

    # cat /etc/containers/policy.json
    {
        "default": [
        {
            "type": "reject"
        }
    ...
    }

    You can see that the "default" section has changed from "insecureAcceptAnything" to "reject".

  9. Pull the minimal Red Hat Universal Base Image 8 (ubi8-minimal) image from the registry.access.redhat.com registry:

    # podman --log-level=debug pull registry.access.redhat.com/ubi8-minimal
    ....
    DEBU[0000] Using registries.d directory /etc/containers/registries.d for sigstore configuration
    DEBU[0000]  Using "docker" namespace registry.access.redhat.com
    DEBU[0000]   Using https://access.redhat.com/webassets/docker/content/sigstore
    ...

    You see that the signature storage address access.redhat.com/webassets/docker/content/sigstore matches the address you specified in the /etc/containers/registries.d/registry.access.redhat.com.yaml.

  10. Log in to the registry.redhat.io registry:

    # podman login registry.redhat.io
    Username: username
    Password: ***********
    Login Succeeded!
  11. Pull the support-tools image from the registry.redhat.io registry:

    # podman --log-level=debug pull registry.redhat.io/rhel8/support-tools
    ...
    DEBU[0000] Using registries.d directory /etc/containers/registries.d for sigstore configuration
    DEBU[0000]  Using "docker" namespace registry.redhat.io
    DEBU[0000]   Using https://registry.redhat.io/containers/sigstore
    ...

    You can see that the signature storage address registry.redhat.io/containers/sigstore matches the address you specified in the /etc/containers/registries.d/registry.redhat.io.yaml.

  12. To list all images pulled to your local system, enter:

    # podman images
    REPOSITORY                               TAG     IMAGE ID      CREATED       SIZE
    registry.redhat.io/rhel8/support-tools   latest  5ef2aab09451  13 days ago   254 MB
    registry.access.redhat.com/ubi8-minimal  latest  86c870596572  13 days ago   146 MB

Additional resources

3.12. Removing images

Use the podman rmi command to remove locally stored container images. You can remove an image by its ID or name.

Procedure

  1. List all images on your local system:

    $ podman images
    REPOSITORY                           TAG     IMAGE ID      CREATED      SIZE
    registry.redhat.io/rhel8/rsyslog     latest  4b32d14201de  7 weeks ago  228 MB
    registry.redhat.io/ubi8/ubi          latest  3269c37eae33  7 weeks ago  208 MB
    localhost/myubi                      X.Y     3269c37eae33  7 weeks ago  208 MB
  2. List all containers:

    $ podman ps -a
    CONTAINER ID  IMAGE                                    COMMAND          CREATED        STATUS            PORTS   NAMES
    7ccd6001166e  registry.redhat.io/rhel8/rsyslog:latest  /bin/rsyslog.sh  6 seconds ago  Up 5 seconds ago          mysyslog

    To remove the registry.redhat.io/rhel8/rsyslog image, you have to stop all containers running from this image using the podman stop command. You can stop a container by its ID or name.

  3. Stop the mysyslog container:

    $ podman stop mysyslog
    7ccd6001166e9720c47fbeb077e0afd0bb635e74a1b0ede3fd34d09eaf5a52e9
  4. Remove the registry.redhat.io/rhel8/rsyslog image:

    $ podman rmi registry.redhat.io/rhel8/rsyslog
    • To remove multiple images:

      $ podman rmi registry.redhat.io/rhel8/rsyslog registry.redhat.io/ubi8/ubi
    • To remove all images from your system:

      $ podman rmi -a
    • To remove images that have multiple names (tags) associated with them, add the -f option to remove them:

      $ podman rmi -f 1de7d7b3f531
      1de7d7b3f531...