In the past article, we talk about installing MySQL and we mentioned the 3 main items needed: a configuration file, a storage and configuring the port.
Installing PostgreSQL is not different, it has the same requirement.
Custom Configuration:
While you may not need any special customization, it wont hurt to have the file in your disposable, you can always get the full config file docker and then customize it, so to get it run the command:
docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf
You can now customize the file, like for example, change the listening address to *
to allow all the devices on your network to access it, like this:
listen_addresses = '*' # what IP address(es) to listen on; # comma-separated list of addresses; # defaults to 'localhost'; use '*' for all # (change requires restart) #port = 5432 # (change requires restart) #max_connections = 100 # (change requires restart)
If you don't have access to docker right now and you would like to check what other options you can change have a look at this online file.
Storage Configuration:
There is a lot of options here, but you need to familiarize yourself with what K3s storage provides, remember K3s is a slimier version of K8s so not everything is available for you to use. Luckily for us, the local storage option is available.
So, what we will define is a local storage with read/write access permission and with 5GB of space, we can use the following to create it:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: postgres-server spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 5Gi
Port Configuration
We are not going to change the default port, but we need to configure out cluster to allow the access to this port, so we have it like this:
apiVersion: v1 kind: Service metadata: name: postgres namespace: postgres-server spec: selector: app: postgres type: LoadBalancer ports: - name: postgres-port protocol: TCP port: 5432 targetPort: 5432
Some of these topics may not be 100% clear to me, so I might also fail to explain, so if you have better way to explain it or know what I am doing wrong, please let me know.
Deployment
Now that we have the most basic information we need, we gather everything in two files, one big yml
file and a small .conf
file.
Lets call our yaml file postgres.yml
and inside of it lets add the following:
--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgres-pvc namespace: postgres-server spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 5Gi --- apiVersion: v1 kind: Service metadata: name: postgres namespace: postgres-server spec: selector: app: postgres type: LoadBalancer ports: - name: postgres-port protocol: TCP port: 5432 targetPort: 5432 --- apiVersion: apps/v1 kind: Deployment metadata: name: postgres namespace: postgres-server spec: replicas: 1 selector: matchLabels: app: postgres template: metadata: labels: app: postgres name: postgres spec: nodeSelector: kubernetes.io/hostname: worker-1 containers: - name: postgres image: ghcr.io/zaherg/postgres:latest imagePullPolicy: Always ports: - name: postgres containerPort: 5432 volumeMounts: - name: postgres-storage mountPath: /var/lib/postgresql/data - name: postgres-config-volume mountPath: /etc/postgresql/postgresql.conf subPath: postgresql.conf env: - name: POSTGRES_PASSWORD value: "secret" - name: POSTGRES_USER value: "postgres" - name: POSTGRES_HOST_AUTH_METHOD value: "trust" volumes: - name: postgres-storage persistentVolumeClaim: claimName: postgres-pvc - name: postgres-config-volume configMap: name: postgres-config items: - key: main-config path: postgresql.conf
I am using my own docker image which I have built based on latest version of ubuntu postgres image, the reason is that in my old experience you have to edit the pg_hba.conf
file to make sure every device can access postgresql, it may not be needed any more, you can always check the official docker docs here about why I need to edit it, but for me I did that to give my development devices access to my RPI cluster, as I nowadays I use that cluster as part of my development setup.
Now that we have everything, we start executing the commands, but remember these commands should be run from within your Master PI.
First we need to create the namespace for our service, as I like to separate everything using the namespace, we do that by executing the command
kubectl create namespace postgres-server
Second, we create something called the configuration map, which will holds our PostgreSQL custom configuration
kubectl create configmap postgres-config --from-file=main-config=my-postgres.conf -n postgres-server
Lastly, we need to create the storage, the service and the deployment, luckily we have stored those all inside our postgres.yml
file we can run the following command to create them at once:
kubectl apply -f postgres.yml
To check that everything is running we can run the following command:
kubectl get svc -n postgres-server
If everything was okay, you will get a result similar to this one:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE postgres LoadBalancer 10.43.97.220 192.168.68.110,192.168.68.111,192.168.68.112 5432:32688/TCP 20d
I have a small github repo which contains all the code if you like to check, you can find it here.
Now, you can connect to it via any apps using the following info (password is "secret").
Remember to change the host to the IP of your RPI, as for me I have the IP aliased to the service name postgres
in my /etc/hosts
file.

Next step we will discuss how to automatically backup our PostgreSQL databases once every day (or more).