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: http://crunchtools.com/a-first-look-at-the-podman-2-0-api/
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!
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.
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.
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 “\->\”
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.
I “think” it’s because the /archive verb is not implemented yet (off the top of my head): https://github.com/containers/podman/issues/6050
Also, you can debug with this: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/using-the-container-tools-api_using-the-container-tools-cli#running-podman-api-manually_using-the-container-tools-api
Then, watch the console for errors. If it’s not the archive verb failing, we would love you to file a bug on github: https://github.com/containers/podman/issues/