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
Log in to the registry.redhat.io registry:
$ podman login registry.redhat.io Username: myuser@mycompany.com Password: <password> Login Succeeded!
Get the
registry.redhat.io/rhel8/skopeo
container image:$ podman pull registry.redhat.io/rhel8/skopeo
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 theregistry.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.
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
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
-
-
The
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
Log in to the registry.redhat.io registry:
$ podman login registry.redhat.io Username: myuser@mycompany.com Password: <password> Login Succeeded!
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 theregistry.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.
-
The
Create a new container using a
registry.access.redhat.com/ubi8
image:# buildah from registry.access.redhat.com/ubi8 ... ubi8-working-container
Run the
ls /
command inside theubi8-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
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
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
Optional: Push the
registry.access.redhat.com/ubi8
image to the a local registry located onregistry.example.com
:# buildah push ecbc6f53bba0 registry.example.com:5000/ubi8/ubi
Additional resources
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
- How to use the --privileged flag with container engines
-
podman-run
man page on your system
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 theregistry.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 theubi8
image. -
Notice that the
ubi8
short image name was resolved as an alias. As a result, theregistry.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
- How to use Podman inside of a container
-
podman-run
man page on your system
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 theregistry.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 thefuse-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 theubi8
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
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 theregistry.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.
-
Run the outer container named
Create a
Containerfile
inside thepodman_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.
-
Build a container from the
Build a new container image named
moon-buggy
using theContainerfile
:# podman build -t moon-buggy .
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
Run a new container based on a
moon-buggy
container:# podman run -it --name moon moon-buggy
Optional: Tag the
moon-buggy
image:# podman tag moon-buggy registry.example.com/moon-buggy
Optional: Push the
moon-buggy
image to the registry:# podman push registry.example.com/moon-buggy
Additional resources