3 Working With Images, Containers, and Pods

Podman can be used to run containers and to obtain the images that are used to create a container in the same way that you would use Oracle Container Runtime for Docker. The following information describes how you can pull container images from registries into the local image storage; how you can manage container images on local storage; how you can run containers based on these images; and how you can manage the containers that you have created on the host system.

In many ways, Podman can be used as a drop-in replacement for Oracle Container Runtime for Docker. Podman can use images that comply with the Open Container Initiative (OCI) specification and can run containers based on these images. Most Podman commands map directly to the command equivalents that are available in the Docker CLI.

A key difference between Podman and Docker is that while the Docker Engine runs as a service on the host and all actions are performed by the service, Podman runs as a standalone runtime so that each operation is independent. This difference is important, as it changes the security model around working with images and containers.

Because Podman operations aren't dependent on a service daemon running as a particular user on the system, Podman provides more isolation than Docker. This means that you can either run Podman as a standard user or as the root user.

Podman respects user namespaces. This means that several users on a single host can all run their own containers and local image stores without any concern that there could be a conflict. Because containers running within a user's namespace are limited to the permissions available to the user on the host system, Podman is considered to provide more security than Docker.

Some key differences exist when you run Podman as a standard user, instead of running Podman as the root user. These differences are based on the permissions available to these different user types. For example, networking functionality is more limited when running Podman as a standard user and most networking is achieved solely using port mapping and port forwarding, when in this mode. This doesn't suggest that running Podman as the root user is preferred, but some limitations might apply when working as a standard user. To some degree, many issues that arise for a standard user can be mitigated by running groups of containers within a pod. For more information about networking and Podman, see Configuring Networking for Podman. For more information about pods, see Managing Pods.

In general, the instructions provided here apply similarly regardless of whether Podman runs as a standard user or as the root user.

Running Commands With Podman

You can review a list of the commands available for the installed version of Podman by using the podman -h command. For example, that list might contain the following commands:

attach

Attach to the shell of a running container

auto-update

Automatically update containers with automatic updating enabled

build

Build an image from a Containerfile

commit

Create an image based on an edited container

container

Manager existing containers

cp

Copy files and folders between the container and host file system

create

Create a container without starting it

diff

View changes on the container's file system

events

Show Podman event logs for the running container

exec

Run a process in a specified container that's already running

export

Export a container's file system and contents to a compressed archive

generate

Generate systemd unit files and pod YAML files

healthcheck

Run a healthcheck on an existing container

history

Review the history of a specified image

image

Manages existing images

images

Lists images present on the host system

import

Import a compressed archive to create a container file system

info

Show system information for Podman

init

Initialize one or more containers

inspect

Display the existing configuration values for a container or image

kill

Stop running containers with a predefined signal

load

Load an image from a container archive file

login

Log in to a container registry

logout

Log out of a container registry

logs

Review logs for a container

manifest

Create and edit manifest lists and image indexes

mount

Mount a running container's root file system

network

Manage networks that are accessible to containers

pause

Suspend all the processes in one or more containers

play

Start a Pod

pod

Create and manage pods

port

List network port mappings for a container

ps

List containers

pull

Pull an image from a container registry

push

Push an image to a container registry

restart

Restart one or more containers

rm

Remove one or more containers

rmi

Remove one or more images from local storage on the host system

run

Run a single command in a new container

save

Save an image to a compressed archive

search

Search a container registry for an image

start

Start one or more containers

stats

Display a real time stream of container resource usage statistics

stop

Stop one or more containers

system

Manage Podman configuration settings

tag

Add another name to an image in local storage on the host system

top

Display the running processes for a container

unmount

Unmount a running container's root file system

unpause

Resume all processes for one or more containers

unshare

Run a command as a specified user

untag

Remove a secondary name from an image in local storage on the host system

version

Show version information for Podman

volume

Manage container storage volumes

wait

Block processes on one or more containers until a specified condition is fulfilled

Each of the listed commands is linked to a manual page that follows the podman-command(1) pattern. For example, to retrieve information about the attach command, see the podman-attach(1) manual page. For a full list of all the documentation available for Podman, see the podman(1) manual page.

Working With Container Images

A container image is a read-only template that's used to generate a container. The image contains all the requirements for a service or application to run. Images can be limited in scope, for example, to host a single service such as a web server application. Or, images can be extensive enough to include a basic OS environment, such as a minimal Oracle Linux release.

Images can be tagged to enable you to identify different versions of the same image. Often an image might include a default tag of latest so that Podman users can easily identify the most recent version of the image. Note that Oracle Linux images don't use the latest tag. See Oracle Linux Container Image Tagging Conventions for more information.

