If you are familiar with containers, you must have heard of Docker and maybe Kubernetes (the orchestrator). Here comes Podman which brings innovation to container tools in the spirit of Unix commands which do “one thing” well. If you have used Docker before, Podman offers a similar experience as the Docker CLI.
How Docker CLI Works
The Docker CLI is a client/server operation and the Docker CLI communicates with the Docker engine when it wants to create or manipulate the operations of a container. This client/server architecture can lead into problems in production because one, you have to start the Docker daemon before Docker CLI comes alive. The Docker CLI then sends an API call to the Docker Engine to launch Open Container Initiative (OCI) Container runtime, in most cases runc, to start the container (projectatomic.io). What this means is that the launched containers are child processes of the Docker Engine.
What is Podman?
What then is Podman? Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System.
Docker vs Podman
The major difference between Docker and Podman is that there is no daemon in Podman. It uses container runtimes as well for example runc but the launched containers are direct descendants of the podman process. This kind of architecture has its advantages such as the following:
- Applied Cgroups or security constraints still control the container: Whatever cgroup constraints you apply on the podman command, the containers launched will receive those same constraints directly.
- Advanced features of systemd can be utilized using this model: This can be done by placing podman into a systemd unit file and hence achieving more.
What about Libpod?
You must have seen Libpod on the title of this guide. Libpod just provides a library for applications looking to use the Container Pod concept, popularized by Kubernetes. It allows other tools to manage pods/container (projectatomic.io). Podman is the default CLI tool for using this library. There are other two important Libraries that make Podman possible:
- containers/storage – This library allows one to use copy-on-write (COW) file systems, required to run containers.
- containers/image – This library that allows one to download and install OCI Based Container Images from containers registries like Docker.io, Quay, and Artifactory, as well as many others (projectatomic.io).
These two libraries were built from the ground up to support multiple independent processes to interact with the libraries at the same time. A good example is that you can be running a full Kubernetes environment with CRI-O, building container images using Buildah and managing your containers and pods with Podman at the same time (projectatomic.io). This brings the spirit of Unix commands which do “one thing” well. Such a combination of tools is not possible with Docker.
Install Podman on CentOS / Fedora / Ubuntu
Let us look at how Podman is installed in CentOS and Fedora
If you are on Ubuntu, please check:
For Debian, use:
Managing Container Images
Pull image using Podman:
podman pull ubuntu
podman pull centos
podman pull centos:8
To list downloaded images, use the command:
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/ubuntu latest 3556258649b2 2 weeks ago 66.6 MB
docker.io/library/alpine latest b7b28af77ffe 3 weeks ago 5.85 MB
docker.io/library/debian latest 00bf7fdd8baf 4 weeks ago 119 MB
docker.io/library/centos latest 9f38484d220f 4 months ago 209 MB
To remove an image, use -rmi option followed by image name/ID:
$ podman rmi 00bf7fdd8baf
00bf7fdd8baf2ba6f0918e1f48415b2a4a1a616806e7cf32527a749dd2ce4b2c
$ podman rmi docker.io/library/ubuntu
3556258649b2ef23a41812be17377d32f568ed9f45150a26466d2ea26d926c32
Tagging images
You can add your custom name to images to make it more intuitive and to remind you what the image does in your set up
# podman tag 7698f282e524 webserver
# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/ubuntu latest 7698f282e524 4 weeks ago 72.3 MB
localhost/webserver latest 7698f282e524 4 weeks ago 72.3 MB
Running Containers with Podman
To run a simple container using Ubuntu image which prints a message, use:
# podman run --rm ubuntu /bin/echo "Computing for Geeks"
Computing for Geeks
To run a container in background (detached mode), use -d option.
podman run -dt -p 8080:8080/tcp -e HTTPD_VAR_RUN=/var/run/httpd -e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \
-e HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \
-e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \
registry.fedoraproject.org/f29/httpd /usr/bin/run-httpd
This will return the container ID:
Trying to pull registry.fedoraproject.org/f29/httpd...Getting image source signatures
Copying blob d77ff9f653ce done
Copying blob aaf5ad2e1aa3 done
Copying blob 7692efc5f81c done
Copying config 25c76f9dcd done
Writing manifest to image destination
Storing signatures
d2cdf0efb0ddc6e2ae52a5a0bdadababa6ee6cc2e1e49145c92a0474b089b664
Listing running containers
The Podman ps command is used to list creating and running containers.
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d2cdf0efb0dd registry.fedoraproject.org/f29/httpd:latest container-entrypo... 4 minutes ago Up 4 minutes ago 0.0.0.0:8080->8080/tcp cranky_borg
# To include stopped / exited containers, use:
$ podman ps --all
Run a shell in a container
To access a container shell, use the options -it:
# podman run -it ubuntu bash
root@d273c12899cd:/#
root@d273c12899cd:/# apt update
Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:3 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [717 kB]
Get:4 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:5 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [535 kB]
Get:6 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Searching in Podman
$ podman search httpd
Inspecting Containers
This displays the low-level information on containers and images identified by name or ID.
# podman inspect 024a277cc474
[
{
"ID": "024a277cc4748ab48539c9ddea15d98c0e0bccc307506c44fbce12ec6c568dfc",
"Created": "2019-06-14T10:58:07.764967058-04:00",
"Path": "/bin/bash",
"Args": [
"/bin/bash"
See more on usage:
$ podman inspect --help
Removing containers
First list all running containers:
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
024a277cc474 docker.io/library/ubuntu:latest /bin/bash 3 minutes ago Exited (0) 3 minutes ago laughing_blackwell
cf4267fb7a2b docker.io/library/ubuntu:latest bash 4 hours ago Exited (0) 2 hours ago nostalgic_archimedes
b800dd64ba11 docker.io/library/ubuntu:latest /bin/bash 4 hours ago Exited (0) 4 hours ago optimistic_hypatia
To delete a single running container use the podman rm command followed by the container id:
$ podman rm 024a277cc474
024a277cc4748ab48539c9ddea15d98c0e0bccc307506c44fbce12ec6c568dfc
To remove all containers, both running and stopped use:
podman rm $(podman ps -a -q)
Viewing the container’s logs
You can view the container’s logs with Podman as well:
podman logs --latest
You can also specify container ID:
podman ps
podman logs d2cdf0efb0dd
To follow the logs output in real-time, use:
podman logs -f ContainerID
podman logs --follow=true --since 10m ContainerID
Show only last 10 lines in logs:
podman logs --tail 10 d2cdf0efb0dd
Viewing the container’s pids
Use podman top to view container’s pids.
podman top <container_id>
Example:
$ podman top d2cdf0efb0dd
USER PID PPID %CPU ELAPSED TTY TIME COMMAND
default 1 0 0.000 29m22.496484247s pts/0 0s httpd -D FOREGROUND
default 22 1 0.000 29m21.496767511s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat
default 23 1 0.000 29m21.496866314s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat
default 24 1 0.000 29m21.497020539s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat
default 25 1 0.000 29m21.497127237s pts/0 0s /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat
default 26 1 0.000 29m21.49723933s pts/0 0s httpd -D FOREGROUND
default 27 1 0.000 29m21.497361006s pts/0 0s httpd -D FOREGROUND
default 28 1 0.000 29m21.497459891s pts/0 0s httpd -D FOREGROUND
default 29 1 0.000 29m21.497552695s pts/0 0s httpd -D FOREGROUND
Checkpointing the container
Checkpointing a container stops the container while writing the state of all processes in the container to disk. This capability requires CRIU 3.11 or later installed on the system. See CRIU installation.
podman container checkpoint <container_id>
Example:
$ podman container checkpoint d2cdf0efb0dd
A container can later be restored and continue running at exactly the same point in time as the checkpoint.
podman container restore <container_id>
Migrate the container
First checkpoint the container on the source system:
podman container checkpoint <container_id> -e /tmp/checkpoint.tar.gz
Copy it to the destination server:
scp /tmp/checkpoint.tar.gz <destination_system>:/tmp
On the destination system, restore container:
podman container restore -i /tmp/checkpoint.tar.gz
Manage container pods with Podman
Podman pods are similar to the Kubernetes concept of Pods
Most of the interaction with pods is exposed through the podman pod commands:
$ podman pod --help
NAME:
podman pod - Manage container pods.
Pods are a group of one or more containers sharing the same network, pid and ipc namespaces.
USAGE:
podman pod command [command options] [arguments...]
COMMANDS:
create Create a new empty pod
exists Check if a pod exists in local storage
inspect displays a pod configuration
kill Send the specified signal or SIGKILL to containers in pod
pause Pause one or more pods
ps, ls, list List pods
restart Restart one or more pods
rm Remove one or more pods
start Start one or more pods
stats Display percentage of CPU, memory, network I/O, block I/O and PIDs for containers in one or more pods
stop Stop one or more pods
top Display the running processes of containers in a pod
unpause Unpause one or more pods
OPTIONS:
--help, -h show help
The example below will create a pod called web
$ podman pod create --name web
0f565b11e9cb3736dc15b46f3361305e351ce556818e342a9fdf799ea4edf7ca
This creates a pod without the extra attributes available on:
$ podman pod create --help
Confirm pod creation
$ podman pod list
POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID
0f565b11e9cb web Running About a minute ago 1 44cca777d12f
By default, the created pod will have a container called infra. The infra container is in sleep mode and its purpose is to hold the namespaces associated with the pod to allow podman to connect other containers to the pod:
$ podman ps -a --pod
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD
44cca777d12f k8s.gcr.io/pause:3.1 23 minutes ago Up 23 minutes ago 0f565b11e9cb-infra 0f565b11e9cb
Now that the pod is created, we can add a container to it:
podman run -dt --pod web alpine:latest top
You should now see the pod has two containers
$ podman ps -a --pod
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES POD
36ccace2d653 docker.io/library/alpine:latest top About a minute ago Up About a minute ago zen_hugle 0f565b11e9cb
44cca777d12f k8s.gcr.io/pause:3.1 28 minutes ago Up 28 minutes ago 0f565b11e9cb-infra 0f565b11e9cb
This how you’ll create a container and expose a port – root required for port binding.
sudo podman pod create -p 8080:80 --name web1
sudo podman run -dt --pod web1 -p 8080 nginx:latest
Note that you need to publish as many port as will be used during the pod creation. This can’t be changed after the creation.
Conclusion
Podman shows a lot of promise in the future of Containerization. In fact, Red Hat did not just remove the Docker container engine from OpenShift. It also removed the Docker container engine, along with the docker
command, from Red Hat Enterprise Linux 8 entirely. Thank you for reading through.
Reference :
- Red Hat Documentation
- Podman Documentation
Also Read: