Podman Kubernetes YAML Integration

The intersection of Podman and Kubernetes represents a strategic shift in how containerized workloads are developed and deployed. Podman, a daemonless, OCI-compliant container engine, is engineered to build, manage, and run containers securely on Linux systems. By operating without a background service, Podman significantly reduces the system attack surface and improves overall stability compared to traditional daemon-based engines. While Podman is an open-source tool for the management of OCI containers and images, it does not possess its own container orchestration management tool, such as Docker Swarm. In advanced deployment scenarios where high availability, scalability, and fault tolerance are required across numerous hosts, Podman users transition to orchestrators like Kubernetes.

Kubernetes manifests specify the desired state of a cluster, and Podman leverages this standard to bridge the gap between local development and production environments. The integration allows developers to use Kubernetes YAML files to define their infrastructure locally, testing and iterating within a Podman environment before promoting those same manifests to a production Kubernetes cluster. This symbiotic relationship is facilitated by the podman kube subcommand, which enables the recreation of containers, pods, and volumes based on structured YAML input. This ensures that the transition from a local machine to a cloud-scale cluster is seamless, as the manifest remains the single source of truth.

The Podman Kube Subcommand Architecture

The podman kube command is the central mechanism for managing containers, pods, and volumes using structured input files. It is explicitly designed to simplify the movement of containerized workloads between a Podman local environment and a Kubernetes cluster. It is critical to note that Podman is not intended to be a direct replication of the kubectl CLI. Once workloads are successfully deployed to a Kubernetes cluster from Podman, the standard kubectl tool must be used for all subsequent cluster management.

The architecture of the podman kube subcommand is divided into four primary operations, each serving a distinct phase of the container lifecycle.

Command Description
apply Applies Kubernetes YAML based on containers, pods, or volumes to a Kubernetes cluster.
down Removes containers and pods based on the provided Kubernetes YAML.
generate Generates Kubernetes YAML based on existing containers, pods, or volumes.
play Creates containers, pods, and volumes based on Kubernetes YAML.

The play command is particularly vital for local development, as it automatically starts the containers defined in the YAML file. This allows a developer to simulate a Kubernetes pod environment on a single machine without the overhead of a full cluster. Conversely, the down command provides a clean method for tearing down these resources, ensuring that local environments do not become cluttered with orphaned containers.

Local Development and Iteration Workflow

The Podman workflow is designed to mirror the Kubernetes workflow to reduce the cognitive load on developers. In a typical Podman development cycle, the process follows a recursive path of definition and testing.

The workflow begins with the creation of a Kubernetes YAML manifest. The developer then executes podman play kube, which translates the YAML instructions into local containers and pods. This creates a local environment where the developer can test the application's behavior and iterate on the configuration. If modifications are required, the developer updates the YAML and repeats the process. Once the local environment is stable, the podman generate kube command is used to export the final state of the pod into a deployment-ready manifest. This manifest is then passed to kubectl apply for deployment into a production Kubernetes cluster.

The comparison between Podman and kubectl workflows highlights the efficiency of local testing.

  • Podman Workflow: Write Kubernetes YAML -> podman play kube -> Local Containers -> Test & Iterate -> podman generate kube.
  • Kubernetes Workflow: Kubernetes YAML -> kubectl apply -> Cluster Pods -> Production.

The output of podman generate kube allows for the same manifest to be used across multiple targets, including standard Kubernetes clusters, OpenShift environments, or other Podman instances.

Operational Command Comparison

To effectively navigate the transition from Podman to Kubernetes, users must understand the mapping between Podman commands and their kubectl equivalents. While the underlying goal is the same—managing containerized resources—the execution differs based on whether the target is a local engine or a remote cluster.

Operation Podman kubectl
Apply YAML podman play kube file.yaml kubectl apply -f file.yaml
Delete resources podman play kube --down file.yaml kubectl delete -f file.yaml
Generate YAML podman generate kube pod-name kubectl get pod -o yaml
List pods podman pod ps kubectl get pods
View logs podman logs container-name kubectl logs pod-name
Exec into container podman exec -it container sh kubectl exec -it pod -- sh

This operational mapping demonstrates that while Podman provides the tools to simulate Kubernetes, it maintains its own identity as a container engine. For example, podman play kube is used to instantiate the YAML locally, whereas kubectl apply interacts with the Kubernetes API server to schedule pods across a distributed set of nodes.

Exporting Pods to Kubernetes YAML

The process of exporting a local Podman pod to a Kubernetes YAML manifest allows developers to capture the exact state of their working environment. This is especially useful when complex pods are created interactively.

To export a pod, the user first creates the pod structure and adds the necessary containers. For example, a developer might create a pod named export-demo with specific port mappings.

podman pod create --name export-demo --publish 8080:80 --publish 6379:6379

Once the structure exists, individual containers are added to the pod.

podman run -d --pod export-demo --name export-demo-nginx nginx:alpine
podman run -d --pod export-demo --name export-demo-redis redis:alpine

To transform this live environment into a portable YAML file, the podman generate kube command is executed.

podman generate kube export-demo > export-demo.yaml

The resulting YAML file includes all containers, volumes, and configurations, ensuring that the environment can be replicated identically in a production cluster. The generated structure includes metadata such as annotations (e.g., io.podman.annotations.autoremove), creation timestamps, and labels. This comprehensive export prevents the loss of configuration details that might occur if the manifest were written manually from memory.

