Red Hat Training

A Red Hat training course is available for RHEL 8

Chapter 18. Running Skopeo, Buildah, and Podman in a container

You can run Skopeo, Buildah, and Podman in a container.

With Skopeo, you can inspect images on a remote registry without having to download the entire image with all its layers. You can also use Skopeo for copying images, signing images, syncing images, and converting images across different formats and layer compressions.

Buildah facilitates building OCI container images. With Buildah, you can create a working container, either from scratch or using an image as a starting point. You can create an image either from a working container or using the instructions in a Containerfile. You can mount and unmount a working container’s root filesystem.

With Podman, you can manage containers and images, volumes mounted into those containers, and pods made from groups of containers. Podman is based on a libpod library for container lifecycle management. The libpod library provides APIs for managing containers, pods, container images, and volumes.

Reasons to run Buildah, Skopeo, and Podman in a container:

  • CI/CD system:

    • Podman and Skopeo: You can run a CI/CD system inside of Kubernetes or use OpenShift to build your container images, and possibly distribute those images across different container registries. To integrate Skopeo into a Kubernetes workflow, you need to run it in a container.
    • Buildah: You want to build OCI/container images within a Kubernetes or OpenShift CI/CD systems that are constantly building images. Previously, people used a Docker socket to connect to the container engine and perform a docker build command. This was the equivalent of giving root access to the system without requiring a password which is not secure. For this reason, Red Hatrecommends using Buildah in a container.
  • Different versions:

    • All: You are running an older operating system on the host but you want to run the latest version of Skopeo, Buildah, or Podman. The solution is to run the container tools in a container. For example, this is useful for running the latest version of the container tools provided in Red Hat Enterprise Linux 8 on a Red Hat Enterprise Linux 7 container host which does not have access to the newest versions natively.
  • HPC environment:

    • All: A common restriction in HPC environments is that non-root users are not allowed to install packages on the host. When you run Skopeo, Buildah, or Podman in a container, you can perform these specific tasks as a non-root user.

18.1. Running Skopeo in a container

You can inspect a remote container image using Skopeo. Running Skopeo in a container means that the container root filesystem is isolated from the host root filesystem. To share or copy files between the host and container, you have to mount files and directories.

Prerequisites

  • The container-tools module is installed.

Procedure

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

    $ podman login registry.redhat.io
    Username: myuser@mycompany.com
    Password: <password>
    Login Succeeded!
  2. Get the registry.redhat.io/rhel8/skopeo container image:

    $ podman pull registry.redhat.io/rhel8/skopeo
  3. Inspect a remote container image registry.access.redhat.com/ubi8/ubi using Skopeo:

    $ podman run --rm registry.redhat.io/rhel8/skopeo \
      skopeo inspect docker://registry.access.redhat.com/ubi8/ubi
    {
        "Name": "registry.access.redhat.com/ubi8/ubi",
        ...
        "Labels": {
            "architecture": "x86_64",
            ...
            "name": "ubi8",
            ...
            "summary": "Provides the latest release of Red Hat Universal Base Image 8.",
            "url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.2-347",
            ...
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Layers": [
        ...
        ],
        "Env": [
            "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
            "container=oci"
        ]
    }

    The --rm option removes the registry.redhat.io/rhel8/skopeo image after the container exits.

Additional resources

18.2. Running Skopeo in a container using credentials

Working with container registries requires an authentication to access and alter data. Skopeo supports various ways to specify credentials.

With this approach you can specify credentials on the command line using the --cred USERNAME[:PASSWORD] option.

Prerequisites

  • The container-tools module is installed.

Procedure

  • Inspect a remote container image using Skopeo against a locked registry:

    $ podman run --rm registry.redhat.io/rhel8/skopeo inspect --creds $USER:$PASSWORD docker://$IMAGE

Additional resources

18.3. Running Skopeo in a container using authfiles

You can use an authentication file (authfile) to specify credentials. The skopeo login command logs into the specific registry and stores the authentication token in the authfile. The advantage of using authfiles is preventing the need to repeatedly enter credentials.

When running on the same host, all container tools such as Skopeo, Buildah, and Podman share the same authfile. When running Skopeo in a container, you have to either share the authfile on the host by volume-mounting the authfile in the container, or you have to reauthenticate within the container.

Prerequisites

  • The container-tools module is installed.

Procedure

  • Inspect a remote container image using Skopeo against a locked registry:

    $ podman run --rm -v $AUTHFILE:/auth.json registry.redhat.io/rhel8/skopeo inspect docker://$IMAGE

    The -v $AUTHFILE:/auth.json option volume-mounts an authfile at /auth.json within the container. Skopeo can now access the authentication tokens in the authfile on the host and get secure access to the registry.

