Kubernetes YAML is the universal language for describing desired states in distributed systems, and you can leverage it to manage Podman containers just as effectively as you would with Docker Swarm.

Let’s see what this looks like in practice. Imagine you have a simple web application, say an Nginx server serving static files.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80
      hostPort: 8080

This YAML describes a single Pod named nginx-pod. Inside this Pod, we have one container named nginx-container that uses the nginx:latest image. Crucially, we’re mapping port 80 inside the container to port 8080 on the host.

Now, how do we get Podman to understand and run this? You’ll use podman play kube.

podman play kube nginx.yaml

This single command reads your Kubernetes YAML and translates it into Podman-native objects. It will pull the nginx:latest image if it’s not already present, create the nginx-pod, and start the nginx-container within it. You can then verify it’s running:

podman ps

You should see an nginx-container listed. Accessing http://localhost:8080 in your browser will now show the default Nginx welcome page.

The real power of Kubernetes YAML, however, comes with describing more complex deployments. Consider a multi-tier application where you need multiple replicas of your web server and a separate database.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web-container
        image: nginx:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer # This will be translated to a port forward on the host

This YAML defines two Kubernetes objects: a Deployment and a Service. The Deployment specifies that we want 3 replicas of our web application (labeled with app: web). Podman’s play kube will create 3 identical Pods from the template definition. The Service named web-service defines how to access these web pods. The selector matches pods with the label app: web. The type: LoadBalancer is Podman’s interpretation for creating a host-level port forward. If you were running this on a cloud provider, it would provision an actual load balancer. For Podman, it typically means picking an available host port and forwarding traffic from that port to the service’s port.

To run this multi-file YAML:

podman play kube app.yaml

After running this, podman ps will show three nginx-container instances. You can then access your web application via the host port that Podman assigns to web-service. To find out which port that is, you’d typically inspect the running Podman containers or use podman port web-service.

The podman play kube command is your bridge to the Kubernetes ecosystem. It allows you to define your application’s desired state using industry-standard YAML and have Podman execute it locally or on a Podman machine. This means you can develop and test Kubernetes-native applications without needing a full Kubernetes cluster, making your development workflow significantly more agile. You can also use podman generate kube to inspect the Kubernetes YAML that Podman generates from running containers, allowing you to transition your Podman-managed applications to Kubernetes.

What most people don’t realize is how podman play kube handles different Kubernetes object types. For instance, a Service of type LoadBalancer doesn’t actually provision a cloud load balancer when run with Podman. Instead, Podman dynamically allocates an available port on the host and sets up a port forward from that host port to the targetPort specified in the service. This is a crucial difference from a full Kubernetes environment and impacts how you expose your services externally. You’ll need to use podman port <container_name_or_id> to discover the dynamically assigned host port.

The next step in orchestrating your applications with Podman using Kubernetes YAML is exploring how to manage configurations and secrets.

Want structured learning?

Take the full Podman course →