Managing Persistent Data with Podman Kube

Podman supports the integration of persistent volumes within its Kubernetes YAML workflows, allowing data to persist even when pods are torn down and recreated. This is achieved by defining volume mounts and persistent volume claims (PVC) within the YAML structure.

In a typical persistent volume configuration, the YAML specifies a mountPath (e.g., /data) and references a persistentVolumeClaim with a specific claimName (e.g., data-pvc).

podman play kube persistent.yaml

After execution, the volume can be verified using the volume listing command.

podman volume ls

The expected output displays the driver and volume name, such as local data-pvc. Further inspection is possible via podman volume inspect data-pvc.

The real-world impact of this capability is seen during the tear-down and recreation cycle. When a user executes podman play kube --down persistent.yaml, the pod is removed, but the data persists in the volume. Upon running podman play kube persistent.yaml again, the data is immediately available. This can be verified by executing a command to read a file within the volume.

podman exec data-pod cat /data/log.txt

This mechanism ensures that stateful applications can be developed locally with the same persistence logic that will be applied in the production Kubernetes environment.

Podman Inside Kubernetes: Execution Strategies

Running Podman inside a Kubernetes pod is a sophisticated use case that allows for container-in-container operations. This can be achieved through several strategies, depending on the required privileges and the desired interaction with the host system.

Rootless Podman in Kubernetes

Rootless Podman allows containers to run without root privileges, which is a significant security advantage. In a Kubernetes environment, this involves mounting local user directories into the pod.

For instance, a configuration might use a hostPath to map the host's container storage to the pod.

mountPath: /home/podman/.local/share/containers
name: podman-local
volumes:
- name: podman-local
hostPath:
path: /home/umohnani/.local/share/containers

When executing into such a pod, the user identity is verified as a non-privileged user.

kubectl exec -it no-priv -- sh
id

The output shows uid=1000(podman) gid=1000(podman) groups=1000(podman). In this environment, Podman can pull images and run containers.

podman run ubi8 echo hello

Furthermore, rootless Podman can build images using the --isolation chroot flag.

podman build --isolation chroot -t myimage -f containerfile .

This allows developers to create and test images entirely within a non-privileged Kubernetes pod, limiting the impact of any potential security breach.

Rootful Podman Without Privileged Flag

In some scenarios, Podman requires root privileges inside the container but should not be run with the full --privileged flag for security reasons. To achieve this, specific Linux capabilities must be granted to the container.

The required capabilities include:
- CAP_SYS_ADMIN: Necessary for the Podman instance running as root to mount required file systems.
- CAP_MKNOD: Required to create device nodes in /dev.
- CAP_SYS_CHROOT and CAP_SETFCAP: Part of the default capability list in Podman; without these, Podman commands will fail as the engine cannot add the capabilities it needs during execution.

These are defined in the Kubernetes YAML under the securityContext section.

securityContext:
capabilities:
add:
- "SYS_ADMIN"
- "MKNOD"
- "SYS_CHROOT"
- "SETFCAP"

This configuration allows podman run ubi8 echo hello to execute successfully while still maintaining a layer of restriction compared to a fully privileged container.

Podman-Remote and Socket Leaking

A highly advanced integration involves "leaking" the Podman socket from the host into a Kubernetes pod. This allows the Podman client inside the pod to communicate with the Podman engine running on the host machine.

To set up this environment, the Podman socket must be enabled on the host, and SELinux must be disabled. The Kubernetes YAML defines a volume mount for the socket.

volumeMounts:
- mountPath: /var/run/podman
name: podman-sock
volumes:
- name: podman-sock
hostPath:
path: /var/run/podman

When executing inside this pod, the user utilizes the --remote flag to direct commands to the host's engine.

podman --remote run ubi8 echo hello

This strategy allows the pod to act as a management console for the host's containers. It also extends to image building.

podman --remote build -t myimage -f Containerfile .

By using the host's resources, the Podman-remote approach avoids the overhead of running a full container engine inside the pod, while still providing the flexibility of a containerized management interface.

Technical Analysis of Podman and Kubernetes Integration

The integration of Podman with Kubernetes creates a powerful continuum for container lifecycle management. The primary value proposition is the elimination of the "it works on my machine" problem. By using the same YAML manifests across local Podman environments and production Kubernetes clusters, the risk of configuration drift is minimized.

The ability to generate YAML from active pods (podman generate kube) creates a feedback loop where the developer can experiment with the container's runtime configuration and then codify that configuration into a manifest. This is far more efficient than manually writing YAML files and repeatedly applying them to a cluster to see if the results match the desired state.

From a security perspective, the support for rootless Podman and the precise allocation of Linux capabilities (CAP_SYS_ADMIN, CAP_MKNOD, etc.) allows organizations to implement the principle of least privilege even when performing complex tasks like container-in-container builds. The option to use a remote socket further decouples the management tools from the execution engine, providing a flexible architecture for DevOps pipelines.

The trade-off in this ecosystem is the operational distinction between Podman and kubectl. Podman's kube commands are focused on the transition and local simulation, not on the ongoing management of a live cluster. This distinction is critical for practitioners to understand to avoid confusion when moving from a local testing phase to a production phase.

Sources

  1. podman-kube - Play containers, pods or volumes based on a structured input file
  2. podman-inside-kubernetes
  3. podman-kubernetes-yaml
  4. how-to-integrate-podman-with-kubernetes

Related Posts