Ultimate Guide to Setting Up PostgreSQL in Kubernetes with StatefulSets, Adminer Dashboard, and Ingress.

Jinesh Nagori
6 min readAug 29, 2023

A Guide to Unleashing the Power of StatefulSets, Adminer, and Ingress for Seamless Database Management!

High Level Architecture

Adminer Deployment

Adminer is a full-featured database management tool written in PHP. Adminer is available for MySQL, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDB.

In order to deploy Adminer you need to have a file called adminer-deployment.yaml which is defined as follows:

apiVersion: apps/v1
kind: Deployment
metadata:
name: adminer
labels:
app: adminer
group: db
spec:
replicas: 1
selector:
matchLabels:
app: adminer
template:
metadata:
labels:
app: adminer
group: db
spec:
containers:
- name: adminer
image: adminer:4.7.6-standalone
ports:
- containerPort: 8080
env:
- name: ADMINER_DESIGN
value: pepa-linha
- name: ADMINER_DEFAULT_SERVER
value: postgres
resources:
limits:
memory: "256Mi"
cpu: "500m"

But there is a problem. How to open the Adminer page? To handle this problem, we need to use another type of Kubernetes object — Service.

To create service object, add new YAML file with Service definition adminer-svc.yaml:

apiVersion: v1
kind: Service
metadata:
name: adminer
labels:
group: db
spec:
type: ClusterIP
selector:
app: adminer
ports:
- port: 8080
targetPort: 8080

Boom! So, am I able now to open the Adminer Dashboard now? Of course not. We need to do one more thing.

Ingress Controller

ClusterIP exposes the app only for other apps inside the cluster. And in order to get to it from outside of it we need to use a different approach.

Here comes Ingress to the rescue, which is a gateway to our cluster. And the object that we need to create is called Ingress Controller and it’s an implementation of Ingress.

By using, Helm command we can install the Nginx Ingress Controller:

helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace

So, then we can move to defining the routing rule to get inside the Adminer Dashboard. Therefore, we need to create an Ingress object defined in a file ingress-controller.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: adminer
port:
number: 8080

By accessing the public ip of Ingress we can access now access Adminer Dashboard.

Awesome! But how to login to the database? Wait, but what database? We don’t have any database at all!

Creating PersistentVolumeClaim

A PersistentVolumeClaim serves as a user’s request for durable storage resources. It acts as a flexible binding mechanism, linking the user’s storage needs to the underlying PersistentVolume. Defining a PVC involves specifying attributes like access modes, storage requests, and storage class.

Save the following manifest as postgres-pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgres-pv-claim
labels:
app: postgres
spec:
storageClassName: manual
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi

Creating PersistentVolume

PersistentVolumes represent actual storage resources in a cluster, abstracting the underlying details of specific storage providers. These volumes can be manually provisioned by an administrator or dynamically provisioned using StorageClasses.

Save the following manifest as postgres-pv.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
name: postgres-pv-volume
labels:
type: local
app: postgres
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/mnt/data"

Creating Postgres ConfigMaps

A ConfigMaps in Kubernetes lets us mount files on containers without the need to make changes to the Dockerfile or rebuilding the container image.

This feature is extremely helpful in cases where configurations have to be modified or created through files.

Save the following manifest as postgres-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
labels:
app: postgres
data:
POSTGRES_DB: postgresdb
POSTGRES_USER: admin

Creating Postgres Secret

Secrets in Kubernetes are the objects used for supplying sensitive information to containers. They are like ConfigMaps with the difference that data is store in a base 64 encoded format.

For the security of our PostgreSQL cluster, it is wise to restrict access to the database with a password. We will use Secrets to mount our desired passwords to the containers.

Save the following manifest as postgres-secrets.yaml. Please change the password with a secure password of your own.

apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
data:
POSTGRES_PASSWORD: YWRtaW4=

PostgreSQL StatefulSet

While deploying the PostgreSQL on Kubernetes, what object type should be used and why? Deployments or StatefulSets?

The answer is StatefulSet. Let’s discuss!

StatefulSet is the Kubernetes object used to manage stateful applications. It’s preferred over deployments for this use case as it provides guarantees about the ordering and uniqueness of these Pods i.e. the management of volumes is better with stateful sets.

Save the following manifest as postgres-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:10.1
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
envFrom:
- configMapRef:
name: postgres-config
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: POSTGRES_PASSWORD
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgres-pv-claim

PostgreSQL Services

Services in Kubernetes are the objects that pods use to communicate with each other. Services of type ClusterIP are usually used for inter-pod communication.

Save the following manifest as postgres-svc.yaml.

apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
selector:
app: postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432

There is nothing new here, except the port mapping which is specific for PostgreSQL.

And now if you go to the Adminer once again, type following credentials:

System: PostgreSQL
Server: postgres
Username: admin
Password: admin
Database: postgresdb

You should be able to login to a page:

Conclusion

In the dynamic realm of Kubernetes, deploying and managing complex applications like PostgreSQL becomes an art that requires understanding the orchestration and service discovery mechanisms. This guide has taken you through a journey of setting up PostgreSQL in Kubernetes with the power of StatefulSets, Adminer Dashboard, and Ingress, all while ensuring a seamless database management experience.

By leveraging StatefulSets, you’ve embraced the ideal choice for deploying stateful applications like databases. Their guarantee of ordered and unique pods, along with better volume management, ensures the reliability and availability of your PostgreSQL instance.

Adminer Dashboard has emerged as a formidable tool for database management, offering an elegant interface and support for a multitude of databases, including PostgreSQL. Through careful deployment and the utilization of Services, we’ve made Adminer accessible, allowing for efficient database interaction and manipulation.

The introduction of Ingress Controller has opened the gateway to our cluster, enabling external access to the Adminer Dashboard. This enhanced accessibility not only empowers developers but also streamlines the management process.

PersistentVolumeClaim and PersistentVolume have played a crucial role in maintaining the integrity of our data. By abstracting storage concerns from the application layer, we’ve ensured that data persists beyond pod lifecycle events, enhancing the overall robustness of our setup.

Furthermore, we’ve explored ConfigMaps and Secrets, mechanisms that facilitate configuration management and secure sensitive information, respectively. These components contribute to the fine-tuning of our deployment.

As I conclude this guide, you’ve gained a comprehensive understanding of deploying PostgreSQL in Kubernetes, equipped with essential tools and practices for managing a production-ready database environment. The orchestration of StatefulSets, the convenience of Adminer, the accessibility through Ingress, and the data integrity ensured by PersistentVolumes collectively form a solid foundation for orchestrating and managing powerful databases within the Kubernetes ecosystem. With these skills in hand, you’re prepared to harness the capabilities of Kubernetes and streamline your database management endeavors.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response