Avengers of Container World - Episode 1: Podman Hands-On

A B Vijay Kumar
8 min readDec 30, 2020

CRI-O and podman have been widely adopted by most of the modern container platforms. In this blog, I will explore, why everybody is gaga about this new ecosystem of tools/utilities, and share some of my experience, in this series.

I got a lot of feedback, after I published my blog on Containers & evolution of Containers (you can read it here “Evolution of k8s worker nodes — CRI-O”). One of the common questions asked, is how podman is different from docker & how the new ecosystem of podman+buildah+cri-o+skopio different from what we do with docker…so I wanted to do a deep dive on these things, and share some of my experiences with this new ecosystem of container runtime & management tools/utilities (in my blog I referred to them as avengers, with OpenShift as the captain…but in this blog, I will focus more on the avengers minus captain america :-) ).

I am planning to split this series into 2 episodes

Podman

Podman is an OCI (Open Container Initiative) complaint Container Engine. (I had published a blog on CRI-O, where I took a deep dive on Docker architecture and evolution of CRI & OCI, you can read it here.)

Docker is one of the most widely used container runtimes in the world, and no doubt, it transformed the way we build cloud-native applications. Docker provided a very good end to end architecture, for building, deploying, and managing containers.

Docker architecture is based on a daemon, that runs as a service in the background. Docker daemon is responsible to run the commands, push/pull images to/from the registry, manage the containers and images on the local machine.

Docker Architecture

It looks like a very neat architecture.

So what are the shortcomings of this approach??

  • Single point of failure: Docker is based on a typical client/server architecture, docker CLI issues commands to Docker daemon and Docker Daemon, has all the logic to run and manage the images and containers. Docker daemon pretty much ended up as a fat monolith. Docker daemon, controls all the child processes, a failure in docker daemon, crashes all the child processes, including running containers.
  • Root access: All the docker operations are conducted as a root user, this is practically an issue in enterprises, where root access is normally controlled, due to security and compliance issues.

Podman works differently. Podman does not need a daemon, and it has decentralized the functionality. Podman does not need root access and can run with local user privileges, and the best part is the users can only view and manage containers, that they have in their local login.

Podman Architecture

Podman does all that the docker does, and I know of a lot of us, who do an alias of podman with docker, and not even know the difference. Podman not only can run containers but also can run Pods. This is very powerful to run and manage multiple containers in a single pod (especially the side-car containers, which is very critical for ServiceMesh kind of architectures)

Now let's get hands-on. Podman only runs on Linux, the rest of the blog, I will walk through how to run podman. I am going to setup CentOS on VirtualBox/MacOS. I am going to use Vagrant to provision the virtual machines.

Step 1: Prepare your machine

Vagrant is a super powerful tool, that helps provision environments, very quickly with very simple declarative config file. You can read more about vagrant here

$ vagrant init centos/8

This creates a vagrant file with the following content

Vagrant.configure("2") do |config|
config.vm.box = "centos/8"
end

Now let's provision CentOS. This will install download and provision the CentOS VM in the Virtual Box

$ vagrant up

You can check the VM in the VirtualBox.

Now that CentOS is up and running, let's install Podman

Step 2: Install podman

Once Vagrant installs the CentOS, you can log in to the CentOS with Shell with the following command

$ vagrant ssh

Once you execute this command, Vagrant takes care of all the complexity of login credentials and will log you on to the CentOS shell.

Now we can install podman with the following command

Kubic project provides more latest updates to podman, though this is not officially tested by RH. You can find more details about Kubic project

This step is optional!!!

# CentOS 8
sudo dnf -y module disable container-tools
sudo dnf -y install 'dnf-command(copr)'
sudo dnf -y copr enable rhcontainerbot/container-selinux
sudo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_8/devel:kubic:libcontainers:stable.repo
sudo dnf -y install podman
sudo dnf -y update

Once podman is installed, you can test if the installation, with the following commands

[vagrant@localhost ~]$ podman version

[vagrant@localhost ~]$ podman info

[vagrant@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
[vagrant@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Step 3: Pull and run tomcat

Now let's pull tomcat image, before that you can search available images in the registry with the search command
[vagrant@localhost ~]$ podman search tomcat

Before we pull the images, we have to login to the respective registries (refer to the Podman architecture). You can login to various registries.

In this case, I am logging in with my dockerhub.

[vagrant@localhost ~]$ podman login docker.io
Username: abvijaykumar
Password:
Login Succeeded!

Now let's pull the tomcat image

[vagrant@localhost ~]$ podman pull docker.io/library/tomcat
Trying to pull docker.io/library/tomcat...
Getting image source signatures
Copying blob d04be46a31d1 done
Copying blob c0afb8e68e0b done
Copying blob e8a829023b97 done
Copying blob ef072fc32a84 done
Copying blob 6c33745f49b4 done
Copying blob d599c07d28e6 done
Copying blob db6007c69c35 done
Copying blob e4ad4c894bce done
Copying blob 248895fda357 done
Copying blob 277059b4cba2 done
Copying config feba8d001e done
Writing manifest to image destination
Storing signatures
feba8d001e3f56558228ed129ce9b381936393c093129593d270140e5717d7d0

Let’s check if the image is pulled properly

[vagrant@localhost ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/tomcat latest feba8d001e3f 11 days ago 661 MB

Let’s run the container

[vagrant@localhost ~]$ podman run -d -t -p 8080:8080 tomcat
3902a2446fb84aa3be4b3054c90a85e33d23c56821e91eda64dcf1c62b74cdb0
  • -d option so that it can run in detached mode
  • -t allocates a pseudo tty for the process
  • what we see as the output is the containerid

Lets now check if the container is running

[vagrant@localhost ~]$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3902a2446fb8 docker.io/library/tomcat:latest catalina.sh run 3 minutes ago Up 3 minutes ago 0.0.0.0:8080->8080/tcp nifty_maxwell

There you go, finally we got the tomcat running, let's check if we can access it

[vagrant@localhost ~]$ curl localhost:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.41</h3></body></html>

We can see, that we are getting a 404 from tomcat server,

Step 4: Access the container from outside the host machine

Remember this CentOS is running inside VirtualBox, by default VirtualBox image would have been set as a NAT Networking setup, we will have to shut down the VirtualBox CentOS Image, and then change the network settings before we can access the tomcat server.

Let's exit the ssh and shutdown the image

[vagrant@localhost ~]$ exit
logout
Connection to 127.0.0.1 closed.
➜ centos vagrant halt
==> default: Attempting graceful shutdown of VM...
==> default: Forcing shutdown of VM...

Modify the vagrant file to configure for public network. we need to add the following configuration in the vagrant file.

config.vm.network "public_network"

Here is how the vagrant file looks like now

Vagrant.configure("2") do |config|
config.vm.box = "centos/8"
config.vm.network "public_network"
end

Now, let's start the image & check what is the IP we got.

As you notice, now the CentOS virtual machine, has a network IP that can be accessed in the local network.

if we now start the tomcat container and access it from macOS using http://192.168.1.139:8080, we should be able to access the tomcat server

(of course you will see a 404 page, as we have not deployed any web application yet, which we will be doing in the next episode).

That's it for the first episode…In the next episode, we will walk thru building our own images using buildah…and also explore skopeo…it's going to be fun.

wear mask, stay away from corona, take care, ttyl :-)

References

👋 Join FAUN today and receive similar stories each week in your inbox! Get your weekly dose of the must-read tech stories, news, and tutorials.

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--

A B Vijay Kumar

IBM Fellow, Master Inventor, Mobile, RPi & Cloud Architect & Full-Stack Programmer