Почему стоит уйти от чартов Bitnami?
Если вы запускаете PostgreSQL на Kubernetes, скорее всего, вы уже пользовались популярными Helm-чартами от Bitnami. Долгое время они были первым выбором для многих, однако на горизонте назревают серьёзные перемены. Как описано в этом GitHub-issue, Bitnami переводит свои production-ready чарты и образы на коммерческую модель. Для тех, кто опирается на открытые решения и продвигает их, это сигнал: пора искать надёжную альтернативу.
Именно здесь на сцену выходит CloudNative-PG.
Знакомство с CloudNative-PG
CloudNative-PG — это Kubernetes-оператор (operator), созданный для управления полным жизненным циклом кластеров PostgreSQL. В основе его философии лежит декларативный, облачно-нативный (cloud-native) подход к управлению базами данных. В марте 2024 года проект был принят в CNCF на стадии incubating, что подтверждает его зрелость и поддержку со стороны сообщества.
Среди ключевых возможностей оператора:
-
Декларативное управление: весь кластер PostgreSQL — роли, базы данных, конфигурации — описывается в одном YAML-файле.
-
Высокая доступность и самовосстановление: автоматический failover и восстановление гарантируют работоспособность базы данных без ручного вмешательства.
-
Встроенный мониторинг: поставляется с экспортером для Prometheus, что упрощает интеграцию в существующий стек наблюдаемости (observability).
-
Удобный импорт данных: предоставляет простой механизм переноса данных из существующей базы PostgreSQL — именно то, что нужно для миграции.
В этом руководстве мы пройдём весь путь: развернём новый кластер PostgreSQL с помощью CloudNative-PG и импортируем данные из базы, ранее управлявшейся Helm-чартом Bitnami.
Шаг 1: Установка оператора CloudNative-PG
Для начала нужно установить оператор в кластер Kubernetes. Оператор включает в себя определения пользовательских ресурсов (Custom Resource Definitions, CRDs), с помощью которых мы будем описывать наши кластеры баз данных.
Следующая команда устанавливает последнюю версию оператора:
kubectl apply --server-side -f \
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.27/releases/cnpg-1.27.0.yaml
Небольшой совет: флаг --server-side здесь рекомендован. Манифест оператора довольно объёмный, и этот флаг помогает избежать проблем с инструментами вроде ArgoCD, которые могут не справляться с большими ресурсами.
Шаг 2: Настройка кластера и импорт данных
Теперь самое интересное. Мы опишем новый кластер PostgreSQL с помощью ресурса Cluster. В том же манифесте будет указана конфигурация для импорта данных из старой базы под управлением Bitnami.
Ниже приведён полный манифест, который мы разберём по частям. Он содержит три основных ресурса:
-
Cluster: сам кластер PostgreSQL.
-
Pooler: пул соединений PgBouncer для обеспечения высокой доступности.
-
PodMonitor: ресурс для сбора метрик Prometheus.
Ресурс Cluster
Это центральный ресурс нашей базы данных PostgreSQL. Рассмотрим ключевые параметры:
-
.spec.instances: создаём кластер из трёх узлов для высокой доступности. CloudNative-PG обеспечит, что один узел будет первичным (primary), а остальные — репликами с потоковой репликацией (streaming replication standbys). -
.spec.managed.roles: роль пользователяtestобъявляется прямо в манифесте — пример декларативного управления ролями. -
.spec.externalClusters: ключ к нашей миграции. Здесь мы описываем ссылку на старую базу данных, которую оператор использует для подключения и организации импорта данных. В полеhostнужно указать сервис существующего PostgreSQL. -
.spec.bootstrap.initdb.import: эта секция указывает оператору инициализировать новый кластер, импортировав данные из указанногоexternalCluster. Параметрtype: microserviceиспользуется для импорта одной базы данных. -
.spec.storage: здесь задаётся хранилище для базы данных — 8 Гб из storage classgp3.
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres
spec:
managed:
roles:
- name: test
ensure: present
instances: 3
imageName: ghcr.io/cloudnative-pg/postgresql:17.5
externalClusters: # Create the reference for the external cluster
- name: source-db
connectionParameters:
host: test-postgresql-ha-pgpool.test.svc.cluster.local # Using K8s DNS
user: postgres
sslmode: disable
dbname: test
password: # Use the password located in my secret test-postgresql
name: test-postgresql
key: PASSWORD
bootstrap:
initdb: # Automatic migration
database: test
owner: test
import:
type: microservice # Only that database for the postgresql
databases:
- test
source:
externalCluster: source-db
enableSuperuserAccess: true
storage:
size: 8Gi
storageClass: gp3
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 1Gi
---
Пул соединений (Connection Pooler)
Пул соединений, такой как PgBouncer, необходим для управления подключениями в конфигурации с высокой доступностью. Он защищает первичную базу данных от шторма соединений (connection storm), особенно во время failover.
-
.spec.cluster.name: привязывает пулер к нашему кластеруpostgres. -
.spec.instances: запускаем две реплики пулера для отказоустойчивости. -
.spec.pgbouncer.poolMode: режимsession— распространённый и безопасный выбор, при котором клиент удерживает соединение на протяжении всей сессии. -
.spec.type: rw: настраивает пулер на работу с первичным экземпляром кластера в режиме чтения-записи (read-write).
apiVersion: postgresql.cnpg.io/v1
kind: Pooler # Because I'm going to use it in HA
metadata:
name: "pooler-postgres"
spec:
cluster:
name: postgres
instances: 2
pgbouncer:
poolMode: session
type: rw
---
Ресурс PodMonitor
CloudNative-PG поставляется со встроенным экспортером метрик для Prometheus. Ресурс PodMonitor, входящий в API Prometheus Operator, сообщает Prometheus, как обнаруживать и собирать метрики с подов PostgreSQL.
-
.spec.selector.matchLabels: этот селектор выбирает поды, принадлежащие нашему кластеруpostgres. -
.metadata.labels: меткаrelease: kube-prometheus-stackважна — она часто используется Prometheus Operator для обнаружения нужныхPodMonitor-ресурсов. В вашей среде может потребоваться другая метка.
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
annotations:
cnpg.io/operatorVersion: 1.27.0
labels:
cnpg.io/cluster: postgres
release: kube-prometheus-stack # I need this label to allow Prometheus scrape metrics.
name: postgres
spec:
namespaceSelector: {}
podMetricsEndpoints:
- bearerTokenSecret:
key: ""
name: ""
port: metrics
selector:
matchLabels:
cnpg.io/cluster: postgres
cnpg.io/podRole: instance
Шаг 3: Проверка миграции
После применения манифеста CloudNative-PG начнёт подготовку кластера. Следить за прогрессом можно с помощью команды kubectl get cluster postgres -w.
Через несколько минут кластер должен быть готов. Главный вопрос: был ли импорт данных выполнен корректно?
Проверим это. Сначала найдём имя сервиса нового пулера:
kubectl get svc -l cnpg.io/cluster=postgres,cnpg.io/podRole=pooler -o name
Затем запустим временный под с PostgreSQL, подключимся к сервису пулера и воспользуемся psql для проверки базы данных. Оператор создаёт секрет для суперпользователя postgres; по умолчанию он называется postgres-superuser.
# Note: The secret name might be different based on your cluster name.
# It follows the pattern <cluster-name>-superuser.
PGPASSWORD=$(kubectl get secret postgres-superuser --template={{.data.password}} | base64 -d)
# Now connect to the database
kubectl run psql-client --rm -it --image=postgres --command -- psql "postgresql://postgres:${PGPASSWORD}@pooler-postgres-rw:5432/test" -c "\dt"
Эта команда выводит список таблиц в базе данных test. Если вы видите таблицы из исходной базы — поздравляем, импорт прошёл успешно!
Важные замечания
Несколько моментов, о которых стоит помнить:
-
Метки PodMonitor: чтобы ресурс
PodMonitorбыл обнаружен Prometheus, необходимо задать правильные метки. В большинстве стандартных установокkube-prometheus-stackтребуется меткаrelease: kube-prometheus-stack, однако в вашей конфигурации может быть иначе. Всегда проверяйте настройки Prometheus. -
Управление внешними секретами: при указании секретов для внешних кластеров документация CloudNative-PG явно регламентирует ожидаемые ключи (
username,password). Использование других ключей не допускается.
Данное руководство охватывает первоначальный импорт данных — наиболее критичный этап. Для полного переключения в production также потребуется спланировать время простоя приложения, обновить деплойменты приложений, указав новый сервис базы данных (pooler-postgres-rw), и вывести из эксплуатации старый деплой Bitnami.
Заключение
Экосистема облачно-нативных инструментов постоянно развивается, и изменения в каталоге Bitnami лишний раз напоминают о важности опоры на проекты, движимые сообществом. CloudNative-PG — зрелое и мощное решение для запуска PostgreSQL на Kubernetes.
Декларативный API, встроенная высокая доступность и тесная интеграция с экосистемой Kubernetes делают его отличной альтернативой для инженеров платформы (platform engineers), которые ценят гибкость и контроль. Миграция требует тщательного планирования, но результатом становится современная, масштабируемая и удобная в обслуживании инфраструктура базы данных — по-настоящему cloud-native.
Об авторе
Я архитектор платформенной инженерии (Platform Engineer Architect), специализирующийся на облачно-нативных технологиях и инженерном лидерстве. Я фокусируюсь на построении эффективных совместных инженерных процессов и документации. Являюсь Golden Kubestronaut и увлечён Cloud Native технологиями.
Свяжитесь со мной в LinkedIn или напишите мне для получения дополнительной информации.