Since I got in touch with VPS and cloud services, which is probably in 2018, I quickly switch all my personal service to docker and try to dockerize most legacy applications. Both in production (I don’t have any income though) and in different labs. I used to manage these services with docker-compose and I indeed find it handy. However, recently I had read a few posts which made me finally decided to start migrating all my services to podman, which is a newer, fancier container stack.
The reasons why I move from docker to podman is considerably simple: just because the docker company (which is also its maintainer) is quite disappointing.
Why Docker is not your best choice
Docker is a completely new tech stack when it first appeared and soon become a fashion all around the world, however, the product that starts the innovation is not always the one wins. There is a history in China that indicates the legitimation of this theory.
Long in history, there was an emperor called “Sui Yang Di”, who was quite innovative and first introduce official examination in Chinese government officer selection. However, his ruling faded out in 15 years time.
There are a few major drawback of Docker which made me eventually decide to move to podman and get rid of Docker completely.
- Too many fiddling with iptables rules on a system using firewalld. This may not be a problem where a host OS’ only role is to run containers. But there are legit cases where containers may run on a host serving other purposes as well.
- Inconsistency between recommendations and real-life experience. Like “Don’t run more than one process in a single container“. Many “official images end up using Docker as VM.
- Some sort of short-sightedness of the mother company of Docker. e.g. the composing architecture called Docker Swarm ends its life gloomy.
- The upper one also affects the “official” container compose tool – docker-compose, which eagerly announced its affinity to Docker Swarm in its 3.x version. In fact, I had to stick with version 2.4 of docker-compose during almost all of my docker career to utilize some useful resource constraints like cpu_limit.
- Some major critical security issues did not obtain much attention from the maintainers, which made Docker quite risky to use in production and commercial area.
I admit some of these issues are probably background related, and some of these also apply to other container technology, which means switching to podman would not make any goods. However, I suppose at this time (Autumn 2020), it is quite obvious there are significant advantage migrating from Docker to Podman.
The Basis of Migration
Any migration requires planning and testing. I stole a diagram from balagetech, which is pretty much the same architecture as mine, to illustrate the present environment of my services. The following is a simple figure that shows an overview of my overall configuration. What is different is that in my configuration clients are directed directly to the reverse proxy part, which I use HAProxy to act as a gateway.
Although this system worked pretty well, there are some major issues with it.
- All container networks are isolated separately, which create a little overhead and probably consume more iptables resource when in high concurrency scenarios.
- I don’t really want a SQL server or PHP server to have its own IP. Allocating only one port to each of these containers might probably bring down the attack surface when it comes to security.
- Docker makes these networking rules with a lot of iptables tweaks, which is not quite exact;y what I want. Dealing with iptables compatibility is for sure a nightmare.
Plan of Migration
There is a very fundamental difference between Docker and Podman, even in the range of concept. Podman have a concept of “pods“, which is pretty much the same with Kubernetes. Containers within a pod share the same namespace of networking. This feature handles the networking issue I mentioned above well.
I then stole another diagram from balagetech to help explaining the difference.
Pods provide another layer of isolation I really like. This way containers of any pods could only access ports published by other pods and not the containers themselves.
I followed this kind of architecture and write a little script to help me create a pod. There are a few projects that help you convert docker-compose file to Kube-compatible config file, like pods-compose, but I just want to keep it simple.
Here is a bash script I used to create my gitea instance. I already backup my data and moved them to the correcct position before running this.
#!/bin/bash set -e podname="gitea" publish_ip="10.88.0.2" podman pod rm --ignore --force ${podname} podman pod create --name ${podname} --hostname ${podname} --ip ${publish_ip} podman run -d --name gitea-server --expose 3000 --pod ${podname} \ -v /data/gitea-server:/data \ -v /tmp:/tmp \ -v /etc/timezone:/etc/timezone:ro \ -v /etc/localtime:/etc/localtime:ro \ --restart always \ gitea/gitea:1 podman run -d --name gitea-db --expose 3306 --pod ${podname} \ -v /data/gitea-db:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD="xxx" \ -e MYSQL_USER=gitea \ -e MYSQL_PASSWORD=xxx \ -e MYSQL_DATABASE=gitea \ --entrypoint='["docker-entrypoint.sh", "--max_allowed_packet=64M"]' \ --restart always \ mariadb:10.5
There are a few things to bear in mind though. Firstly, this kind of network structure is achieved using CNI which requires ROOT permission, which is probably a major flaw of this structure. Secondly, the parameter –restart=always does not work like Docker. Since Podman does not have any daemon process, it cannot bootstrap your containers without further configuration in systemd. The only usage of this parameter is auto restart the container when it failed.
Then I go straight forward to my HAProxy which currently located directly on the host machine without any containerize and added the bellow backend.
backend gitea mode http option forwardfor server 1 10.88.0.2:3000
Till now, it seems that I have migrated from Docker to Podman.
Excitements with Podman
Thers are a few features in Podman that really excite me. First of all, there is literally no gap between Podman and Kubernetes. The following command let you quickly generate a K8s compatible kube config file that can be directly import to Kubernetes.
podman generate kube <Your Podname>
This command is likely to give you a <Your Podman>.yml which includes all the configuration of your current running pod.
Then you can go forward to use it in K8s or just use it back in Podman.
podman play kube ./my-pod.yaml
This makes maintaining services in Podman as convenient as with docker-compose.
Second, Podman is quite robust compared to docker. As many enthusiasts may mention before, Docker does not perform well in terms of robustness. It might not be obvious enough for you to notice sitting in front of screens reading articles, but is definitely noticeable when you have it in your hands.
Final Thoughts
It seems quite obvious to me that Docker has already lost some of its reputation in the market. Recent news says that Kubernetes plan to drop Docker support of their container engine, which is a significant sign that maybe you have a better choice than Docker.
I haven’t done migrating all my services to Podman yet, and I also need to figure out how to add systemd configuration to auto start my containers, but in my opinion, it is worthy to do such a migration. See you next time.