Why we chose immutable application containers for our Cloud Native PostgreSQL and BDR products
Cloud Native PostgreSQL and Cloud Native BDR are the two Kubernetes operators written by 2ndQuadrant entirely from scratch in the Go language and relying exclusively on the Kubernetes API.
The reason behind this choice stands on an important 3-word concept: Immutable Application Containers.
Our operators for PostgreSQL and BDR are currently private products available only under Production Support services. Cloud Native BDR is based on Cloud Native PostgreSQL. Each of them consists of a Kubernetes manifest that can be downloaded from the 2ndQuadrant Portal. The manifest is just a YAML file.
Yes, we have adopted the Kubernetes’ declarative configuration approach to deploy our software, instead of an imperative one. Our DevOps mindset urges us to define a desired status, not a list of steps or changes to be executed in sequence.
As anticipated, another important aspect to consider is that at 2ndQuadrant we build immutable application containers, with a minimal operating system to produce the smallest and lightest image possible. Container image builds are directly integrated in our Continuous Delivery Pipeline from commit phase to publishing on our private Docker registry.
You might be asking yourself: “Gabriele, you mentioned immutable application containers. What are they?”. An application container is a container designed to run primarily a single main entry point process, for example a PostgreSQL server.
An application container is in contrast with a system container, in which multiple services are running at the same time (such as PostgreSQL, SSH, Syslog, and so on). System containers are similar to traditional virtual machines or physical servers, but they tend not to fit well in Kubernetes (or at least, this is what we believe).
Another important property of our application containers is that they are also immutable, meaning that they are shipped with a given version of the stack and they cannot be updated using
yum update or
apt upgrade, for example.
An update means a new container image. For example, in Kubernetes terms, PostgreSQL is an application, and every PostgreSQL minor release has its own immutable container image.
Kubernetes has been designed to work with immutable application containers, and to perform deployments and/or updates of such applications. Persistent Volumes allow us to reuse the same PGDATA files.
Another benefit of using application containers over system containers is that our application containers do not require the root user to run or access the storage, reducing the risk of exploits and privilege escalation incidents. This allows us to implement important Pod Security Policies (PSP) in our systems such as non-privileged mode for containers and volume access.
Choosing a declarative approach and immutable application containers means that our Cloud Native PostgreSQL and Cloud Native BDR products can only work with Kubernetes and, most importantly, in Kubernetes.
This is according to us an important difference in views between our operators and the existing ones currently available as open source. Consider for example that, in order to manage High Availability and automated failover, we do not use tools that have been designed for VM/bare metal setups like Patroni or repmgr (which by the way we created and still develop).
We’ve decided to rely on Kubernetes only or, simply, we made the Cloud Native choice.
Leave a ReplyWant to join the discussion?
Feel free to contribute!