Going Dockerless

In my last article back in July 2019 I described deploying a variety of services (wiki, opengrok, jenkins, nginx) as Docker Swarm stacks on a home Linux development server. At the time the server was running Fedora 29 and it was subsequently upgraded in place to Fedora 30. In anticipation of upgrading to Fedora 31 at some point in the future I became aware of Redhat's move away from Docker and cgroupsV1 in favor of cgroupsV2, Podman and Buildah. While installing docker-ce is possible on Fedora 31 with a hack/workaround there is no guarantee of any such workaround in subsequent Fedora releases. With that in mind I spun up a Fedora 31 VM on my home server and began experimenting with Podman and friends.

As a disclaimer, I don't claim to be either a Docker (or Podman) expert; I've figured out enough to be dangerous with Docker over the years and my goal with Podman is to get a minimal set of services running on a home server for my needs matching similar functionality I have now with Docker Swarm on Fedora 30. None of these services is exposed to the internet or intended to serve a large scale developer community.

This article is a bit of a work in progress. The scripts and files I've used to create these services using Podman are here: https://github.com/CJLove/podman-playground. This repo will be updated as additional services are defined and as I learn more.

Background Info

I'll defer to other internet sources as far as fully describing what Podman supports and the advantages over Docker. In a nutshell, Podman eliminates the monolithic docker daemon running as root and enables running "rootless" containers securely as non-root users. Podman can be used to manage individual containers (the 'podman' CLI is largely a drop-in replacement for the 'docker' CLI). It can also be used to manage Pods, which are groups of containers sharing host and network resources (equivalent to Kubernetes Pods).

There is support for Podman to generate a yaml-based pod specification from a running pod which is usable both with Podman (via `podman play <pod.yaml>`) and with Kubernetes. Podman implements a small subset of the Kubernetes stack as far as yaml manifest files go, so it doesn't appear that you can currently easily write a yaml-based pod spec from scratch and then play it.

Elimination of the docker daemon paves the way for more cleanly managing containers using Systemd. Podman can generate Systemd unit files which can then be used to manage single containers or pods. So for my use case of orchestrating handful of services on a private Linux server I was able to go from having Docker Swarm (running as root) managing the lifecycle of Swarm stacks for each service to having Systemd manage the pod and containers for each service, even with those services now running as non-root users.

Server and User Setup

Fedora 31 makes recent versions of Podman and Buildah available (1.8.2 and 1.14.3 respectively at the time of writing this article). Since I'll set up separate user accounts for each service I deploy with Podman (nginx, opengrok, wiki, jenkins) I will need to allocate a block of sub-user ids and sub-group ids for each account. This can be done for existing accounts by editing the '/etc/subuid' and '/etc/subgid' files directly or more conveniently by running 'usermod --add-subuids <range> --add-subgids <range> <user>':

usermod --add-subuids 165536-166535 --add-subgids 165536-166535 nginx
usermod --add-subuids 166536-167535 --add-subgids 166536-167535 opengrok
usermod --add-subuids 167536-168535 --add-subgids 167536-168535 wiki
usermod --add-subuids 168536-169535 --add-subgids 168536-169535 jenkins

Note: for Fedora 31 at least, if creating the account from scratch via 'useradd' these files are updated automatically.

Simple Podman Service: NGINX

As mentioned in my last article I primary run an http server in order to host various local yum repos that are used in building container images. Nginx runs in a container, mounting a volume from the host which holds the repo files into '/usr/share/nginx/html/'. The service will be available on a port.

In the absence of a declarative yaml-based pod specification a bash script can be used to deploy the pod and its container(s) as desired, then generate Systemd unit files and enable them for the nginx user. On reboot the service will be started via Systemd and can then be started/stopped via `systemctl --user start pod-nginx` or `systemctl --user stop pod-nginx`.

[nginx@birch nginx]$ ./nginx.sh 
Validating account nginx...
nginx:231072:65536
nginx:231072:65536
Setting owner/group on /home/nginx/www...
Creating pod...
57a475d9db33e0d815e11c92c6938590c6f3b7ed32ac97f5883886cbab0b49c8
Creating nginx container...
bbe0b072ec560fc256fe1f2e43783c71348b78b62ff1fb7001d431db4ce045b6
Creating /home/nginx/.config/systemd/user...
Generating systemd unit files...
/home/nginx/.config/systemd/user/pod-nginx.service
/home/nginx/.config/systemd/user/container-http.service
    Fixing target in container-http.service...
    Fixing target in pod-nginx.service...
Reloading systemd...
Enabling systemd services...
    Enabling container-http.service...
Created symlink /home/nginx/.config/systemd/user/default.target.wants/container-http.service → /home/nginx/.config/systemd/user/container-http.service.
    Enabling pod-nginx.service...
Created symlink /home/nginx/.config/systemd/user/default.target.wants/pod-nginx.service → /home/nginx/.config/systemd/user/pod-nginx.service.
/home/love/Development/podman/nginx
Nginx service running on port 3004

[nginx@birch nginx]$ podman pod list
POD ID         NAME    STATUS    CREATED          # OF CONTAINERS   INFRA ID
57a475d9db33   nginx   Running   14 seconds ago   2                 62bea1b76333

[nginx@birch ~]$ curl http://birch:3004
Welcome to birch!

 

First Impressions

So far I've only been playing with Podman a few days and I'm still getting my desired services running.

Podman seems like a work in progress at this point. The entire workflow of doing a manual or scripted pod/container deployment then generating yaml or Systemd files from the running pod seems a bit awkward and a departure from Kubernetes or Swarm. There is a companion podman-compose tool that would let you deploy services using Docker Compose files but it is under development as well. It seems like it would be far better to document the subset of Kubernetes pod manifest yaml that Podman supports and then create pod specifications that way since Kubernetes is the defacto standard.

I understand the motivations for Redhat and other distros to move away from Docker, but it seems like the niche served by Docker Swarm and/or Docker Compose isn't cleanly being served (yet).

Podman Resources

To view or add a comment, sign in

More articles by Chris Love

  • Another kind of "Pi day"

    Motivation In order to stay somewhat current with containers and Kubernetes now that my day job is pure…

  • DevOps @ Home

    Note: this is my first time writing an article via LinkedIn Publishing, as I'm just checking out the capabilities of…

Explore content categories