Podman is the daemonless container engine, which can manage rootfull and rootless containers. Since it is already named Podman, there should be pods. This article explains, how you can handle pods in Podman and how this enhances your container deployments.
The pod concept was introduced by the Kubernetes project. First, a pod itself has no application in it, but it can manage all the resources like a container does. A pod basically wraps containers, storage resources, and an ephemeral network identity together as a single unit.
First, let's review a single container, where everything is combined. This is how Docker handles containers.
# Start a container $ podman container run -d --name container01 \ -p 8080:80 docker.io/library/httpd # List running containers $ podman container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a1ef7cbaf330 docker.io/library/httpd httpd-foreground 9 seconds ago Up 10 seconds ago 0.0.0.0:8080->80/tcp container01 # Remove the container $ podman container rm -f container01
A container in a pod
To have an application in a pod, you need to provide a container in it.
Creating a pod is easy and attaching a container to it needs only one additional parameter.
# Create a pod $ podman pod create -p 8080:80 --name pod01 # List pods $ podman pod ls POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS c5d90af17283 pod01 Created 8 seconds ago 9b720f35d62d 1 # Start a container in the pod $ podman container run -d --name container01 \ --pod pod01 docker.io/library/httpd # List containers $ podman container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9b720f35d62d k8s.gcr.io/pause:3.2 27 seconds ago Up 6 seconds ago 0.0.0.0:8080->80/tcp c5d90af17283-infra 111e6c72b994 docker.io/library/httpd httpd-foreground 5 seconds ago Up 6 seconds ago 0.0.0.0:8080->80/tcp container01
As you can see, there is another container running, based on the
image. Port bindings, cgroup values, and kernel namespaces are assigned to this infra container. Once the pod is created these attributes are assigned to the infra container and cannot be changed.
Multiple container in a pod
You can also have multiple containers, in the same pod. The containers will share some resources and therefore are behaving as "one service".
Let's add two more containers to the pod.
# Start a second container in the pod $ podman container run -d --name container02 --pod pod01 docker.io/library/mariadb # Start a third container in the pod $ podman container run -d --name container03 --pod pod01 docker.io/library/redis # List pods $ podman pod ls POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS c5d90af17283 pod01 Degraded About a minute ago 9b720f35d62d 4 # List containers $ podman container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9b720f35d62d k8s.gcr.io/pause:3.2 2 minutes ago Up About a minute ago 0.0.0.0:8080->80/tcp c5d90af17283-infra 111e6c72b994 docker.io/library/httpd httpd-foreground About a minute ago Up About a minute ago 0.0.0.0:8080->80/tcp container01 01713e4871f3 docker.io/library/redis:latest redis-server 22 seconds ago Up 22 seconds ago 0.0.0.0:8080->80/tcp container03
Cool, now we have a pod with 3 containers in it. But why is this useful? Well let's see.
Using pods can be very useful when sharing resources across containers.
Often one needs containers to communicate with each other. A web server should be able to communicate with a Redis server or a database for example (fortunately our example above is exactly about this). With 3 containers in the same pod, all the services are working, as if they are the same machine, and you can use "localhost:PORT" to communicate.
The web server is published and reachable via 8080/TCP from outside the host, but the database and Redis server are not. But, the web server can use them via "localhost:3306" and "localhost:6379" without publishing them explicitly or fiddling with IP addresses.
This is also very useful for sidecar containers, that collect metrics, logs, etc. and push them to a central instance.
Well, there are some limitations, that you need to be aware of.
First, you cannot add additional published ports to the already created pods. In case you need to add more ports, you need to re-create the pod, and its containers.
Furthermore, you need to be aware, that this behavior may lead to security issues. The PostgreSQL container image for example sees all traffic from 127.0.0.1 as "secure" traffic. Since all containers in the same pod are "the same machine", this may have impacts to your security concepts.
Lastly, you need to be aware, that you cannot start multiple containers with the same exposed port in a Pod. For example starting two containers based on docker.io/library/httpd is not possible.
As always, there is more to it. The below links will provide additional insights and scenarios, that may be helpful.
Podman pods can be very handy, if you want to bundle different containers into one service. Restarting all containers can be done with a single command and all containers in the same pod are sharing the same network namespace. Therefore, one can reach each container from another one via localhost:PORT.