Все больше компаний внедряют Kubernetes как из интереса к передовым технологиям, так и в рамках стратегии по трансформации бизнеса. Когда дело касается переноса приложений в контейнеры и инфраструктуру Kubernetes, перед разработчиками и специалистами по эксплуатации встают непростые задачи, если приложения изначально не ориентированы на облако.
Миграция баз данных всегда сопряжена с рисками и простоями для бизнеса. Сегодня я продемонстрирую, насколько легко можно перенести базу данных PostgreSQL в Kubernetes с минимальными простоями. В этом мне поможет дистрибутив Percona для PostgreSQL Operator.
Чтобы воссоздать у себя такую конфигурацию, вам понадобятся:
В моем случае это дистрибутив Percona для PostgreSQL версии 13, установленный на несколько серверов с Linux.
1. Настройте pgBackrest.
# cat /etc/pgbackrest.conf
[global]
log-level-console=info
log-level-file=debug
start-fast=y
[db]
pg1-path=/var/lib/postgresql/13/main
repo1-type=gcs
repo1-gcs-bucket=sp-test-1
repo1-gcs-key=/tmp/gcs.key
repo1-path=/on-prem-pg
archive_mode = on
archive_command = 'pgbackrest --stanza=db archive-push %p'
После изменения конфигурации потребуется перезапуск.
3. Operator требует, чтобы в каталоге данных также находился файл с именем postgresql.conf. Будет достаточно пустого файла:
touch /var/lib/postgresql/13/main/postgresql.conf
4. На источнике необходимо создать пользователя primaryuser, чтобы обеспечить корректную настройку репликации через Operator.
# create user primaryuser with encrypted password '<PRIMARYUSER PASSWORD>' replication;
# create the namespace
kubectl create namespace pgo
# clone the git repository
git clone -b v0.2.0 https://github.com/percona/percona-postgresql-operator/
cd percona-postgresql-operator
# deploy the operator
kubectl apply -f deploy/operator.yaml
2. Измените главный манифест настраиваемого ресурса — deploy/cr.yaml.
...
repoPath: "/on-prem-pg"
...
storages:
my-s3:
type: gcs
endpointUrl: https://storage.googleapis.com
region: us-central1-a
uriStyle: path
verifyTLS: false
bucket: sp-test-1
storageTypes: [
"gcs"
]
kubectl apply -f gcs.yaml
4. Создайте пользователей путем создания секретных объектов: postgres и primaryuser (тот же пользователь, которого мы создали на источнике). См. примеры секретов для пользователей здесь. Пароли должны быть такими же, как на источнике.
kubectl apply -f users.yaml
5. Теперь развернем кластер на Kubernetes, применив манифест cr.yaml:
kubectl apply -f deploy/cr.yaml
kubectl -n pgo logs -f --tail=20 cluster1-5dfb96f77d-7m2rs
2021-07-30 10:41:08,286 INFO: Reaped pid=548, exit status=0
2021-07-30 10:41:08,298 INFO: establishing a new patroni connection to the postgres cluster
2021-07-30 10:41:08,359 INFO: initialized a new cluster
Fri Jul 30 10:41:09 UTC 2021 INFO: PGHA_INIT is 'true', waiting to initialize as primary
Fri Jul 30 10:41:09 UTC 2021 INFO: Node cluster1-5dfb96f77d-7m2rs fully initialized for cluster cluster1 and is ready for use
2021-07-30 10:41:18,781 INFO: Lock owner: cluster1-5dfb96f77d-7m2rs; I am cluster1-5dfb96f77d-7m2rs 2021-07-30 10:41:18,810 INFO: no action. i am the standby leader with the lock 2021-07-30 10:41:28,781 INFO: Lock owner: cluster1-5dfb96f77d-7m2rs; I am cluster1-5dfb96f77d-7m2rs 2021-07-30 10:41:28,832 INFO: no action. i am the standby leader with the lock
Измените какие-нибудь данные на источнике и убедитесь, что они корректно синхронизируются с целевым кластером.
FileNotFoundError: [Errno 2] No such file or directory: '/pgdata/cluster1/postgresql.conf' -> '/pgdata/cluster1/postgresql.base.conf'
Если забыть создать пользователя primaryuser, в логах появится следующее:
psycopg2.OperationalError: FATAL: password authentication failed for user "primaryuser"
Из-за неправильных или отсутствующих параметров доступа к объектному хранилищу возникает следующая ошибка:
WARN: repo1: [CryptoError] unable to load info file '/on-prem-pg/backup/db/backup.info' or '/on-prem-pg/backup/db/backup.info.copy': CryptoError: raised from remote-0 protocol on 'cluster1-backrest-shared-repo': unable to read PEM: [218529960] wrong tag HINT: is or was the repo encrypted? CryptoError: raised from remote-0 protocol on 'cluster1-backrest-shared-repo': unable to read PEM: [218595386] nested asn1 error
HINT: is or was the repo encrypted?
HINT: backup.info cannot be opened and is required to perform a backup.
HINT: has a stanza-create been performed?
ERROR: [075]: no backup set found to restore
Fri Jul 30 10:54:00 UTC 2021 ERROR: pgBackRest standby Creation: pgBackRest restore failed when creating standby
1. Остановите исходный кластер PostgreSQL, чтобы исключить вероятность записи данных во время переключения:
systemctl stop postgresql
2. Сделайте целевой кластер основным. Для этого удалите параметр spec.backup.repoPath и измените значение параметра spec.standby на false в файле deploy/cr.yaml. Затем примените изменения:
kubectl apply -f deploy/cr.yaml
PostgreSQL автоматически перезапустится, а в логах появится следующее:
2021-07-30 11:16:20,020 INFO: updated leader lock during promote
2021-07-30 11:16:20,025 INFO: Changed archive_mode from on to True (restart might be required)
2021-07-30 11:16:20,025 INFO: Changed max_wal_senders from 10 to 6 (restart might be required)
2021-07-30 11:16:20,027 INFO: Reloading PostgreSQL configuration.
server signaled
2021-07-30 11:16:21,037 INFO: Lock owner: cluster1-5dfb96f77d-n4c79; I am cluster1-5dfb96f77d-n4c79
2021-07-30 11:16:21,132 INFO: no action. i am the leader with the lock
В настоящее время Kubernetes становится стандартным механизмом управления инфраструктурой. В связи с этим разработчики и специалисты по эксплуатации часто сталкиваются с задачей миграции, которая обычно превращается в сложный проект. В этой статье продемонстрировано, что миграция базы данных может быть нетрудным мероприятием, которое осуществляется с минимальным временем простоя.
Рекомендуем испробовать решение Operator: см. репозиторий на GitHub и документацию.
Нашли баг или хотите предложить новую возможность для разработки? Отправьте запрос в JIRA.
Общие вопросы можно задавать на форуме сообщества.
Если вы разработчик и хотите внести вклад в проект, ознакомьтесь с инструкцией CONTRIBUTING.md и отправляйте pull-запросы.
В дистрибутиве Percona для PostgreSQL объединены наилучшие компоненты с открытым исходным кодом, необходимые для развертывания СУБД в корпоративной среде. Все компоненты протестированы с точки зрения взаимной совместимости.
Миграция баз данных всегда сопряжена с рисками и простоями для бизнеса. Сегодня я продемонстрирую, насколько легко можно перенести базу данных PostgreSQL в Kubernetes с минимальными простоями. В этом мне поможет дистрибутив Percona для PostgreSQL Operator.
Цель
Для выполнения миграции я буду использовать следующую конфигурацию:- База данных PostgreSQL, развернутая локально или где-то в облаке. Эту базу данных будем называть источником.
- Кластер Google Kubernetes Engine (GKE), на котором будет развернуто решение Percona Operator для управления целевым кластером PostgreSQL и подом pgBackRest.
- Резервные копии и журналы предзаписи PostgreSQL загружаются в какой-либо бакет объектного хранилища (в моем случае — GCS).
- Данные из бакета считываются с помощью пода pgBackRest.
- Этот же под непрерывно восстанавливает данные в кластер PostgreSQL в Kubernetes.
Миграция
Предварительные требованияЧтобы воссоздать у себя такую конфигурацию, вам понадобятся:
- PostgreSQL версии 12 или 13 (нет разницы, где запущена СУБД);
- установленный пакет pgBackRest;
- Google Cloud Storage или любой другой S3-бакет (в моем случае — GCS);
- кластер Kubernetes.
В моем случае это дистрибутив Percona для PostgreSQL версии 13, установленный на несколько серверов с Linux.
1. Настройте pgBackrest.
# cat /etc/pgbackrest.conf
[global]
log-level-console=info
log-level-file=debug
start-fast=y
[db]
pg1-path=/var/lib/postgresql/13/main
repo1-type=gcs
repo1-gcs-bucket=sp-test-1
repo1-gcs-key=/tmp/gcs.key
repo1-path=/on-prem-pg
- Значением параметра pg1-path должен быть путь к каталогу данных PostgreSQL.
- В параметре repo1-type указано GCS, так как мы хотим сохранять резервные копии в этом хранилище.
- В файле /tmp/gcs.key находится ключ, который можно получить через пользовательский интерфейс Google Cloud. Подробнее об этом читайте здесь.
- Резервные копии будут сохраняться в папке on-prem-pg в бакете sp-test-1.
archive_mode = on
archive_command = 'pgbackrest --stanza=db archive-push %p'
После изменения конфигурации потребуется перезапуск.
3. Operator требует, чтобы в каталоге данных также находился файл с именем postgresql.conf. Будет достаточно пустого файла:
touch /var/lib/postgresql/13/main/postgresql.conf
4. На источнике необходимо создать пользователя primaryuser, чтобы обеспечить корректную настройку репликации через Operator.
# create user primaryuser with encrypted password '<PRIMARYUSER PASSWORD>' replication;
Настройка целевого кластера
1. Разверните дистрибутив Percona для PostgreSQL Operator на Kubernetes. Этот процесс подробно описан в документации.# create the namespace
kubectl create namespace pgo
# clone the git repository
git clone -b v0.2.0 https://github.com/percona/percona-postgresql-operator/
cd percona-postgresql-operator
# deploy the operator
kubectl apply -f deploy/operator.yaml
2. Измените главный манифест настраиваемого ресурса — deploy/cr.yaml.
- Я не стал изменять имя кластера и оставил cluster1.
- Кластер будет функционировать в режиме ожидания, то есть он будет синхронизировать данные из бакета GCS. Задайте для параметра spec.standby значение true.
- Настройте GCS. Раздел spec.backup должен выглядеть примерно так (параметры bucket и repoPath имеют те же значения, что и в вышеприведенной конфигурации pgBackrest):
...
repoPath: "/on-prem-pg"
...
storages:
my-s3:
type: gcs
endpointUrl: https://storage.googleapis.com
region: us-central1-a
uriStyle: path
verifyTLS: false
bucket: sp-test-1
storageTypes: [
"gcs"
]
- Я хочу, чтобы в моем кластере PostgreSQL была как минимум одна реплика. Для этого параметру spec.pgReplicas.hotStandby.size нужно присвоить значение 1.
kubectl apply -f gcs.yaml
4. Создайте пользователей путем создания секретных объектов: postgres и primaryuser (тот же пользователь, которого мы создали на источнике). См. примеры секретов для пользователей здесь. Пароли должны быть такими же, как на источнике.
kubectl apply -f users.yaml
5. Теперь развернем кластер на Kubernetes, применив манифест cr.yaml:
kubectl apply -f deploy/cr.yaml
Проверка работоспособности и устранение неполадок
Если все сделано правильно, вы увидите в логах основного пода следующее:kubectl -n pgo logs -f --tail=20 cluster1-5dfb96f77d-7m2rs
2021-07-30 10:41:08,286 INFO: Reaped pid=548, exit status=0
2021-07-30 10:41:08,298 INFO: establishing a new patroni connection to the postgres cluster
2021-07-30 10:41:08,359 INFO: initialized a new cluster
Fri Jul 30 10:41:09 UTC 2021 INFO: PGHA_INIT is 'true', waiting to initialize as primary
Fri Jul 30 10:41:09 UTC 2021 INFO: Node cluster1-5dfb96f77d-7m2rs fully initialized for cluster cluster1 and is ready for use
2021-07-30 10:41:18,781 INFO: Lock owner: cluster1-5dfb96f77d-7m2rs; I am cluster1-5dfb96f77d-7m2rs 2021-07-30 10:41:18,810 INFO: no action. i am the standby leader with the lock 2021-07-30 10:41:28,781 INFO: Lock owner: cluster1-5dfb96f77d-7m2rs; I am cluster1-5dfb96f77d-7m2rs 2021-07-30 10:41:28,832 INFO: no action. i am the standby leader with the lock
Измените какие-нибудь данные на источнике и убедитесь, что они корректно синхронизируются с целевым кластером.
Типичные проблемы
Следующее сообщение об ошибке говорит о том, что вы забыли создать файл postgresql.conf в каталоге данных:FileNotFoundError: [Errno 2] No such file or directory: '/pgdata/cluster1/postgresql.conf' -> '/pgdata/cluster1/postgresql.base.conf'
Если забыть создать пользователя primaryuser, в логах появится следующее:
psycopg2.OperationalError: FATAL: password authentication failed for user "primaryuser"
Из-за неправильных или отсутствующих параметров доступа к объектному хранилищу возникает следующая ошибка:
WARN: repo1: [CryptoError] unable to load info file '/on-prem-pg/backup/db/backup.info' or '/on-prem-pg/backup/db/backup.info.copy': CryptoError: raised from remote-0 protocol on 'cluster1-backrest-shared-repo': unable to read PEM: [218529960] wrong tag HINT: is or was the repo encrypted? CryptoError: raised from remote-0 protocol on 'cluster1-backrest-shared-repo': unable to read PEM: [218595386] nested asn1 error
HINT: is or was the repo encrypted?
HINT: backup.info cannot be opened and is required to perform a backup.
HINT: has a stanza-create been performed?
ERROR: [075]: no backup set found to restore
Fri Jul 30 10:54:00 UTC 2021 ERROR: pgBackRest standby Creation: pgBackRest restore failed when creating standby
Переключение
Все выглядит хорошо — пора сделать переключение. В этой статье я затрагиваю лишь те аспекты, которые непосредственно связаны с базой данных, однако не нужно забывать о необходимости перенастроить приложение, чтобы оно ссылалось на нужный кластер PostgreSQL. Перед переключением приложение рекомендуется остановить.1. Остановите исходный кластер PostgreSQL, чтобы исключить вероятность записи данных во время переключения:
systemctl stop postgresql
2. Сделайте целевой кластер основным. Для этого удалите параметр spec.backup.repoPath и измените значение параметра spec.standby на false в файле deploy/cr.yaml. Затем примените изменения:
kubectl apply -f deploy/cr.yaml
PostgreSQL автоматически перезапустится, а в логах появится следующее:
2021-07-30 11:16:20,020 INFO: updated leader lock during promote
2021-07-30 11:16:20,025 INFO: Changed archive_mode from on to True (restart might be required)
2021-07-30 11:16:20,025 INFO: Changed max_wal_senders from 10 to 6 (restart might be required)
2021-07-30 11:16:20,027 INFO: Reloading PostgreSQL configuration.
server signaled
2021-07-30 11:16:21,037 INFO: Lock owner: cluster1-5dfb96f77d-n4c79; I am cluster1-5dfb96f77d-n4c79
2021-07-30 11:16:21,132 INFO: no action. i am the leader with the lock
Заключение
Развертывание кластеров баз данных и управление ими — непростая задача. Недавно выпущенный дистрибутив Percona для PostgreSQL Operator позволяет автоматизировать операции по настройке и вводу в эксплуатацию PostgreSQL на Kubernetes, превращая это мероприятие в слаженный процесс без лишней головной боли.В настоящее время Kubernetes становится стандартным механизмом управления инфраструктурой. В связи с этим разработчики и специалисты по эксплуатации часто сталкиваются с задачей миграции, которая обычно превращается в сложный проект. В этой статье продемонстрировано, что миграция базы данных может быть нетрудным мероприятием, которое осуществляется с минимальным временем простоя.
Рекомендуем испробовать решение Operator: см. репозиторий на GitHub и документацию.
Нашли баг или хотите предложить новую возможность для разработки? Отправьте запрос в JIRA.
Общие вопросы можно задавать на форуме сообщества.
Если вы разработчик и хотите внести вклад в проект, ознакомьтесь с инструкцией CONTRIBUTING.md и отправляйте pull-запросы.
В дистрибутиве Percona для PostgreSQL объединены наилучшие компоненты с открытым исходным кодом, необходимые для развертывания СУБД в корпоративной среде. Все компоненты протестированы с точки зрения взаимной совместимости.
Миграция PostgreSQL в Kubernetes
Все больше компаний внедряют Kubernetes как из интереса к передовым технологиям, так и в рамках стратегии по трансформации бизнеса. Когда дело касается переноса приложений в контейнеры и...
habr.com