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=# \qCreate 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.yamlCreate 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.yamlCreate 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: ClusterIPNow, apply the service.
kubectl apply -f pgadmin-service.yamlCreate 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: 3GiThe 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.yamlCreate 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: 80Now, we apply it
kubectl apply -f pgadmin-ingress.yamlWe should now be able to open a web browser and go to pgadmin.weepynet.com and get greeted with the pgadmin web console.