The capability to group containers into logical units known as pods is the primary architectural feature that distinguishes Podman from Docker. In the Podman ecosystem, a pod is defined as a group of one or more containers that share the same network, PID, and IPC namespaces. This shared environment allows containers within a pod to communicate with one another via localhost, significantly reducing networking complexity for microservices that require high-speed, low-latency interaction. The ability to list and inspect these pods is critical for system administrators and DevOps engineers to maintain visibility over the orchestration of these shared namespaces.
Managing these entities requires a deep understanding of the podman pod ps and podman pod ls commands. These tools provide a window into the operational state of the system, allowing users to track pod IDs, names, statuses, and the specific containers attached to each pod. Because Podman aims for compatibility with Kubernetes, the pod concept is central to its design, enabling a seamless transition from a local development environment to a production Kubernetes cluster.
Pod Identification and Visibility
The fundamental method for viewing pods on a system is through the use of listing commands. Podman provides several aliases for this functionality, ensuring that users coming from different background paradigms can find intuitive commands.
The following commands are used to list all pods available on the system:
podman pod lspodman pod pspodman list(as an alias)
When a user executes these commands, the system retrieves a comprehensive list of pods. The default output is structured to provide a snapshot of the current environment, including the pod ID, the human-readable name, the current status, the time of creation, the infra ID, and the total number of containers contained within that pod.
The impact of this visibility is that it allows the operator to identify exactly which services are grouped together and verify if the intended architecture is deployed. For example, if a web-pod is intended to contain both a frontend and a backend container, the "number of containers" column provides an immediate validation of this configuration.
Pod Status Definitions
The status of a pod is not a simple binary of "running" or "stopped." Instead, Podman utilizes a nuanced state machine to describe the exact condition of the pod and its constituent containers. This ensures that the user knows whether a pod is failing, idling, or actively processing requests.
The following table details the status values returned by the listing commands:
| Status | Description |
|---|---|
| Created | No containers running nor stopped |
| Running | At least one container is running |
| Stopped | At least one container stopped and none running |
| Exited | All containers stopped in pod |
| Dead | Error retrieving state |
The "Created" status indicates a pod that has been initialized but has no active workloads. The "Running" status is the most common for active production environments, signifying that at least one container within the pod is operational. The distinction between "Stopped" and "Exited" is crucial; "Stopped" implies a partial failure or a controlled pause of some containers, while "Exited" indicates a complete cessation of all container activities within that specific pod. Finally, the "Dead" status is a critical error indicator, suggesting that the Podman engine cannot retrieve the state of the pod, which may necessitate a restart of the container engine or an investigation into the underlying storage driver.
Advanced Filtering and Selection
To manage large-scale deployments, simply listing all pods is insufficient. Podman provides a robust filtering system via the --filter or -f flag, allowing users to isolate specific pods based on defined criteria. This capability is essential for automation and scripting, where a user may only want to act upon pods that meet a certain condition.
If multiple filters are required, the --filter option must be passed multiple times. For example, a user might combine a label filter with a time-based filter using podman pod ls --filter label=test --filter until=10m.
The following filters are supported by the system:
- ctr-ids: Filter by container ID within the pod. This supports prefix matching by default and accepts regular expressions.
- ctr-names: Filter by the name of a container within the pod.
- ctr-number: Filter by the specific number of containers associated with the pod.
- ctr-status: Filter by the status of a container within the pod.
- id: Filter by the pod ID, using prefix matching or regex.
- label: Filter by container labels. This also supports negative filtering using
label!=[...]to exclude specific labels. - name: Filter by the pod name.
- network: Filter by the name or the full ID of the network.
The real-world impact of these filters is the ability to perform targeted operations. An administrator can quickly identify all pods that contain exactly two containers using podman pod ps --sort id --filter ctr-number=2, or they can isolate only the pods that are currently in a running state using podman pod ls --filter status=running.
Customizing Output and Formatting
For users who need to integrate Podman into larger automation pipelines or custom dashboards, the default table output is often too verbose. Podman allows for extreme customization of the output via the --format flag, utilizing Go templates or JSON output.
Go Template Formatting
Go templates allow users to extract only the specific fields they need. This reduces the noise in the terminal and makes the output easier to parse for humans.
To show only the pod names and their current status:
podman pod ls --format "{{.Name}}\t{{.Status}}"To show the pod name, the number of containers, and the creation time:
podman pod ls --format "table {{.Name}}\t{{.NumberOfContainers}}\t{{.Created}}"To list the ID, container names, and cgroups:
podman pod ps --format "{{.ID}} {{.ContainerNames}} {{.Cgroup}}"
JSON and Programmatic Output
For programmatic parsing, the --format json option is the gold standard. This allows the output to be piped into tools like jq for complex data manipulation.
To get the pod list as JSON:
podman pod ls --format jsonTo extract only the names of the pods using
jq:
podman pod ls --format json | jq '.[].Name'
Additionally, the -q (quiet) flag is provided to return only the numeric pod IDs. This is specifically designed for use in shell loops. For example, a user can iterate through all pods to inspect their names using the following loop:
bash
for pod_id in $(podman pod ls -q); do
echo "Pod: $(podman pod inspect "$pod_id" --format '{{.Name}}')"
done
Detailed Container Inspection within Pods
While the basic listing command shows the number of containers, users often need to see the actual identities and statuses of those containers without having to run a separate podman ps command. Podman provides specific flags to expand the pod list to include container-level details.
The following flags are used to expand the information provided by podman pod ps:
--ctr-ids: Displays the container UUIDs associated with the pod.--ctr-names: Displays the names of the containers within the pod.--ctr-status: Displays the current status of the containers.
To avoid the truncation of long IDs, which is common in standard terminal output, the --no-trunc flag can be combined with these options. This ensures that the full UUID is displayed, which is necessary when copying IDs into other configuration files or scripts.
Example of listing pods with full container IDs:
podman pod ps --no-trunc --ctr-ids
Pod Lifecycle and Operations
Understanding how to list pods is only useful if the operator knows how to create and manage the entities they are listing. Pods in Podman can be handled through a variety of lifecycle commands.
Creating Pods
A pod can be created as an empty shell or as a containerized unit.
Creating an empty pod:
podman pod create
An empty pod consists of a single infra container. The purpose of this infra container is to keep the pod alive and maintain the associated namespaces (network, PID, IPC) so that subsequent containers added to the pod can share them.Creating a pod with specific networking:
podman pod create --name mypod -p 8080:80
This command creates a pod named "mypod" and maps host port 8080 to container port 80.
Adding Containers to Pods
Containers can be integrated into pods either at the time of creation or after the pod already exists.
Adding a container to an existing pod:
podman run [options] --pod [pod-name-or-id] [image]
Example for adding an Alpine Linux container to a pod with ID e06ed089b454:
podman run --pod e06ed089b454 alpineCreating a pod and a container simultaneously:
Podman allows the use of a singlepodman runcommand to create a new pod and add a container to it in one operation.
Management Commands
Beyond listing, the following commands are essential for the management of pods:
- Starting pods:
podman pod start <pod>(Starts one or more stopped pods) - Stopping pods:
podman pod stop <pod>(Stops one or more running pods) - Restarting pods:
podman pod restart <pod>(Restarts one or more pods) - Removing pods:
podman pod rm <pod>(Removes one or more pods) - Inspecting pods:
podman pod inspect <pod>(Displays detailed JSON information on a pod) - Process monitoring:
podman pod top <pod>(Displays the running processes of containers in a pod)
Kubernetes Integration
One of the most powerful aspects of Podman's pod management is its alignment with Kubernetes. Podman allows users to move between a local environment and a Kubernetes cluster by generating and consuming YAML manifests.
Generating Manifests
To export a pod's configuration into a format that Kubernetes can understand, the podman generate kube command is used.
- Example of exporting a pod as a Kubernetes manifest:
podman generate kube mypod > mypod.yaml
This process converts the local Podman pod state, including the container images and network settings, into a standard YAML file.
Deploying from Manifests
Conversely, a user can take a Kubernetes YAML file and deploy it locally using the podman play kube command.
- Example of creating a pod from a Kubernetes manifest:
podman play kube mypod.yaml
This ensures that the environment used for local testing is identical to the one that will be deployed in a production Kubernetes cluster, eliminating the "it works on my machine" problem.
Comparison of Container and Pod Listing
It is important to distinguish between podman ps (which lists containers) and podman pod ps (which lists pods). While they share a similar syntax, they operate at different levels of the hierarchy.
The following table compares the options available for both listing commands:
| Feature | podman ps (Containers) | podman pod ps (Pods) |
|---|---|---|
| Basic List | -a (all), --last, --latest |
Default lists all pods |
| Filtering | -f, --filter |
--filter, -f |
| Formatting | --format (Go template/JSON) |
--format (Go template/JSON) |
| Special Detail | --size, --ns |
--ctr-ids, --ctr-names, --ctr-status |
| Pod Relation | -p, --pod (shows pod association) |
N/A (The entity is the pod) |
| Sorting | --sort (command, size, etc.) |
--sort (id, etc.) |
The -p or --pod flag in podman ps is particularly useful because it allows the user to see which pod a specific container belongs to, effectively providing the inverse view of podman pod ps.
Analysis of Podman's Pod Architecture
The implementation of pods in Podman represents a shift toward a more organized, service-oriented approach to containerization. By sharing namespaces, Podman eliminates the need for complex virtual networks when containers need to communicate. For instance, when an application is split into a frontend and a backend, they can communicate via localhost as if they were processes on the same host, rather than requiring separate IP addresses and DNS entries.
The inclusion of the infra container is a critical technical detail. Because a pod is essentially a collection of shared namespaces, there must be a persistent entity to maintain those namespaces even if the application containers within the pod are restarted or crash. The infra container serves as the "anchor" for the pod.
From a DevOps perspective, the ability to generate Kubernetes YAML files directly from a running Podman pod allows for an iterative development cycle. An engineer can manually adjust a pod's configuration using podman run or podman pod create, verify the behavior using podman pod ps, and then commit the final configuration to a version-controlled YAML file. This tight integration reduces the friction between development and operations, accelerating the deployment pipeline for microservices.
The flexibility provided by the --filter and --format flags ensures that Podman scales from a simple tool used by a "noob" to a powerful engine for "tech geeks" and system architects. Whether it is a simple check of a single pod's status or a complex automated script managing hundreds of pods across a distributed system, the listing and inspection tools provide the necessary granularity for absolute control over the container environment.