Стадия жизненного цикла модуля: Preview
У модуля есть требования для установки
Postgres
Namespaced ресурс, который позволяет создавать конечную конфигурацию и является точкой правды состояния для конкретного развернутого сервиса postgres.
PostgresClass Name
Имя класса, с которым будет связан конкретный ресурс.
Без созданного PostgresClass разворачивание сервиса невозможно.
spec:
postgresClassName: defaultInstance
Секция, которая описывает ресурсы создаваемого сервиса.
Должна пройти валидацию по sizingPolicy соответствующего класса:
spec:
instance:
memory:
size: 1Gi
cpu:
cores: 1
coreFraction: 50
persistentVolumeClaim:
size: 1Gi
storageClassName: defaultConfiguration
Секция, описывающая конфигурацию сервиса postgres.
Должна пройти валидацию по overridableConfiguration и validations соответствующего класса:
spec:
configuration:
maxConnections: 300
sharedBuffers: 128MiType
Тип репликации сервиса, может быть Cluster или Standalone
spec:
type: ClusterCluster
Секция, описывающая топологию и способ репликации кластера postgres.
Должна пройти валидацию по allowedTopology соответствующего класса:
spec:
cluster:
topology: Zonal
replication: ConsistencyAndAvailabilityРежимы репликации и операционные компромиссы
Каждому значению replication соответствуют фиксированное число инстансов и конкретные настройки PostgreSQL. Ниже — главное, что нужно понимать при выборе режима.
Availability (2 инстанса: primary + асинхронная реплика)
Приоритет — скорость восстановления после сбоя (RTO < 60 сек).
-
Репликация асинхронная (
synchronous_commit = local): primary подтверждает транзакцию сразу после записи в собственный WAL, не дожидаясь реплики. Если primary упадёт прямо сейчас, последние несколько транзакций могут не успеть попасть на реплику — данные будут потеряны. RPO не равен нулю. -
Проверка готовности реплики (readiness) сводится к тому, отвечает ли PostgreSQL на подключение (
pg_isready). Реплика может быть помечена готовой, даже если она сильно отстала от primary (т.е. лаг репликации не учитывается).
Когда выбирать: доступность важнее, чем нулевые потери данных; нагрузка хорошо переживёт возможное небольшое расхождение данных.
Consistency (2 инстанса: primary + синхронная реплика)
Приоритет — не потерять ни одной подтверждённой (committed) транзакции (RPO = 0, RTO < 120 сек).
Среднее время переключения в случае отказа (failover) ~ 60 секунд.
-
Репликация синхронная (
synchronous_commit = remote_apply): primary подтверждает транзакцию только после того, как реплика записала WAL на диск и применила ее у себя. Потери подтверждённых (committed) данных при failover нет (RPO = 0), но каждый коммит немного медленнее. -
Запись может остановиться полностью. Если реплика недоступна, primary перестаёт принимать коммиты до тех пор, пока реплика не восстановится.
-
Проверка готовности реплики основана на состоянии потока репликации (
streaming): реплика считается готовой только если она активно получает WAL от primary.
Когда выбирать: потеря даже одной подтверждённой транзакции недопустима, и вы готовы мириться с остановкой записи при потере реплики.
ConsistencyAndAvailability (3 инстанса: primary + одна синхронная + одна асинхронная реплика)
Баланс между надёжностью и доступностью. Рекомендуется как основной режим для production (RPO ~ 0, RTO < 90 сек).
Среднее время переключения в случае отказа (failover) ~ 30 секунд.
-
Три инстанса — потребляет больше ресурсов (3 пода, 3 PVC), но надёжнее: третий узел позволяет оператору принять взвешенное решение при failover (кворум).
-
Репликация в режиме
remote_write: primary подтверждает транзакцию, когда синхронная реплика получила WAL и сохранила его на диск. Это быстрее, чемremote_applyв режимеConsistency, но строже, чем чисто асинхронная репликация (в режимеAvailability): при падении primary большинство или все данные уже у реплики. -
Взвешенный автоматический failover: наличие трёх узлов (кворум) позволяет оператору убедиться, что синхронная реплика достаточно актуальна, прежде чем делать её primary. Это снижает риск promote узла с устаревшими данными, но в сложных ситуациях failover может занять чуть больше времени.
-
Синхронная реплика: Выбирается автоматически и не фиксирована (т.е. первая реплика, записавшая WAL на диск и сообщившая об этом primary, будет считаться синхронной). При failover становится primary практически без задержек с момента получения promote request.
-
Асинхронная реплика может отставать от синхронной. Не рассчитывайте на неё как на источник актуальных данных для чтения или как на кандидата при failover — это резервный узел.
Когда выбирать: production-нагрузка, где важны и сохранность данных, и быстрое автоматическое восстановление.
Поддерживаемые версии PostgreSQL
Единственная поддерживаемая версия Postgres 17.6
Наши образы для запуска PostgreSQL-контейнеров основаны на distroless-архитектуре.
Основные концепции каждого образа:
- добавлена русская локаль
ru_RU.UTF-8 - запуск процессов
**postgres**производится под пользователем с UID64535
Users
Секция, позволяющая управлять пользователями postgres.
Список структур декларативно отражает состояние пользователей сервиса и с помощью контроллера Postgres Operator,
будет синхронизироваться в цикле Reconcile.
Внимание: Удаление элемента списка или изменения имени - будет означать удаления пользователя в сервисе postgres.
spec:
users:
- name: test-rw
hashedPassword: >-
SCRAM-SHA-256$4096:8LTjDsWOlQ7fnvr0DqRQx0TXMTh6LIyQJow2UnNlsJE=$ZjQi5diDTvn0g7is1ez9qPSGm6SoGezF0FVCZXssDKw=:IEzN8Dz5KcGd1r47thky5XFRhXlIMeoNLNfZtIlGv/8=
role: rw
# password: 123
# storeCredsToSecret: test-rw-credsПароли пользователя
В целях безопасности, по умолчанию мы используем хэшированные пароли для доступа к базе данных.
Вы можете самостоятельно указать пароль в поле hashedPassword в формате MD5/SCRAM-SHA-256, который нативно поддерживается postgres.
Либо указать plain-текст пароль в поле password и мы автоматически мутируем его в хэшированный формат.
В случае если вы указали plain-текст password, вы можете указать имя секрета, который будет создан для хранения там пароля в открытом виде, и обновляться строками подключения для имеющихся логических баз.
Смена пароля происходит путем изменения одного из полей hashedPassword или password c последующей его мутацией.
Внимание: Возможно указание пароля либо в хэшированном виде hashedPassword, либо в виде открытой строки password.
Внимание: Доставка учетных данных, в случае когда поле storeCredsToSecret не указано, берет на себя пользователь.
Пример полей пользовательского секрета:
Kind: Secret
name: test-rw-creds
data:
host: 'd8ms-pg-test-rw'
password: '123'
test-dsn: 'host=d8ms-pg-test-rw;port=5432;dbname=test;user=test-ro;password=123'
username: test-rwРоли
Для управления ролями пользователей мы предлагаем набор пред-созданных ролей:
rw- роль, позволяющая читать, писать, изменять схему таблиц внутри логической базы. Является владельцем всех логических баз.ro- роль, позволяющая только читать из таблиц логических баз.monitoring- дает возможность собирать метрики из системных таблиц, соответствует встроенной ролиpg_monitor.
Пред-созданные роли работают глобально для всех логических баз в рамках одного развернутого сервиса.
Базы данных
Секция, позволяющая управлять логическими базами postgres.
Список структур декларативно отражает состояние логических баз сервиса и с помощью контроллера Postgres Operator,
будет синхронизироваться в цикле Reconcile.
Внимание: Удаление элемента списка или изменения имени - будет означать удаления базы и ВСЕХ ДАННЫХ этой базы в сервисе postgres.
spec:
databases:
- name: "test"Cтатус
Статус сервиса Managed Postgres отражается в ресурсе Postgres.
Структура Conditions однозначно показывает текущий статус сервиса.
Значимые типы:
LastValidConfigurationApplied- Агрегирующий тип, который показывает, была ли применена успешно последняя валидная конфигурация хотя бы раз.ConfigurationValid- показывает прошла ли что конфигурация все валидации связанногоPostgresClass.ScaledToLastValidConfiguration- показывает, соответствует ли количество работающих реплик заданной конфигурации.Available- показывает, работает ли master реплика сервиса и принимает подключения.UsersSynced- показывает, все ли пользователи были синхронизированы и приведены к описанному состоянию.DatabasesSynced- показывает, все ли логические базы были синхронизированы и приведены к описанному состоянию.
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Статус False говорит о проблеме на том или ином этапе либо незавершенной синхронизации состояния.
Для такого состояния будет указан reason и message с описанием.
---
- 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
---Примеры использования
Базовое использование
- Создайте namespace с именем
postgres. - Создайте ресурс
Postgres
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgresapiVersion: 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- Подождите, пока кластер будет создан все conditions будет в
True:
kubectl get postgres test -n postgres -o wide -w- Для подключения используйте клиент
psqlи сервисd8ms-postgres-rw
psql -U test-rw -d testdb -h d8ms-test-rw.postgres.svc -p 5432Развертывание в режиме Standalone
- Создайте namespace с именем
postgres. - Создайте ресурс
Postgres
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgresapiVersion: 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- Подождите, пока кластер будет создан все conditions будет в
True:
kubectl get postgres test -n postgres -o wide -w- Для подключения используйте клиент
psqlи сервисd8ms-standalone-rw
psql -U test-rw -d testdb -h d8ms-pg-standalone-rw.postgres.svc -p 5432Availability для использования другим сервисом в k8s
- Создайте namespace с именем
postgres. - Создайте ресурс
Postgres
kubectl apply -f managed-services_v1alpha1_postgres.yaml -n postgresapiVersion: 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- Подождите, пока кластер будет создан:
kubectl get postgres availability -n postgres -o wide -w- Получить dsn подключение к базе можно используя команду. Либо подключить как переменную окружения в под сервиса.
kubectl get secret test-rw-creds -n postgres-ek -o jsonpath='{.data.test-dsn}' | base64 --decode