Kubegres allows to override its default configurations and bash scripts based on your requirements.
For each namespace where a Kubegres resource is created, Kubegres controller creates a base ConfigMap resource with this contents. That base ConfigMap contains the default configs for all Kubegres resource(s) in that namespace. It defines default contents for "postgres.conf", "pg_hba.conf" and a backup logic in "backup_database.sh".
You can override the following configurations in that base ConfigMap:
- primary_init_script.sh: a bash script which runs the 1st time a Primary PostgreSql container is created. This happens when a new Kubegres resource is deployed to create a new PostgreSql cluster. It is the right place to add instructions creating custom database(s) and user(s) for your requirement.
- backup_database.sh: if you enabled backup for your Kubegres resource, this bash script defines the actions to perform during a backup. It is executed regularly by a dedicated CronJob.
- postgres.conf: the official PostgreSql configs used for both Primary and Replica servers.
- pg_hba.conf: the host-based authentication configs for both Primary and Replica servers.
Examples from Kubegres user(s)
@laukaichung published a great example in GitHub showing how the scripts "backup_database.sh" and "primary_init_script.sh" were overridden in order to use S3 for backup storage and initialization.
How to override the default configurations for all running Kubegres resources?
As mentioned above, Kubegres automatically creates a base ConfigMap named base-kubegres-config in each namespace where Kubegres resources are running.
If you would like to change that base ConfigMap, you can do so by using the tool "kubectl" and edit the resource with name "base-kubegres-config". That change would apply to all Kubegres resources in the same namespace:
kubectl edit configmap base-kubegres-config -n [namespace]
How to override the default configurations for a specific Kubegres resource?
If you would like to override the default configs for a specific PostgreSql cluster only, you can create a custom ConfigMap in that namespace and set its name to the property "spec.customConfig" in your Kubegres YAML, as follows:
apiVersion: kubegres.reactive-tech.io/v1 kind: Kubegres metadata: name: mypostgres namespace: default spec: replicas: 3 image: postgres:13.2 port: 5432 database: size: 200Mi customConfig: mypostgres-conf env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: mySecretResource key: superUserPassword - name: POSTGRES_REPLICATION_PASSWORD valueFrom: secretKeyRef: name: mySecretResource key: replicationUserPassword
And in your custom ConfigMap you can override one or many of these configs: primary_init_script.sh, backup_database.sh, postgres.conf and pg_hba.conf. Please see the examples below.
The bash script below runs only the 1st time a Primary PostgreSql container is created. It overrides "primary_init_script.sh" in a custom ConfigMap, by creating a custom user and a database and grant to that user access rights:
apiVersion: v1 kind: ConfigMap metadata: name: mypostgres-conf namespace: default data: primary_init_script.sh: | #!/bin/bash set -e # This script assumes that the env-var $POSTGRES_MY_DB_PASSWORD contains the password of the custom user to create. # You can add any env-var in your Kubegres resource config YAML. dt=$(date '+%d/%m/%Y %H:%M:%S'); echo "$dt - Running init script the 1st time Primary PostgreSql container is created..."; customDatabaseName="my_app_db" customUserName="my_username" echo "$dt - Running: psql -v ON_ERROR_STOP=1 --username $POSTGRES_USER --dbname $POSTGRES_DB ..."; psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL CREATE DATABASE $customDatabaseName; CREATE USER $customUserName WITH PASSWORD '$POSTGRES_MY_DB_PASSWORD'; GRANT ALL PRIVILEGES ON DATABASE "$customDatabaseName" to $customUserName; EOSQL echo "$dt - Init script is completed";
This script above assumes that the env-var $POSTGRES_MY_DB_PASSWORD contains the password of the custom user to create. Please see an example about how to add a custom env-variable.
Please see below an example of an overridden "backup_database.sh" in a custom ConfigMap, which contains the logic to dump PostgreSql Primary's database:
apiVersion: v1 kind: ConfigMap metadata: name: mypostgres-conf namespace: default data: backup_database.sh: | #!/bin/bash set -e dt=$(date '+%d/%m/%Y %H:%M:%S'); fileDt=$(date '+%d_%m_%Y_%H_%M_%S'); backUpFileName="$KUBEGRES_RESOURCE_NAME-backup-$fileDt.gz" backUpFilePath="$BACKUP_DESTINATION_FOLDER/$backUpFileName" echo "$dt - Starting DB backup of Kubegres resource $KUBEGRES_RESOURCE_NAME into file: $backUpFilePath"; echo "$dt - Running: pg_dumpall -h $BACKUP_SOURCE_DB_HOST_NAME -U postgres -c | gzip > $backUpFilePath" pg_dumpall -h $BACKUP_SOURCE_DB_HOST_NAME -U postgres -c | gzip > $backUpFilePath if [ $? -ne 0 ]; then rm $backUpFilePath echo "Unable to execute a BackUp. Please check DB connection settings" exit 1 fi echo "$dt - DB backup completed for Kubegres resource $KUBEGRES_RESOURCE_NAME into file: $backUpFilePath";
When overriding postgres.conf, there are 2 properties to be aware of:
- "listen_addresses": by default PostgreSql set it to "localhost". But Kubegres explicitly set it to "*". When defining your own postgres.conf, do not forget to set it to "*". Not setting it or using an alternative value could break Kubegres replication capability.
- "wal_level": You cannot set a value for this config because it is passed as an argument to the PostgreSql container. This restriction is part of the design.
Please see below an example of an overridden "postgres.conf" in a custom ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: mypostgres-conf namespace: default data: postgres.conf: | # Replication configs listen_addresses = '*' max_wal_senders = 10 wal_keep_segments = 48 #in Mb max_connections = 100 shared_buffers = 128MB # Logging log_destination = 'stderr,csvlog' logging_collector = on log_directory = 'pg_log' log_filename= 'postgresql-%Y-%m-%d_%H%M%S.log'
Please see below an example of an overridden "pg_hba.conf" in a custom ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: mypostgres-conf namespace: default data: pg_hba.conf: | # TYPE DATABASE USER ADDRESS METHOD # Replication connections by a user with the replication privilege host replication replication all md5 # As long as it is authenticated, all connections allowed except from "0.0.0.0/0" local all all md5 host all all all md5 host all all 0.0.0.0/0 reject
Note about applying ConfigMap changes to existing PostgreSql pods
When we make a change to a ConfigMap, Kubernetes does not notify the Kubegres controller about that update. Consequently, if we want to apply those changes to existing running PostgreSql pods, when have to manually restart them.
However, restarting pods could trigger the failover process and Kubegres may wrongly think that the primary PostgreSql pod is not available and would failover to a Replica PostgreSql pod. To avoid Kubegres controller to failover, we need to pause it.
The instructions to follows are:
- Update your ConfigMap (e.g. "base-kubegres-config", or your custom ConfigMap)
Pause the Kubegres controller by running:
kubectl scale --replicas=0 deployment.apps/kubegres-controller-manager -n kubegres-system
Restart the StatefulSets of your Postgres cluster (in this example my cluster's name is "mypostgres" and I have 3 pods running):
kubectl rollout restart statefulset mypostgres-1 mypostgres-2 mypostgres-3
From that point your pods are using the latest version of the ConfigMap. Check the pods are in a running state:
kubectl get pods
If the pods are running and healthy, then resume the Kubegres controller by running:
kubectl scale --replicas=1 deployment.apps/kubegres-controller-manager -n kubegres-system