Deploying single-node containers and high-availability clusters on k8s

1. Single-node container

On the master node of the k8s cluster, create a namespace named ivorysql.

[root@k8s-master ~]# kubectl create ns ivorysql

Download the latest docker_library code.

[root@k8s-master ~]# git clone https://github.com/IvorySQL/docker_library.git

Enter the single-node directory

[root@k8s-master ~]# cd docker_library/k8s-cluster/single
[root@k8s-master single]# vim statefulset.yaml #Update the PVC information and database password in the StatefulSet to match your actual environment.

Use statefulset.yaml to create a single-node pod.

[root@k8s-master single]# kubectl apply -f statefulset.yaml
service/ivorysql-svc created
statefulset.apps/ivorysql created

Wait for the single-node pod to be successfully created.

[root@k8s-master single]# kubectl get all -n ivorysql
NAME             READY   STATUS              RESTARTS   AGE
pod/ivorysql-0   0/1     ContainerCreating   0          47s

NAME                   TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/ivorysql-svc   NodePort   10.108.178.236   <none>        5432:32106/TCP,1521:31887/TCP   47s

NAME                        READY   AGE
statefulset.apps/ivorysql   0/1     47s
[root@k8s-master single]# kubectl get all -n ivorysql
NAME             READY   STATUS    RESTARTS   AGE
pod/ivorysql-0   1/1     Running   0          2m39s

NAME                   TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/ivorysql-svc   NodePort   10.108.178.236   <none>        5432:32106/TCP,1521:31887/TCP   2m39s

NAME                        READY   AGE
statefulset.apps/ivorysql   1/1     2m39s

Connect to IvorySQL via its PostgreSQL port using the psql

[root@k8s-master single]# psql -U ivorysql -p 32106 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=# select version();
                                                        version
------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 18.0 (IvorySQL 5.0) on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-28), 64-bit
(1 row)

ivorysql=# show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 pg
(1 row)

ivorysql=# exit

Connect to IvorySQL’s Oracle-compatible port using psql.

[root@k8s-master single]# psql -U ivorysql -p 31887 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=# select version();
                                                        version
------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 18.0 (IvorySQL 5.0) on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-28), 64-bit
(1 row)

ivorysql=# show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 oracle
(1 row)

Uninstall Single-node container

[root@k8s-master single]# kubectl delete -f statefulset.yaml

2. High Availability Cluster

Access the master node of the k8s cluster and create a namespace named ivorysql.

[root@k8s-master ~]# kubectl create ns ivorysql

Download the latest docker_library code.

[root@k8s-master ~]# git clone https://github.com/IvorySQL/docker_library.git

Enter the high-availability cluster directory.

[root@k8s-master ~]# cd docker_library/k8s-cluster/ha-cluster/helm_charts
[root@k8s-master single]# vim values.yaml #Adjust the PVC settings, cluster size, and other configurations in values.yaml according to your environment. For the database password, check templates/secret.yaml and modify it as needed.

Deploy the high-availability cluster using Helm commands.

[root@k8s-master helm_charts]# helm install ivorysql-ha-cluster -n ivorysql .
NAME: ivorysql-ha-cluster
LAST DEPLOYED: Wed Sep 10 09:45:36 2025
NAMESPACE: ivorysql
STATUS: deployed
REVISION: 1
TEST SUITE: None
[root@k8s-master helm_charts]# kubectl get all -n ivorysql
NAME                         READY   STATUS    RESTARTS   AGE
pod/ivorysql-patroni-hac-0   1/1     Running   0          42s
pod/ivorysql-patroni-hac-1   0/1     Running   0          18s

NAME                                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/ivorysql-patroni-hac          NodePort    10.96.119.203    <none>        5432:32391/TCP,1521:32477/TCP   42s
service/ivorysql-patroni-hac-config   ClusterIP   None             <none>        <none>                          42s
service/ivorysql-patroni-hac-pods     ClusterIP   None             <none>        <none>                          42s
service/ivorysql-patroni-hac-repl     NodePort    10.100.122.0     <none>        5432:30111/TCP,1521:32654/TCP   42s

NAME                                    READY   AGE
statefulset.apps/ivorysql-patroni-hac   1/3     42s

Wait until all pods are running successfully, indicating the cluster deployment is complete.

[root@k8s-master helm_charts]# kubectl get all -n ivorysql
NAME                         READY   STATUS    RESTARTS   AGE
pod/ivorysql-patroni-hac-0   1/1     Running   0          88s
pod/ivorysql-patroni-hac-1   1/1     Running   0          64s
pod/ivorysql-patroni-hac-2   1/1     Running   0          41s

NAME                                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                         AGE
service/ivorysql-patroni-hac          NodePort    10.96.119.203    <none>        5432:32391/TCP,1521:32477/TCP   88s
service/ivorysql-patroni-hac-config   ClusterIP   None             <none>        <none>                          88s
service/ivorysql-patroni-hac-pods     ClusterIP   None             <none>        <none>                          88s
service/ivorysql-patroni-hac-repl     NodePort    10.100.122.0     <none>        5432:30111/TCP,1521:32654/TCP   88s
NAME                                    READY   AGE
statefulset.apps/ivorysql-patroni-hac   3/3     88s

Connect to the PostgreSQL and Oracle ports of the cluster’s primary node using psql.

[root@k8s-master helm_charts]# psql -U ivorysql -p 32391 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=# show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 pg
(1 row)

ivorysql=# SELECT pg_is_in_recovery();
 pg_is_in_recovery
-------------------
 f
(1 row)

ivorysql=# exit
[root@k8s-master helm_charts]# psql -U ivorysql -p 32477 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=# show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 oracle
(1 row)

ivorysql=# SELECT pg_is_in_recovery();
 pg_is_in_recovery
-------------------
 f
(1 row)

ivorysql=#

Use psql to connect to the PostgreSQL and Oracle ports of the cluster’s standby node.

[root@k8s-master helm_charts]# psql -U ivorysql -p 30111 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=# show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 pg
(1 row)

ivorysql=# SELECT pg_is_in_recovery();
 pg_is_in_recovery
-------------------
 t
(1 row)

ivorysql=# exit

[root@k8s-master helm_charts]# psql -U ivorysql -p 32654 -h 127.0.0.1 -d ivorysql
Password for user ivorysql:

ivorysql=#  show ivorysql.compatible_mode;
 ivorysql.compatible_mode
--------------------------
 oracle
(1 row)

ivorysql=# SELECT pg_is_in_recovery();
 pg_is_in_recovery
-------------------
 t
(1 row)

ivorysql=#

Uninstall high-availability cluster

[root@k8s-master helm_charts]# helm uninstall ivorysql-ha-cluster -n ivorysql

Remove PVC

[root@k8s-master helm_charts]# kubectl delete pvc ivyhac-config-ivorysql-patroni-hac-0 -n ivorysql
[root@k8s-master helm_charts]# kubectl delete pvc ivyhac-config-ivorysql-patroni-hac-1 -n ivorysql
[root@k8s-master helm_charts]# kubectl delete pvc ivyhac-config-ivorysql-patroni-hac-2 -n ivorysql
[root@k8s-master helm_charts]# kubectl delete pvc pgdata-ivorysql-patroni-hac-0 -n ivorysql
[root@k8s-master helm_charts]# kubectl delete pvc pgdata-ivorysql-patroni-hac-1 -n ivorysql
[root@k8s-master helm_charts]# kubectl delete pvc pgdata-ivorysql-patroni-hac-2 -n ivorysql