Images are often hosted on container registries that can be accessed over HTTP/S by Podman instances to obtain particular image versions. Registries are described in more detail in Using Container Registries.

Sometimes, you might want to change an existing image or create custom images, which can be done by using the Buildah utility. See Building Images With Buildah for more information.

You can search the configured registries for an image by using the podman search command:

podman search oraclelinux

For more information about how to configure container registries for use with Podman, see Using Container Registries

Pulling Images From a Registry

When you have found an image, download a copy of it by using the podman pull command. When pulling an image, specify the image reference as follows:

podman pull registry.host/repository/imagename:tag
  • The registry.host is the resolvable hostname of the registry where the image is hosted. Although the registry host is often required, if the registry is already listed within the podman configuration you don't need to specify this value.

  • The repository is optional and depends on how images are stored and on the registry.

  • The imagename is required to specify which image to download.

  • The tag represents a version of the image and should always be specified. Many tools default to using the latest tag if no tag is specified but this can lead to errors and is now considered bad practice. See Oracle Linux Container Image Tagging Conventions for more information on tags and why the latest tag is unreliable.

The following example shows how to pull a slim Oracle Linux 7 image from the Oracle Container Registry:

podman pull container-registry.oracle.com/os/oraclelinux:7-slim
Trying to pull container-registry.oracle.com/os/oraclelinux:7-slim...
Getting image source signatures
Copying blob 50ab38810635 done
Copying config d788eca028 done
Writing manifest to image destination
Storing signatures
d788eca028a0f49b6bc70b251c8535b16ee5bd94e0ab375ca8f3a923e6ce4281

Because the Oracle Container Registry is configured for Podman by default, this command could equally be specified as follows:

podman pull os/oraclelinux:7-slim

Shortcuts to registries and repositories for some commonly used image names are stored in /etc/containers/registries.conf.d/000-shortnames.conf. These shortcuts enable you to easily pull an image without needing to know the registry or repository to search, for example:

podman pull oraclelinux:7-slim

The image is downloaded into the local container image store. This storage is described in more detail in Configuring Storage for Podman.

Inspecting an Image

After the download has completed, you can check the default configuration settings and metadata for a container image by running the following command:

podman inspect container-registry.oracle.com/os/oraclelinux:7-slim
[
     {
          "Id": "6a34bf5396690a3c0ea1d6914f32fae9860bca03c68e7253cfd6d5d11551e2d2",
          "Digest": "sha256:e63584e0060861cd5301a9fc924b087f32ba28c380126b32ed4874d52bf02051",
          "RepoTags": [
               "container-registry.oracle.com/os/oraclelinux:7-slim"
          ],
          "RepoDigests": [
               "container-registry.oracle.com/os/oraclelinux@sha256:d7ae060ba190...690de5aa442b8ff8ce46d53895",
               "container-registry.oracle.com/os/oraclelinux@sha256:e63584e00608...32ba226b32ed4874d52bf02051"
          ],
          "Parent": "",
          "Comment": "",
          "Created": "2022-08-24T19:35:43.028869456Z",
          "Config": {
               "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
               ],
               "Cmd": [
                    "/bin/bash"
               ]
          },
          "Version": "20.10.12",
          "Author": "",
          "Architecture": "amd64",
          "Os": "linux",
          "Size": 139573259,
          "VirtualSize": 139573259,
          "GraphDriver": {
               "Name": "overlay",
               "Data": {
                    "UpperDir": "/home/opc/.local/share/containers/storage/overlay/bcf2a1ad6472a891de95b...5fb/diff",
                    "WorkDir": "/home/opc/.local/share/containers/storage/overlay/bcf2a1ad6472a891de95b5...5fb/work"
               }
          },
          "RootFS": {
               "Type": "layers",
               "Layers": [
                    "sha256:bcf2a1ad6472a891de95b5132d013c064a07ec9995cb61b0cc0f8d4a4ea855fb"
               ]
          },
          "Labels": null,
          "Annotations": {},
          "ManifestType": "application/vnd.docker.distribution.manifest.v2+json",
          "User": "",
          "History": [
               {
                    "created": "2022-08-24T19:35:42.419825447Z",
                    "created_by": "/bin/sh -c #(nop) ADD file:adf7ebc1d65494dba22f4f...d6e9964f936343e6d in / "
               },
               {
                    "created": "2022-08-24T19:35:43.028869456Z",
                    "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/bash\"]",
                    "empty_layer": true
               }
          ],
          "NamesHistory": [
               "container-registry.oracle.com/os/oraclelinux:7-slim"
          ]
     }
]

Listing Available Images

To list all the locally stored container images that have already been downloaded, type:

