Databases¶
PostgreSQL, MariaDB and Redis run on the platform under Kubernetes operators. An operator is a controller that watches for objects of its own custom resource types and reconciles the running database to match them, continuously. Creating a database therefore means creating an object rather than calling a provisioning API, and the operator keeps the result in the state the object describes.
Each engine runs as a StatefulSet on persistent volumes, so it is scheduled, restarted, monitored and backed up by the same machinery as any other workload. You are responsible for your schema and your data; provisioning, replication, failover, patching and backups are handled by the operator.
Each engine is reached the same way in the console: WebHosting > Databases, then the engine you want. Every row on those pages is one logical database in your project.
PostgreSQL¶
Powered by CloudNativePG.
PostgreSQL databases can only reference a Postgres cluster in the same project, so each
project that wants PostgreSQL needs its own cluster provisioned once before the
Create PostgreSQL button will work. That first step is not yet self-service - ask your
platform administrator, or apply the Cluster yourself if you have oc access with
sufficient permissions:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres
namespace: <your-project>
spec:
bootstrap:
initdb:
database: app
owner: app
enablePDB: false
enableSuperuserAccess: true
imageName: ghcr.io/cloudnative-pg/postgresql:17.2
instances: 1
storage:
storageClass: berry-storage-block
accessModes:
- ReadWriteOnce
size: 5Gi
Set instances above 1 for high availability, and enablePDB: true once you do. Encrypted
offsite backups are wired up automatically for every cluster - you do not configure
spec.backup yourself. See Observability & backup.
Once the cluster exists, each additional database is lightweight:
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: myapp
namespace: <your-project>
spec:
cluster:
name: postgres
name: myapp
owner: app
Connecting. CloudNativePG creates the Services and a credentials Secret for you:
| What | Where |
|---|---|
| Read-write host | <cluster-name>-rw.<your-project>.svc |
| Read-only host | <cluster-name>-ro.<your-project>.svc |
| Credentials | Secret <cluster-name>-app, keys username and password |
Deleting. Removing a Database drops that one database. Removing the Cluster removes
the whole instance and every database in it - back up anything you need first.
MariaDB¶
Powered by the MariaDB Operator.
Like PostgreSQL, MariaDB runs per project: a MariaDB server in your namespace, on
your storage, with the databases inside it. Two Templates in the openshift namespace
create the objects, so the console and oc process produce the same result:
oc process -n openshift mariadb-instance -p NAME=mariadb -p NAMESPACE=<your-project> | oc apply -f -
oc process -n openshift mariadb-database -p NAME=myapp -p NAMESPACE=<your-project> \
-p INSTANCE_NAME=mariadb -p DB_USER=myapp-user | oc apply -f -
The first creates the server and a Secret mariadb-root with root's generated password.
The second creates the database, the user your application connects as, a grant giving
that user all privileges on that one database, and the credentials Secret:
apiVersion: k8s.mariadb.com/v1alpha1
kind: Database
metadata:
name: myapp
namespace: <your-project>
spec:
mariaDbRef:
name: mariadb
waitForIt: true
name: myapp
characterSet: utf8mb4
collate: utf8mb4_unicode_ci
cleanupPolicy: Skip
Connecting. Everything a workload needs is in one Secret:
| What | Where |
|---|---|
| Host | <server>.<your-project>.svc, port 3306 |
| Credentials | Secret <database>-db-user, keys username, password, host, port and database |
Deleting. Removing a Database keeps the data on the server (cleanupPolicy: Skip);
set it to Delete first to drop the database. Removing the MariaDB removes the whole
server and every database in it - back up anything you need first. See the
MariaDB guide.
Redis¶
Powered by the Redis Operator. Each instance is dedicated to your project - caching, sessions, queues and other low-latency workloads.
The password comes from a Secret you create first:
apiVersion: v1
kind: Secret
metadata:
name: redis-cache
namespace: <your-project>
type: Opaque
stringData:
password: <choose-a-strong-password>
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: Redis
metadata:
name: cache
namespace: <your-project>
spec:
kubernetesConfig:
image: quay.io/opstree/redis:v7.0.12
imagePullPolicy: IfNotPresent
redisSecret:
name: redis-cache
key: password
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
service:
serviceType: ClusterIP
redisConfig: {}
storage:
volumeClaimTemplate:
spec:
storageClassName: berry-storage-block
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Omit redisSecret for an instance with no authentication.
Connecting. Host <name>.<your-project>.svc, port 6379, authenticating with the
password from the Secret.
Deleting. Remove the Redis object. Depending on your storage class's reclaim policy,
its persistent volume goes with it.
Simple and advanced views¶
The PostgreSQL and MariaDB pages carry a Simple / Advanced toggle. Simple is the guided view described above. Advanced hands off to the operator's own panel, which exposes every resource type the operator provides and full YAML editing - useful for replicas, poolers and scheduled backups that the guided forms do not cover.
How to¶
Step-by-step guides for each of these, in the console and as YAML: