A First Look at The Podman 2.0 API

A First Look at The Podman 2.0 API

Most days, I don’t have any good ideas. I only have bad ideas. But, I’ve become pretty good at stack ranking my bad ideas into good, better, and best. In this article, I’m going to run through a bunch of the best bad ideas that I had using the new Podman 2.0 REST API.

I’ve been talking with the team for months as they developed the new, REST based Podman 2.0 API. This new API is designed to have two sets of methods. One set of methods are available at the root endpoint and compatible with the Docker API. The other set of methods are available at the /libpod path. The idea is to have something like this:

Docker Compatible: /v1.24/containers/foobar/images
Podman Compatible: /v1.0/libpod/containers/images

OK, so there’s a Docker compatible API, but how do we access it? Podman hates daemons right? It should be said that Podman has no emotional reaction to daemons one way or the other. But, it does have a special connection to a particular daemon that is pretty much mandatory on every modern Linux distribution. That daemon is called systemd. And, systemd has this lesser known feature called socket activation.

Socket activation is kinda like the old xinetd stuff that us old folks used back in the day. The idea was that a single daemon on the system could multiplex to the different binaries that needed to handle the requests. Nowadays, systemd has this feature built in, so why add another daemon? You shouldn’t, just let systemd do it. It looks something like this:

docker -> /var/run/docker.sock -> systemd -> podman -> runc -> Linux kernel -> new process

Pretty cool. So far these sound like good ideas, let’s get to some bad ideas.

A Good Bad Idea

For our first, and not greatest, bad idea, we are going to use Fedora Rawhide to test the latest Podman (you could also compile it yourself using these instructions). We’ll use systemd to fire up socket activation, and then we’re going to use the docker client to do some crazy stuff. It’s ridiculously easy, just follow these commands:

Install podman and docker:

yum install -y podman moby

Now, you’ll have a system that has podman and docker installed. Now, you just need to configure systemd to fire up podman when it receives a connection on the socket. Run the following:

systemctl enable --now podman.socket

Now, you have systemd listening on this socket:

/var/run/podman/podman.sock