podman images
REPOSITORY                                    TAG         IMAGE ID      CREATED     SIZE
container-registry.oracle.com/os/oraclelinux  8-slim      0393d9bbfe64  5 days ago  105 MB
container-registry.oracle.com/os/oraclelinux  7-slim      6a34bf539669  7 days ago  140 MB

Deleting an Image

To delete a locally stored container image that have already been downloaded, use the podman rmi command.

podman rmi oraclelinux:7-slim
Untagged: container-registry.oracle.com/os/oraclelinux:7-slim

Note:

You can't delete an image if it's in use by a container, even if the container isn't running. You must remove all the containers that depend on the image before you can remove the image itself.

Managing Containers

Containers are running instances of images. Each container uses an image as its starting point and then loads into run time by using the parameters that are provided when it's created or run.

Containers share namespaces and can access shared port mappings to communicate with each other and with the host system. Podman introduces the concept of pods to the runtime environment. You can use pods to further isolate a group of containers, thereby making it easier to manage a set of services that work together to provision a logical application. See Managing Pods for more information.

Creating Containers

You can create a container from an existing image using the podman create command.

podman create -d --name oracle oraclelinux:7-slim

If the image doesn't already exist on the local system, Podman searches the remote registries for a matching image and pulls the image automatically.

You can specify other options when creating a container, such as whether it belongs to a particular pod or whether it uses a particular network or port mapping. Run podman help create to see more information. Options are extensive and can be used to apply a wide range of runtime functionality to any container.

Running Containers

You run a single command in a container that's provisioned and destroy in a single step by using the podman run command with the --rm flag, for example:

podman run --rm oraclelinux:7-slim cat /etc/oracle-release
Oracle Linux Server release 7.9

You can also create a container and connect to it in a single step by using the -it flag. The -i flag makes the container interactive and -t connects the local terminal to the container. This flag combination is commonly used in conjunction when running a specified shell as part of the podman run command.

podman run --name=oracleshell -it oraclelinux:7-slim /bin/bash
[root@dcbe94cd0301 /]#

The container stops as soon as you disconnect by typing exit. To restart the container and connect to it again, run the podmand start command:

podman start -ai oracleshell

You can also create Podman containers that continue to run as a background daemon by including the -d flag in the command, for example:

podman run -d --name=oracledaemon oraclelinux:7-slim /bin/bash -c 'yum install -y httpd && httpd -Dforeground'

If you run a container that doesn't already exist, it's created automatically. If the image that the container uses isn't available locally, Podman searches the remote registries for a matching image and pulls the image automatically.

Note:

If a container runs a shell as the primary process (PID 1) and you intend to detach it, run it with the --stop-signal=SIGHUP command option so that the shell is stopped cleanly when you stop the container. For example:

podman run --stop-signal SIGHUP --name myol9 oraclelinux:9

Many shells ignore the default SIGTERM signal when stopping a container. If the correct stop-signal isn't used, the container might return the following error when the container is stopped:

WARN[0010] StopSignal SIGTERM failed to stop container myol9 in 10 seconds, resorting to SIGKILL

Enabling FIPS Mode in Containers

To run containers in FIPS mode, you must first enable FIPS mode on the Oracle Linux host system.

For more information about Oracle Linux 8 releases that have FIPS validated cryptographic modules available for installation, see Oracle Linux 8: Enhancing System Security. For more information about FIPS on Oracle Linux 9, see Oracle Linux 9: Installing and Configuring FIPS Mode.

Note:

Oracle provides FIPS compliant container images by using the slim-fips tag. Container images tagged as FIPS compliant include compliant cryptographic package versions and initial image setup required for container FIPS mode. If you use these images you don't need to perform any extra steps to configure a container for FIPS mode. See The slim tag for more information.

For Oracle Linux 7 Containers:

To enable FIPS mode in an Oracle Linux 7 container, install the dracut-fips package or mount /etc/system-fips from the host. For more information about mounting host files and directories inside a Podman container, see Setting Up Container Mounts.

For Oracle Linux 8 and Oracle Linux 9 Containers:

If you have enabled FIPS mode on an Oracle Linux 8 or Oracle Linux 9 host, then Podman runs Oracle Linux 8 or Oracle Linux 9 containers in FIPS mode automatically.

Listing and Monitoring Containers

You can list all the running Podman containers by using the podman ps command. Use the -a flag to also display the stopped and paused containers:

podman ps -a
CONTAINER ID  IMAGE                                                COMMAND               CREATED         STATUS                     PORTS  NAMES
3a430d30612d  container-registry.oracle.com/os/oraclelinux:7-slim  /bin/bash -c yum...   20 seconds ago  Up 19 seconds ago                 oracledaemon
dcbe94cd0301  container-registry.oracle.com/os/oraclelinux:7-slim  /bin/bash             58 seconds ago  Exited (0) 29 seconds ago         oracleshell
726d97e9bfbd  container-registry.oracle.com/os/oraclelinux:7-slim  top                   3 days ago      Created                           oracle

