Управление резервным копированием PostgreSQL через веб-интерфейс: обзор утилиты PG Back Web

Сегодня мы рассмотрим утилиту PG Back Web. Это инструмент для управления резервным копированием PostgreSQL.

Разберём, что умеет это решение и как выглядит его интерфейс. А бонусом покажу примеры развёртывания PG Back Web в Kubernetes.

64dec0475c01e1d3258039238f4f9738.png

О продукте

Open Source-решение PG Back Web используют для настройки резервного копирования и управления восстановлением баз данных, работающих под PostgreSQL. 

В качестве средства самого резервного копирования PG Back Web использует pg_dump (format=plain). При восстановлении используется вызов psql -f.

PG Back Web также включает в себя средства, с помощью которых можно мониторить доступность базы данных и успешность выполнения заданий резервного копирования.

Лицензия: MIT license.

Поддерживаемые СУБД: PostgreSQL 13, 14, 15 и 16-й версий.

Возможности

Ключевые особенности PG Back Web:

  • отлично продуманный веб-интерфейс, о котором расскажем подробнее в следующем блоке;

  • простота развёртывания и настройки;

  • поддержка резервного копирования как в S3-совместимое объектное хранилище, так и в локальный каталог;

  • резервное копирование как по требованию, так и по расписанию;

  • управление жизненным циклом резервных копий;

  • поддержка шифрования собственных чувствительных данных с помощью PGP;

  • мониторинг успешного выполнения резервного копирования;

  • мониторинг доступности PostgreSQL и объектного хранилища;

  • возможность подключения мониторинга к системе управления инцидентами;

  • Cloud Ready: решение полностью готово для развёртывания в Kubernetes.

При этом у данного решения есть и недостатки, так как у него отсутствуют:

  • поддержка резервного копирования PostgreSQL 17 (скоро планируется добавить);

  • многопользовательский режим с разделением прав;

  • возможность управления всеми параметрами вызова pg_dump, в том числе невозможно задать --format=custom;

  • возможность создать резервную копию всех БД экземпляра PostgreSQL средствами pg_dumpall либо pg_basebackup;

  • поддержка pg_basebackup в принципе;

  • возможность организовать PITR;

  • ручные фильтры в списке резервных копий.

Однако я хотел бы отметить, что подавляющее большинство этих недостатков во многом является следствием достоинств решения, а именно — его простоты и универсальности. Используемая модель прекрасно вписывается в идеологию облачных баз данных с подходом «Один экземпляр СУБД = одна база данных». Кроме того, применяемый метод резервного копирования полностью независим от того, где и как развёрнута СУБД и кем она управляется.

Обзор интерфейса

Интерфейс понятен и лаконичен, состоит из основных разделов:

  • Databases

  • Destinations

  • Backups

  • Executions

  • Restorations

  • Webhooks

2dbf030f70717fc8c7fb0dbd0b99aa2a.png

Databases

Раздел для управления соединениями с базами данных:

68a64ef4e1132cc13316b38d382aeab2.png

Через кнопку «Create database» можно добавить новое соединение. В появившейся форме нужно указать имя, версию PostgreSQL и строку подключения:

5e44b4a60d0adfa19fdd336c8ebed884.png

Ещё можно перейти в список резервных копий (Executions), отфильтрованных по нужной базе данных:

84c2c71a696e4f60a085462652d2294a.png

Destinations

Раздел для управления соединениями с объектными хранилищами:

3cfb0b70eb26df0504d4828fe53d719b.png

Через кнопку «Create destination» можно добавить новое соединение. В открывшейся форме нужно указать имя, имя бакета, эндпоинт, регион, ключ доступа и секретный ключ:

c5ae8ed92e22e67e81ee6a561c81399e.png3bbda410363250431b7cd51a77b689e2.png

Backups

Раздел для управления расписаниями резервного копирования:

7e6c7ce1237f7d7764e99caedb633599.png

При создании расписания нужно указать:

  • название задания резервного копирования;

  • выбор одной из настроенных в Databases баз данных;

  • бэкап в локальный каталог или объектное хранилище:

    • если бэкап не локальный, то выбор одного из настроенных в Destinations объектных хранилищ;

    • если локальный, то нужно задать путь к каталогу для бэкапов (Destination directory);

  • расписание в стандартном формате cron;

  • время жизни резервных копий.

Время жизни можно указать только в днях. Проверка на актуальность хранимых бэкапов выполняется при каждом старте. Например, если снятие бэкапа настроено раз в час, а срок хранения бэкапов — 1 день, то при каждом успешном выполнении бэкапа будет удален бэкап, сделанный 25 часов назад.

e9a2437094b4afe1044dd3420457d1a7.pngb9489f77247f19f58b39a18ad7369512.png

 При необходимости можно задать некоторые параметры pg_dump:

017d6325dad0242be1692bc8ac88264d.png

У PG Back Web нет доступа к физическим серверам, и при настройке бэкапа типа Local подразумевается сохранение резервных копий на диск экземпляра самого PG Back Web. При задании Destination directory для бэкапа типа Local задаётся путь к подкаталогу /backups.

Например, если в настройках указан путь:

d05561ec006c2616b89d49bed49117b9.png

…то на диске резервные копии будут храниться здесь:

ls -1 /backups/tmp/tribute/2024/12/27/

dump-20241227-005000-7dc0a663-8562-417c-8be6-f103b71533cd.zip

Если PG Back Web развёрнут в Kubernetes, в каталог /backups должен быть смонтирован volume для хранения дампов.

Из раздела Backups можно вызвать выполнение резервного копирования принудительно, а также перейти в раздел Executions с фильтрацией по конкретному расписанию:

b1f7bed076e56fe6cac9880b9d4a5cf0.png

Executions

Раздел со списком всех вызовов операций резервного копирования и удаления резервных копий:

69b12e06752d54cf050afdf791543440.png

Для операций, завершившихся с ошибкой, можно посмотреть сообщение об ошибке без необходимости обращения к логу пода с приложением:

6713f20ec08cdc4bc01f012cc3f4cc17.png

Кроме того, интерфейс позволяет скачать успешно выполненный дамп:

e7aa0f152bd08b721199c79f037847cb.png

Restorations

Раздел со списком всех вызовов операций восстановления из резервной копии:

a156fb5a9a70f65f322b1ce872f277b2.png

Сама же операция восстановления инициируется из раздела Executions. Для восстановления необходимо выбрать нужную резервную копию, в её контекстном меню выбрать Restore execution и в качестве места назначения восстановления либо выбрать одну из настроенных в разделе Databases БД, либо указать произвольный адрес подключения:

f60b31efd613e2158a240ccba3149506.png

Если PG Back Web развёрнут в Kubernetes, в каталог /tmp должен быть смонтирован volume, так как при восстановлении PG Back Web загружает в этот каталог выбранный дамп, разархивирует его и выполняет вызов вида:

/usr/lib/postgresql/13/bin/psql postgresql://pgbackweb:*******@192.168.199.69:5433/myth -f /tmp/pbw-restore-1423349472/dump.sql

Webhooks

Раздел для настройки мониторинга выполнения резервного копирования, а также для мониторинга доступности баз данных и объектных хранилищ.

7bc5bf2a25171863ccfdac8bd379f337.png

Пример настройки мониторинга доступности базы данных с доставкой информации в систему управления инцидентами:

2dcfdf2ee02a748fff16c8e892d50d69.png79d6a5ed42789c7688138bbaf3cfeb37.pngcbaccbc044e311914ecbabe8887ded71.png

Ошибки выполнения резервного копирования активируют вебхук по факту возникновения инцидента. Проверки доступности баз данных и объектных хранилищ выполняются по расписанию раз в 10 минут.

Для проверки работоспособности резервного копирования, а также для проверки доступности баз данных и объектных хранилищ можно настроить обратную проверку типа Dead Man Switch. Этот механизм подразумевает, что система мониторинга будет получать подтверждение работоспособности каждые 10 минут. Если подтверждение не будет получено в течение установленного времени, система автоматически сгенерирует предупреждение (алерт). Пример настройки DMS:

12f2c9018c27f770207f462cfee6c798.png

Пример развёртывания PG Back Web в Kubernetes

StatefulSet приложения:

apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: pgbackweb
spec:
 serviceName: pgbackweb
 selector:
   matchLabels:
     app: pgbackweb
 replicas: 1
 template:
   metadata:
     labels:
       app: pgbackweb
   spec:
     containers:
     - name: pgbackweb
       image: eduardolat/pgbackweb:0.3.0
       envFrom:
       - secretRef:
           name: pgbackweb
       volumeMounts:
       - name: backup
         mountPath: /backups
       - name: tmp
         mountPath: /tmp
       resources:
         requests:
           cpu: 5m
           memory: 1Gi
         limits:
           memory: 1Gi
       livenessProbe:
         failureThreshold: 3
         httpGet:
           path: /
           port: http
           scheme: HTTP
         initialDelaySeconds: 20
         periodSeconds: 5
         successThreshold: 1
         timeoutSeconds: 2
       readinessProbe:
         failureThreshold: 3
         httpGet:
           path: /
           port: http
           scheme: HTTP
         initialDelaySeconds: 10
         periodSeconds: 5
         successThreshold: 1
         timeoutSeconds: 2
       ports:
       - containerPort: 8085
         name: http
         protocol: TCP
 volumeClaimTemplates:
 - apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: backup
   spec:
     accessModes:
     - ReadWriteOnce
     resources:
       requests:
         storage: 200Gi
     storageClassName: ceph-ssd
     volumeMode: Filesystem
 - apiVersion: v1
   kind: PersistentVolumeClaim
   metadata:
     name: tmp
   spec:
     accessModes:
     - ReadWriteOnce
     resources:
       requests:
         storage: 50Gi
     storageClassName: ceph-ssd
     volumeMode: Filesystem

Secret приложения:

apiVersion: v1
kind: Secret
type: Opaque
metadata:
 name: pgbackweb
data:
  PBW_ENCRYPTION_KEY: bGFjaEFrSm9zZGVkcnlzcHlhSG9sdnl1OUZsaWN5YXA=
  PBW_POSTGRES_CONN_STRING: cG9zdGdyZXNxbDovL3BnYmFja3dlYjppdHNwYXNzd29yZEBwb3N0Z3Jlczo1NDMyL3BnYmFja3dlYj9zc2xtb2RlPWRpc2FibGU=
  TZ: RXVyb3BlL01vc2Nvdw==

В Secret все значения закодированы в Base64. На всякий случай напомню, что при кодировании значений переменных для Secrets в Base64 необходимо убирать символы переноса строки.

Пример:

echo -n "my_secret_string" | base64
bXlfc2VjcmV0X3N0cmluZw==

Service приложения:

apiVersion: v1
kind: Service
metadata:
 name: pgbackweb
spec:
 clusterIP: None
 selector:
   app: pgbackweb
 ports:
 - name: http
   port: 8085

Ingress приложения:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: pgbackweb
spec:
 rules:
 - host: pgbackweb.mydomain.com
   http:
     paths:
     - path: /
       pathType: Prefix
       backend:
         service:
           name: pgbackweb
           port:
             name: http
 tls:
 - hosts:
   -  pgbackweb.mydomain.com
   secretName: pgbackweb-tls

Здесь следует понимать, что ключ шифрования, задаваемый переменной окружения PBW_ENCRYPTION_KEY, служит не для шифрования резервных копий. Он предназначен для шифрования чувствительных данных пользовательских настроек, которые хранятся в служебной базе данных PostgreSQL. Это необходимо, поскольку доступ к служебной базе данных PG Back Web может иметь не только администратор резервного копирования. 

Пример хранения connection string:

postgres=# \c pgbackweb
You are now connected to database "pgbackweb" as user "postgres".
pgbackweb=# select * from databases limit 1;
-[ RECORD 1 ]-----+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
id                | 48844f37-6ed2-4456-b424-252d90a76038
name              | myth
connection_string | \xc30d040703025c1d84c186e9e04e73d2690167eef67bc473e9da442300e2bd3ced1e34d98e67eae0340a6bfc4fd0891e2551e0b6cd3f52878be559a907856a4b3d92d2e2c8d06c69171d8d20ee8c16ef5c81270080010203923a8046d6d264a1d854f24211e95ffcc8a6d8cb4a9cbf3c42edeb868c50111b7b1b
pg_version        | 13
created_at        | 2024-12-19 10:16:33.642688+00
updated_at        | 2024-12-28 05:00:00.028803+00
test_ok           | t
test_error        |
last_test_at      | 2024-12-28 05:00:00.028803+00

Вывод

PG Back Web полностью Cloud Ready, отличается прекрасно продуманным веб-интерфейсом и стабильной работой. Это решение великолепно подойдёт для управления резервным копированием баз данных относительно небольшого размера, работающих под управлением PostgreSQL, то есть в случаях, когда не требуется получения бинарной копии файлов кластера либо задания custom-формата для резервных копий.

P. S.

Читайте также в нашем блоге:

© Habrahabr.ru