How to Deploy pgadmin to Kubernetes

How to Deploy pgadmin to Kubernetes

Overview

This outlines how to add the pgadmin container to kubernetes and point to an existing postgresql instance, residing outside the cluster.

Create SuperUser for Postgres Server

If you already have an administrator user on postgres, you can skip this step. Otherwise, SSH into the postgres machine and log into the database:

ssh wn-postgres-01
sudo su - postgres
psql
postgres=#

Modify the details of this command (username and password)

CREATE ROLE blair WITH LOGIN SUPERUSER PASSWORD 'Password123!';

Execute the query and exit

postgres=# CREATE ROLE blair WITH LOGIN SUPERUSER PASSWORD 'Password123!';
postgres=# \q

Create Admin Password Secret

We will need to provide the admin credentials as a kubernetes secret to the container.

First, let’s get the base64 for our password:

echo -n "Password123" | base64
UGFzc3dvcmQxMjM=

pgadmin-secret.yaml

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: pgadmin
data:
  pgadmin-password: UGFzc3dvcmQxMjM=

Now, let’s apply the secret to the cluster.

kubectl apply -f pgadmin-secret.yaml

Create a ConfigMap

We will need to create a config map to tell pgadmin which postgres servers to connect to.

pgadmin-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: pgadmin-config
data:
servers.json: |
{
	"Servers": {
		"1": {
			"Name": "wn-postgres-01",
			"Group": "Servers",
			"Port": 5432,
			"Username": "postgres",
			"Host": "wn-postgres-01.weepynet.com",
			"SSLMode": "prefer",
			"MaintenanceDB": "postgres"
		}
	}
}

Let’s apply this config map.

kubectl apply -f pgadmin-configmap.yaml

Create Kubernetes Service

We will now need to create a service object, so we will have something to point traefik to.

pgadmin-service.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: pgadmin-service
spec:
  selector:
    app: pgadmin
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  type: ClusterIP

Now, apply the service.

kubectl apply -f pgadmin-service.yaml

Create StatefulSet

We will use a stateful set, as it will autoprovision stateful storage, rather than having to define pvc/vc manually.

pgadmin-statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pgadmin
spec:
  serviceName: pgadmin-service
  podManagementPolicy: Parallel
  replicas: 1
  updateStrategy:
    type: RollingUpdate
  selector:
    matchLabels:
      app: pgadmin
  template:
    metadata:
      labels:
        app: pgadmin
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: pgadmin
          image: dpage/pgadmin4:5.4
          imagePullPolicy: Always
          env:
            - name: PGADMIN_DEFAULT_EMAIL
              value: blair.hoddinott@gmail.com
            - name: PGADMIN_DEFAULT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: pgadmin
                  key: pgadmin-password
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          volumeMounts:
            - name: pgadmin-config
              mountPath: /pgadmin4/servers.json
              subPath: servers.json
              readOnly: true
            - name: pgadmin-data
              mountPath: /var/lib/pgadmin
      volumes:
        - name: pgadmin-config
          configMap:
            name: pgadmin-config
  volumeClaimTemplates:
    - metadata:
        name: pgadmin-data
        annotations:
          volume.beta.kubernetes.io/storage-class: nfs-client
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 3Gi

The annotation volume.beta.kubernetes.io/storage-class: nfs-client is important, because we are dynamically provisioning the storage with the nfs-client provisioner.

Now, we apply the stateful set.

kubectl apply -f pgadmin-statefulset.yaml

Create the Traefik Ingress

Now, all that is remaining is to create the traefik ingress so we can log into pgadmin through the browser.

pgadmin-ingress.yaml

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: pgadmin-ingress
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`pgadmin.weepynet.com`)
      kind: Rule
      services:
        - name: pgadmin-service
          port: 80

Now, we apply it

kubectl apply -f pgadmin-ingress.yaml

We should now be able to open a web browser and go to pgadmin.weepynet.com and get greeted with the pgadmin web console.