To review the logs generated by a container that has already performed actions, use the podman logs command.

podman logs oracledaemon

In the sample command, oracledaemon can be either the container's ID or name.

To review the hardware resource usage statistics for any running container, use the podman stats command.

podman stats oracledaemon
ID             NAME           CPU %   MEM USAGE / LIMIT   MEM %   NET IO              BLOCK IO   PIDS
c4e296d0c78e   oracledaemon   4.25%   33.33MB / 29.22GB   0.11%   2.412kB / 1.536kB   -- / --    3

Pausing and Resuming Containers

If you need to temporarily halt the operation of a container without destroying its workload, you can use the podman pause command and specify the container name or ID.

podman pause oracledaemon

Running the previous command freezes all the running processes inside a container, in their current state:

When you're ready for the container to resume where it was halted, you can instruct the container to continue with its previous operation from that point by using the podman unpause command, for example:

podman unpause oracledaemon

Stopping and Removing Containers

To stop containers by specifying the name or container ID with the podman stop command:

podman stop oracledaemon

If you need to temporarily take the server down for maintenance, you can stop every running container that hasn't already been paused by appending the -a flag to the podman stop command:

podman stop -a

Specify the container name or ID with the podman rm command to delete a specified container:

podman rm oracle

Managing Pods

Podman introduces the concept of the pod within the context of a container runtime. This concept is borrowed from Kubernetes and isn't available in Oracle Container Runtime for Docker.

A pod is a collection of containers that are grouped together into a single namespace so that they can share resources, such as local networking to communicate with each other and interact. A pod can be used to group a set of services that you need to deploy a complete application.

In many ways a pod behaves similar to a virtual host on which the services within each container are run. This means that each container can access the services on each other container as if they were running on the same host. Running containers in this way can remove a lot of complexity around networking and can make it easier to limit public exposure of ports that are only intended for use by services within the application itself.

Finally, by running containers within pods, it's easier to set up and tear down entire application environments using atomic operations. By using pods, you can create service wrappers to automatically start a set of containers for an application at boot. See Working With Podman Services for more information.

Creating and Managing Pods

The concept of pods is derived from Kubernetes pods. Podman pods are the smallest compute units that you can create and deploy in a Kubernetes environment. These pods include an infra container so that Podman can connect with all the containers within the pod. Podman can manage the containers in the pod, such as stopping containers, without interfering with the operation of the pod itself.

Create a pod with the podman pod create command. Add the --name parameter to give the pod a human-readable identifier.

podman pod create --name oraclepod

You can also set the --hostname option if services within the pod need to use a particular hostname when connecting to each other.

Pods can also be created automatically when a container is run for the first time. See Using Containers Within a Pod for more information.

List all the available and running pods by using the podman pod ps or podman pod list command.

podman pod list

Remove the pod by using the rm command.

podman pod rm oraclepod

Note that you can only remove a pod when all the containers within the pod have been removed, except for the infrastructure container. By default, an infrastructure container is created for each pod, so a pod normally contains at least one container which can only be removed by removing the pod itself. You can see which containers are within the pod by using the podman pod inspect command.

Using Containers Within a Pod

To attach containers to a pod, use the --pod flag when you run the container.

podman run -d --pod oraclepod nginx:alpine
podman run --pod oraclepod -it --rm oraclelinux:7-slim curl http://localhost:80

In the previous example, a container using the nginx image is run and connected to the pod named oraclepod. A second container, using the oraclelinux image is started and connected to the same pod. The curl command is run in the second container to access the web service running on localhost on port 80. The containers are both running as standard user but can use a reserved port within the pod without any port mapping required. Furthermore, the containers can both use the localhost network namespace and can access each other as if they were running on the same host. This example provides an illustration of how pods can make it easier for services running within different containers to access each other and work together without any requirement for complex networking.

If a pod doesn't already exist, you can create it directly by using the podman run command with the --pod option and prepending the new: option to the human-readable name that you have chosen as the pod name:

podman run -d --pod new:oraclepod nginx:alpine

Review all the containers on a host with the pod to which the containers are attached by including the --pod or -p flag with the podman ps -a command.

podman ps -ap

You can start and stop containers as usual without affecting the entire pod; however, you can also use the podman pod start and podman pod stop commands to start and stop every container that exists within the same pod simultaneously, for example:

podman pod stop oraclepod
podman pod start oraclepod

To check the current status of a pod, use the podman pod ps command:

podman pod ps