Other Skopeo commands work similarly, for example:

  • Use the skopeo-copy command to specify credentials on the command line for the source and destination image using the --source-creds and --dest-creds options. It also reads the /auth.json authfile.
  • If you want to specify separate authfiles for the source and destination image, use the --source-authfile and --dest-authfile options and volume-mount those authfiles from the host into the container.

Additional resources

18.4. Copying container images to or from the host

Skopeo, Buildah, and Podman share the same local container-image storage. If you want to copy containers to or from the host container storage, you need to mount it into the Skopeo container.

Note

The path to the host container storage differs between root (/var/lib/containers/storage) and non-root users ($HOME/.local/share/containers/storage).

Prerequisites

  • The container-tools module is installed.

Procedure

  1. Copy the registry.access.redhat.com/ubi8/ubi image into your local container storage:

    $ podman run --privileged --rm -v $HOME/.local/share/containers/storage:/var/lib/containers/storage \
    registry.redhat.io/rhel8/skopeo skopeo copy \
    docker://registry.access.redhat.com/ubi8/ubi containers-storage:registry.access.redhat.com/ubi8/ubi
    • The --privileged option disables all security mechanisms. Red Hat recommends only using this option in trusted environments.
    • To avoid disabling security mechanisms, export the images to a tarball or any other path-based image transport and mount them in the Skopeo container:

      • $ podman save --format oci-archive -o oci.tar $IMAGE
      • $ podman run --rm -v oci.tar:/oci.tar registry.redhat.io/rhel8/skopeo copy oci-archive:/oci.tar $DESTINATION
  2. Optional: List images in local storage:

    $ podman images
    REPOSITORY                               TAG     IMAGE ID      CREATED       SIZE
    registry.access.redhat.com/ubi8/ubi      latest  ecbc6f53bba0  8 weeks ago   211 MB

Additional resources

18.5. Running Buildah in a container

The procedure demonstrates how to run Buildah in a container and create a working container based on an image.

Prerequisites

  • The container-tools module is installed.

Procedure

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

    $ podman login registry.redhat.io
    Username: myuser@mycompany.com
    Password: <password>
    Login Succeeded!
  2. Pull and run the registry.redhat.io/rhel8/buildah image:

    # podman run --rm --device /dev/fuse -it \
      registry.redhat.io/rhel8/buildah /bin/bash
    • The --rm option removes the registry.redhat.io/rhel8/buildah image after the container exits.
    • The --device option adds a host device to the container.
    • The sys_chroot - capability to change to a different root directory. It is not included in the default capabilities of a container.
  3. Create a new container using a registry.access.redhat.com/ubi8 image:

    # buildah from registry.access.redhat.com/ubi8
    ...
    ubi8-working-container
  4. Run the ls / command inside the ubi8-working-container container:

    # buildah run --isolation=chroot ubi8-working-container ls /
    bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv
  5. Optional: List all images in a local storage:

    # buildah images
    REPOSITORY                        TAG      IMAGE ID       CREATED       SIZE
    registry.access.redhat.com/ubi8   latest   ecbc6f53bba0   5 weeks ago   211 MB
  6. Optional: List the working containers and their base images:

    # buildah containers
    CONTAINER ID  BUILDER  IMAGE ID     IMAGE NAME                       CONTAINER NAME
    0aaba7192762     *     ecbc6f53bba0 registry.access.redhat.com/ub... ubi8-working-container
  7. Optional: Push the registry.access.redhat.com/ubi8 image to the a local registry located on registry.example.com:

    # buildah push ecbc6f53bba0 registry.example.com:5000/ubi8/ubi

18.6. Privileged and unprivileged Podman containers

By default, Podman containers are unprivileged and cannot, for example, modify parts of the operating system on the host. This is because by default a container is only allowed limited access to devices.

The following list emphasizes important properties of privileged containers. You can run the privileged container using the podman run --privileged <image_name> command.

  • A privileged container is given the same access to devices as the user launching the container.
  • A privileged container disables the security features that isolate the container from the host. Dropped Capabilities, limited devices, read-only mount points, Apparmor/SELinux separation, and Seccomp filters are all disabled.
  • A privileged container cannot have more privileges than the account that launched them.

Additional resources

18.7. Running Podman with extended privileges

If you cannot run your workloads in a rootless environment, you need to run these workloads as a root user. Running a container with extended privileges should be done judiciously, because it disables all security features.

Prerequisites

  • The container-tools module is installed.

