k8s-pg-controller is a Kubernetes operator that provides a small
PostgresDatabase custom resource on top of
CloudNativePG. The controller translates a
database-focused API into a CloudNativePG Cluster, while leaving PostgreSQL
replication, failover, and runtime database management to CloudNativePG.
This project is currently an early-stage personal controller project. The
current scope is intentionally narrow: one PostgresDatabase owns or references
one CloudNativePG Cluster in the same namespace.
- Creates a CloudNativePG
Clusterfor eachPostgresDatabase. - Supports
deletionPolicy: DeleteanddeletionPolicy: Retain. - Reconciles spec changes after creation: only
replicasis applied to the existing cluster;versionandsizeClasschanges are reported as unsupported (see below). - Reports status endpoints and readiness from the CloudNativePG cluster.
- Marks unsupported post-creation changes to PostgreSQL version and storage size class as status conditions.
Example:
apiVersion: db.stakuya.dev/v1alpha1
kind: PostgresDatabase
metadata:
name: orders
spec:
databaseName: app
deletionPolicy: Retain
version: 16.10-system-trixie
replicas: 1
sizeClass: small| Field | Default | Description |
|---|---|---|
databaseName |
required | Logical database name requested by the user. Currently recorded on the resource but not yet wired into CloudNativePG bootstrap. |
ownerUserName |
empty | Optional owner user name. Currently recorded on the resource but not yet wired into CloudNativePG bootstrap. |
version |
16.10-system-trixie |
PostgreSQL image tag suffix used for the CloudNativePG image. |
replicas |
1 |
CloudNativePG instance count. Valid range: 1 to 3. |
sizeClass |
small |
Storage preset. Valid values: small, medium, large. |
deletionPolicy |
Delete |
Whether deleting the PostgresDatabase also deletes the CloudNativePG Cluster. |
deletionPolicy: Delete sets a controller owner reference on the generated
CloudNativePG cluster. When the PostgresDatabase is deleted, the controller
deletes the CloudNativePG cluster before removing its finalizer.
deletionPolicy: Retain does not keep a controller owner reference on the
CloudNativePG cluster. When the PostgresDatabase is deleted, the controller
removes its finalizer and leaves the CloudNativePG cluster in place. The
controller tracks retained clusters through the
db.stakuya.dev/postgresdatabase label.
| Size class | Storage size |
|---|---|
small |
1Gi |
medium |
5Gi |
large |
10Gi |
Changing sizeClass or version after cluster creation is currently reported
as unsupported through status conditions instead of mutating the existing
CloudNativePG cluster.
- Go 1.26+
- Docker or another container tool
kubectl- Access to a Kubernetes cluster
- CloudNativePG installed in the target cluster
Run focused controller tests:
go test ./internal/controller -run 'TestReconcile|TestBuildStatus' -count=1Install envtest assets and run the non-e2e test suite:
make setup-envtest
make testThe make test target downloads Kubernetes envtest assets under bin/ and
sets KUBEBUILDER_ASSETS for the test run. If a direct go test command fails
with a missing /usr/local/kubebuilder/bin/etcd, install the assets first and
export the path manually. Use the Kubernetes version that matches the project's
k8s.io/api dependency (the make test / make setup-envtest targets derive
this automatically; substitute the matching version below):
export KUBEBUILDER_ASSETS="$(./bin/setup-envtest use 1.35 --bin-dir ./bin -p path)"
go test ./internal/controllerRegenerate manifests and generated Go code:
make manifests generateRun formatting and static checks:
make fmt vet
make lintBuild and push the manager image:
make docker-build docker-push IMG=<registry>/k8s-pg-controller:<tag>Install the CRD:
make installDeploy the controller:
make deploy IMG=<registry>/k8s-pg-controller:<tag>Create the sample PostgresDatabase:
kubectl apply -k config/samples/Check the custom resource and generated CloudNativePG cluster:
kubectl get postgresdatabases
kubectl get clusters.postgresql.cnpg.ioDelete sample resources:
kubectl delete -k config/samples/Undeploy the controller and remove the CRD:
make undeploy
make uninstallconfig/crd,config/rbac,config/manager, andconfig/defaultare Kubebuilder-generated deployment manifests.config/samplescontains the public sample custom resource.bin/,dist/, and coverage output are local generated artifacts and are ignored by Git.PROJECTis Kubebuilder project metadata and should stay in the repository.
Apache License 2.0.