Test the socket by using the podman-remote command which is already configured to talk to this socket (:

podman-remote info

Configure Docker to connect to this socket:

export DOCKER_HOST=unix:///var/run/podman/podman.sock

Finally, let’s test it:

docker info

There’s some really interesting information in the output of this command. Notice the Server Version is 2.0 because we are playing with podman 2.0. Also, notice that podman is using crun to fire up containers, and there’s no systemd version listed:

Server Version: 2.0.0-dev
...
Default Runtime: crun
…
containerd version:

A Better Bad Idea

Alright, our good bad idea should be whetting your pallet. Now, let’s try a better bad idea!

systemctl disable --now podman.socket

Configure the unit file

cat /usr/lib/systemd/system/podman.socket
[Unit]
Description=Podman API Socket
Documentation=man:podman-api(1)

[Socket]
#ListenStream=%t/podman/podman.sock
ListenStream=/run/docker.sock
SocketMode=0660

[Install]
WantedBy=sockets.target

Restart the systemd:

systemctl daemon-reload
systemctl start podman.socket

Start a container with docker:

docker run -it ubi8 bash

Look at it in another terminal with podman:

podman ps

Output:

CONTAINER ID  IMAGE   COMMAND  CREATED        STATUS            PORTS   NAMES
5a5840d7aae7  ubi8    bash     8 seconds ago  Up 7 seconds ago          vigorous_shannon

Notice that that UUID matches. That’s an even better bad idea, using docker and podman is fun.

The Best Bad Idea

To be fair, the people I work with are well aware of my best bad ideas. I probably have a bit of notoriety for my comical use of the good, better, best bad idea breakdown. So far, we have configured docker to talk to podman, tested it, and fired up a container as root. Now, we’re going to go to an even better bad idea – we’re going to fire up a container as a regular user, also known as rootless.

We’re going to create a local, rootless service and socket. Systemd will automatically start when you log in and try to use the socket. Then, the docker client will be able to communicate with the podman API to create and monitor containers. Let’s begin.

Create a rootless socket for podman:

vim .config/systemd/user/podman.socket

Input:

[Unit]
Description=Podman API Socket
Documentation=man:podman-api(1)

[Socket]
ListenStream=/home/fatherlinux/docker.sock
SocketMode=0660

[Install]
WantedBy=sockets.target

Create a rootless service for podman:

vim .config/systemd/user/podman.service

Input:

[Unit]
Description=Podman API Service
Requires=podman.socket
After=podman.socket
Documentation=man:podman-api(1)
StartLimitIntervalSec=0

[Service]
Type=oneshot
Environment=REGISTRIES_CONFIG_PATH=/etc/containers/registries.conf
ExecStart=/usr/bin/podman system service unix:///home/fatherlinux/docker.sock
TimeoutStopSec=30
KillMode=process

[Install]
WantedBy=multi-user.target
Also=podman.socket

Make sure the unit files are loaded by systemd, and start the service:

systemctl --user daemon-reload
systemctl --user enable --now podman.socket

Configure docker to talk to the rootless socket:

export DOCKER_HOST=unix:///home/fatherlinux/docker.sock

Fire up a container with docker:

docker run -it ubi8 bash

Look at it running with podman:

podman ps

 

Output:

CONTAINER ID  IMAGE  COMMAND  CREATED                 STATUS  PORTS  NAMES
e691025046f5  ubi8   bash     Less than a second ago  Up             sleepy_noether

Now, let’s take a quick look with ps:

pstree -u

Output:

├─systemd(fatherlinux)─┬─(sd-pam)
│ ├─conmon─┬─bash
│ │ └─{conmon}
│ ├─dbus-broker-lau───dbus-broker
│ ├─2*[fuse-overlayfs]
│ └─podman─┬─podman───7*[{podman}]
│ └─4*[{podman}]

 

Conclusion

I’ve had a lot of bad ideas, but I really think these might have been some of the most fun ones. I’ve shown you how this new podman API will unlock your ability to more smoothly move from Docker to Podman. If you have automation, scripting or other pieces of software, this new API should help ease the transition.

If you’ve been inspired by these bad ideas, please share your bad ideas below!

Originally published at: https://crunchtools.com/a-first-look-at-the-podman-2-0-api/

8 comments on “A First Look at The Podman 2.0 API

  1. Hey. Nice article. Just you might want to check the third code block which seems to not escape certain characters. I’m reading “->” and that doesn’t seem like the correct sequence of characters to input through a shell.

    Besides that thanks for sharing this awesome info about the new Podman!

    1. Yeah, there is something wacky with the way it’s displaying it. I’m trying to figure it out now. Thanks for pointing it out.

    2. I “think” I fixed 🙂 I had copied/pasted it in from the document I used to edit the article, and for some reason it converted the arrows.

  2. It seems it’s being better rendered in the comments than in the code box.

    I guess it’s supposed to read “->” but the box shows “\->\”

  3. Quick test and “docker image ls” failed.

    $ docker pull centos
    Using default tag: latest
    0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566: pulling image () from docker.io/library/centos:latest
    docker.io/library/centos:latest
    $ podman image ls
    REPOSITORY TAG IMAGE ID CREATED SIZE
    docker.io/library/centos latest 0d120b6ccaa8 3 months ago 222 MB
    $ docker image ls
    json: cannot unmarshal string into Go struct field ImageSummary.Created of type int64

    My environment

    $ cat /etc/redhat-release
    CentOS Linux release 8.2.2004 (Core)
    $ rpm -q podman
    podman-2.0.5-5.module_el8.3.0+512+b3b58dca.x86_64
    $ rpm -q docker-ce-cli
    docker-ce-cli-19.03.13-3.el8.x86_64

    And systemd services (podman.service & podman.socket) are configured in –user scope (best bad idea) – as suggested in the article.

Leave a Reply

Your email address will not be published. Required fields are marked *