Preliminary version. The functionality may change, but the basic features will be preserved. Compatibility with future versions is ensured, but may require additional migration actions.
Postgres
Namespaced resource that allows creating the final configuration and serves as the source of truth for the state of a specific deployed postgres service.
Postgres Class Name
The name of the class to which a specific resource will be linked.
Deploying the service is impossible without a created Postgres Class.
spec:
postgresClassName: default
Instance
Section that describes the resources of the service being created. Must pass validation according to the sizingPolicy of the corresponding class
spec:
instance:
memory:
size: 1Gi
cpu:
cores: 1
coreFraction: 50
persistentVolumeClaim:
size: 1Gi
storageClassName: default
Configuration
Section describing the configuration of the postgres service. Must pass validation according to the overridableConfiguration and validations of the corresponding class
spec:
configuration:
maxConnections: 300
sharedBuffers: 128Mi
Type
Service replication type, can be Cluster or Standalone
spec:
type: Cluster
Cluster
Section describing the topology and replication method of the postgres cluster. Must pass validation according to the allowedTopology of the corresponding class
spec:
cluster:
topology: Zonal
replication: ConsistencyAndAvailability
Postgres Image
Section allowing you to specify a specific postgres version
spec:
postgresImage:
type: standard
version: "17.4"
Supported PostgreSQL Versions
PostgreSQL versions 16 and above are supported.
Our images for running PostgreSQL containers are based on distroless architecture.
Key concepts of each image:
- Russian locale
ru_RU.UTF-8has been added - postgres processes are run under a user with UID
64535
Additionally, images are divided by types (postgresVersion.imageType).
Image Types
There are several types of images:
minimal- image without additional PG extensions, only built-in ones.standard- image with additional PG extensions:pgaudit,pgvectorandpg-failover-slots.
Users
Section that allows managing postgresql users.
The list of structures declaratively reflects the state of service users and with the help of the Postgres Operator controller,
will be synchronized in the Reconcile loop.
Warning: Removing a list element or changing a name will mean deleting the user in the postgresql service.
spec:
users:
- name: test-rw
hashedPassword: >-
SCRAM-SHA-256$4096:8LTjDsWOlQ7fnvr0DqRQx0TXMTh6LIyQJow2UnNlsJE=$ZjQi5diDTvn0g7is1ez9qPSGm6SoGezF0FVCZXssDKw=:IEzN8Dz5KcGd1r47thky5XFRhXlIMeoNLNfZtIlGv/8=
role: rw
# password: 123
# storeCredsToSecret: test-rw-creds
User Passwords
For security purposes, by default we use hashed passwords for database access.
You can specify a password by yourself in the hashedPassword field in MD5/SCRAM-SHA-256 format, which is natively supported by postgresql.
Or specify a plain-text password in the password field and we will automatically mutate it to hashed format.
In case you specified plain-text password, you can specify the name of a secret,
which will be created to store the password in plain text there, and updated with connection strings for existing logical databases.
Password change occurs by changing one of the fields hashedPassword or password followed by its mutation.
Warning: It is possible to specify a password either in hashed form hashedPassword, or as a plain string password.
Warning: Delivery of credentials, when the storeCredsToSecret field is not specified, is the user’s responsibility.
Example user secret fields:
Kind: Secret
name: test-rw-creds
data:
password: '123'
test-dsn: 'pgsql:host=d8ms-pg-test-rw;port=5432;dbname=test;user=test-ro;password=123'
username: test-rw
Roles
To manage user roles, we offer a set of pre-created roles:
- rw - role that allows reading, writing, changing table schema within a logical database. Owns all logical databases
- ro - role that only allows reading from logical database tables.
- monitoring - allows collecting metrics from system tables, corresponds to the built-in
pg_monitorrole
Pre-created roles work globally for all logical databases within one deployed service.
Databases
Section that allows managing postgresql logical databases.
The list of structures declaratively reflects the state of service logical databases and with the help of the Postgres Operator controller,
will be synchronized in the Reconcile loop.
Warning: Removing a list element or changing a name will mean deleting the database and ALL DATA of this database in the postgres service.
spec:
databases:
- name: "test"
Status
The status of the Managed Postgres service is reflected in the Postgres resource.
The Conditions structure clearly shows the current status of the service
Significant types:
LastValidConfigurationApplied- Aggregating type that shows whether the last valid configuration was successfully applied at least once.ConfigurationValid- shows whether the configuration passed all validations of the associatedPostgres Class.ScaledToLastValidConfiguration- shows whether the number of running replicas matches the specified configuration.Available- shows whether the master replica of the service is running and accepting connections.UsersSynced- shows whether all users have been synchronized and brought to the described state.DatabasesSynced- shows whether all logical databases have been synchronized and brought to the described state.
conditions:
- lastTransitionTime: '2025-09-22T23:20:36Z'
observedGeneration: 2
status: 'True'
type: Available
- lastTransitionTime: '2025-09-22T14:38:04Z'
observedGeneration: 2
status: 'True'
type: ConfigurationValid
- lastTransitionTime: '2025-09-22T14:38:06Z'
observedGeneration: 2
status: 'True'
type: DatabasesSynced
- lastTransitionTime: '2025-09-22T14:38:47Z'
observedGeneration: 2
status: 'True'
type: LastValidConfigurationApplied
- lastTransitionTime: '2025-09-22T23:20:36Z'
observedGeneration: 2
status: 'True'
type: ScaledToLastValidConfiguration
- lastTransitionTime: '2025-09-22T14:38:05Z'
observedGeneration: 2
status: 'True'
type: UsersSynced
Status False indicates a problem at one stage or another or incomplete state synchronization.
For such a state, reason and message with description will be specified.
---
- lastTransitionTime: '2025-09-23T14:53:33Z'
message: Syncing
observedGeneration: 1
reason: Syncing
status: 'False'
type: LastValidConfigurationApplied
- lastTransitionTime: '2025-09-23T14:54:58Z'
message: Not all the instances are running still waiting for 1 to become ready
observedGeneration: 1
reason: ScalingInProgress
status: 'False'
type: ScaledToLastValidConfiguration
---
Usage Examples
Basic Usage
- Create a namespace named
postgres. - Create a
Postgresresource
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgres
apiVersion: managed-services.deckhouse.io/v1alpha1
kind: Postgres
metadata:
labels:
app.kubernetes.io/name: managed-psql-operator
name: test
spec:
users:
- name: test-rw
password: '123'
role: rw
databases:
- name: "testdb"
postgresClassName: default
instance:
memory:
size: 4Gi
cpu:
cores: 2
coreFraction: 50
persistentVolumeClaim:
size: 10Gi
type: Cluster
cluster:
topology: TransZonal
replication: ConsistencyAndAvailability
- Wait until the cluster is created and all conditions are
True:
kubectl get postgres test -n postgres -o wide -w
- To connect, use the
psqlclient and thed8ms-test-rwservice
psql -U test-rw -d testdb -h d8ms-test-rw.postgres.svc -p 5432
Deployment in Standalone Mode
- Create a namespace named
postgres. - Create a
Postgresresource
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgres
apiVersion: managed-services.deckhouse.io/v1alpha1
kind: Postgres
metadata:
labels:
app.kubernetes.io/name: managed-psql-operator
name: standalone
spec:
users:
- name: test-rw
password: '123'
role: rw
databases:
- name: "testdb"
postgresClassName: default
instance:
memory:
size: 4Gi
cpu:
cores: 2
coreFraction: 50
persistentVolumeClaim:
size: 10Gi
type: Standalone
- Wait until the cluster is created and all conditions are
True:
kubectl get postgres test -n postgres -o wide -w
- To connect, use the
psqlclient and thed8ms-pg-standalone-rwservice
psql -U test-rw -d testdb -h d8ms-pg-standalone-rw.postgres.svc -p 5432
Availability for Use by Another Service in k8s
- Create a namespace named
postgres. - Create a
Postgresresource
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgres
apiVersion: managed-services.deckhouse.io/v1alpha1
kind: Postgres
metadata:
labels:
app.kubernetes.io/name: managed-psql-operator
name: availability
spec:
users:
- name: test-rw
password: '123'
storeCredsToSecret: 'test-rw-creds'
role: rw
databases:
- name: "testdb"
postgresClassName: default
instance:
memory:
size: 4Gi
cpu:
cores: 2
coreFraction: 50
persistentVolumeClaim:
size: 10Gi
type: Cluster
cluster:
topology: TransZonal
replication: ConsistencyAndAvailability
- Wait until the cluster is created:
kubectl get postgres availability -n postgres -o wide -w
- To get the DSN for connecting to the database, use the following command. Or set it as an environment variable in the service pod.
kubectl get secret test-rw-creds -n postgres-ek -o jsonpath='{.data.test-dsn}' | base64 --decode