Procedure

  • Run the Podman container in the Podman container:

    $ podman run --privileged --name=privileged_podman \
      registry.access.redhat.com//podman podman run ubi8 echo hello
    Resolved "ubi8" as an alias (/etc/containers/registries.conf.d/001-rhel-shortnames.conf)
    Trying to pull registry.access.redhat.com/ubi8:latest...
    ...
    Storing signatures
    hello
  • Run the outer container named privileged_podman based on the registry.access.redhat.com/ubi8/podman image.
  • The --privileged option disables the security features that isolate the container from the host.
  • Run podman run ubi8 echo hello command to create the inner container based on the ubi8 image.
  • Notice that the ubi8 short image name was resolved as an alias. As a result, the registry.access.redhat.com/ubi8:latest image is pulled.

Verification

  • List all containers:

    $ podman ps -a
    CONTAINER ID  IMAGE                            COMMAND               CREATED            STATUS                          PORTS   NAMES
    52537876caf4  registry.access.redhat.com/ubi8/podman               podman run ubi8 e...  30 seconds ago     Exited (0) 13 seconds ago               privileged_podman

Additional resources

18.8. Running Podman with less privileges

You can run two nested Podman containers without the --privileged option. Running the container without the --privileged option is a more secure option.

This can be useful when you want to try out different versions of Podman in the most secure way possible.

Prerequisites

  • The container-tools module is installed.

Procedure

  • Run two nested containers:

    $ podman run --name=unprivileged_podman --security-opt label=disable \
      --user podman --device /dev/fuse \
      registry.access.redhat.com/ubi8/podman \
      podman run ubi8 echo hello
  • Run the outer container named unprivileged_podman based on the registry.access.redhat.com/ubi8/podman image.
  • The --security-opt label=disable option disables SELinux separation on the host Podman. SELinux does not allow containerized processes to mount all of the file systems required to run inside a container.
  • The --user podman option automatically causes the Podman inside the outer container to run within the user namespace.
  • The --device /dev/fuse option uses the fuse-overlayfs package inside the container. This option adds /dev/fuse to the outer container, so that Podman inside the container can use it.
  • Run podman run ubi8 echo hello command to create the inner container based on the ubi8 image.
  • Notice that the ubi8 short image name was resolved as an alias. As a result, the registry.access.redhat.com/ubi8:latest image is pulled.

Verification

  • List all containers:

    $ podman ps -a
    CONTAINER ID  IMAGE                            COMMAND               CREATED            STATUS                          PORTS   NAMES
    a47b26290f43               podman run ubi8 e...  30 seconds ago     Exited (0) 13 seconds ago               unprivileged_podman

18.9. Building a container inside a Podman container

You can run a container in a container using Podman. This example shows how to use Podman to build and run another container from within this container. The container will run "Moon-buggy", a simple text-based game.

Prerequisites

  • The container-tools module is installed.
  • You are logged in to the registry.redhat.io registry:

    # podman login registry.redhat.io

Procedure

  1. Run the container based on registry.redhat.io/rhel8/podman image:

    # podman run --privileged --name podman_container -it \
      registry.redhat.io/rhel8/podman /bin/bash
    • Run the outer container named podman_container based on the registry.redhat.io/rhel8/podman image.
    • The --it option specifies that you want to run an interactive bash shell within a container.
    • The --privileged option disables the security features that isolate the container from the host.
  2. Create a Containerfile inside the podman_container container:

    # vi Containerfile
    FROM registry.access.redhat.com/ubi8/ubi
    RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
    RUN yum -y install moon-buggy && yum clean all
    CMD ["/usr/bin/moon-buggy"]

    The commands in the Containerfile cause the following build command to:

    • Build a container from the registry.access.redhat.com/ubi8/ubi image.
    • Install the epel-release-latest-8.noarch.rpm package.
    • Install the moon-buggy package.
    • Set the container command.
  3. Build a new container image named moon-buggy using the Containerfile:

    # podman build -t moon-buggy .
  4. Optional: List all images:

    # podman images
    REPOSITORY                  TAG      IMAGE ID      CREATED        SIZE
    localhost/moon-buggy  latest  c97c58abb564  13 seconds ago  1.67 GB
    registry.access.redhat.com/ubi8/ubi latest 4199acc83c6a  132seconds ago 213 MB
  5. Run a new container based on a moon-buggy container:

    # podman run -it --name moon moon-buggy
  6. Optional: Tag the moon-buggy image:

    # podman tag moon-buggy registry.example.com/moon-buggy
  7. Optional: Push the moon-buggy image to the registry:

    # podman push registry.example.com/moon-buggy