Operators: the robot DBA/admin
An operator is a controller that knows how to run a specific piece of software. You don’t write a Deployment, a Service, a StatefulSet, and a backup cron by hand — you declare one high-level Custom Resource (CR) describing what you want, and the operator reconciles all the low-level objects to match. It’s a robot DBA/admin that watches its CR forever and keeps reality in sync.
Declare intent, get a managed system
Section titled “Declare intent, get a managed system”flowchart LR CR[/Custom Resource<br/>e.g. Cluster, Keycloak/] -->|watches| Op[Operator] Op -->|creates + manages| Pods[Pods / StatefulSet] Op --> Svc[Services] Op --> Sec[(Secrets)] Op -.->|drift? recreate| Pods
You commit the CR to Git; Argo CD applies it (see GitOps); the operator does the rest. One operator, many instances — the same CNPG operator runs every Postgres on the cluster, no matter which app owns it.
The two operators here
Section titled “The two operators here”| Operator | CR you write | API group/version | Namespace |
|---|---|---|---|
| CloudNativePG | Cluster | postgresql.cnpg.io/v1 | cnpg-system |
| Keycloak | Keycloak | k8s.keycloak.org/v2beta1 | keycloak |
A CNPG Cluster is tiny — instances, storage, and a backup target — yet it yields a
running Postgres with WAL archiving:
apiVersion: postgresql.cnpg.io/v1kind: Clustermetadata: name: <app>-pg namespace: <app>spec: instances: 1 bootstrap: initdb: database: <app> owner: <app>A Keycloak CR points the auth server at its database and hostname; the operator
creates the StatefulSet and a keycloak-test-service for it:
apiVersion: k8s.keycloak.org/v2beta1kind: Keycloakmetadata: name: keycloak-test namespace: keycloakspec: instances: 1 db: vendor: postgres host: keycloak-test-pg-rw # the CNPG read-write Service database: keycloakBoth operators are installed declaratively via app-of-apps
(apps/cnpg-operator, apps/keycloak-operator).
The auto-generated connection secret
Section titled “The auto-generated connection secret”When CNPG creates a Cluster named <app>-pg, it also generates the
<app>-pg-app Secret automatically. That Secret
holds the app user’s credentials and a ready-to-use uri key — which the API consumes
as DB_URL:
env: - name: DB_URL valueFrom: secretKeyRef: name: <app>-pg-app # <cluster>-app, created by CNPG key: uriSo the database password is never written anywhere by you — the operator mints it,
and other workloads reference it by name. The Keycloak DB works the same way via
keycloak-test-pg-app. See Secrets for the full picture.