Репликация и бэкап БД в S3

Запуск БД в Docker и без него. Способы организации репликации. Написание скрипта резервного копирования базы данных PostgreSQL с загрузкой в S3-совместимое файловое хранилище. Эмуляция хранилища для локальной разработки.

  • 00:00:15 Вопрос надёжности хранения
  • 00:02:02 Репликация для PostgreSQL в Docker
  • 00:06:09 Запуск СУБД вне Docker
  • 00:10:13 Использование облачных СУБД
  • 00:16:57 Переименование Cron-сервиса
  • 00:17:22 Уменьшение интервала для docker prune
  • 00:18:33 Выбор хранилища и протокола
  • 00:20:54 Протокол Amazon S3
  • 00:22:01 Консольный клиент aws
  • 00:23:45 Альтернативы от других провайдеров
  • 00:24:57 Создание контейнера для бэкапов
  • 00:27:50 Эмулятор для локальной разработки
  • 00:32:11 Проброс для веб-интерфейса
  • 00:34:50 Автосоздание Bucket в эмуляторе
  • 00:38:00 Docker-сервис для бэкапа
  • 00:41:02 Скрипт резервного копирования
  • 00:48:01 Dockerfile для образа
  • 00:50:26 Проверка backup-скрипта в Jenkins
  • 00:52:54 Запуск по Cron в production
  • 00:57:29 Обзор результата
Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (24)
Руслан

Спасибо!

Ответить
Александр

Спасибо, прям то что нужно.

Ответить
Arunas

Спасибо.

Ответить
Евгений Горяев

Спасибо за видео. Есть только один момент - увидав в заголовке тему про репликацию был очень обнадежен. Однако по видео не понятно, какую проблему решает данный подход кроме резервного копирования данных в реалтайме. Может быть в следующих видосах будет раскрыта пошире эта тема - как сделать эти базы реально безотказными, с выбором мастера, как приложению переключаться на новый мастер, как новую ноду запускать чтобы она как-то влилась в процесс и подцепила бекап и тд. Кажется, эта тема была интересна многим )

Ответить
Дмитрий Елисеев

Полноценная репликация с автопереключением сложнее. Там нужно следить за мастером через repmgr, чтобы в мастер направлять все запросы на запись через балансировщик pgpool. Для этого можно взять такие готовые образы от этого же автора.

А приложение подключать напрямую к балансировщику pgpool.

Ответить
Евгений Горяев

Спасибо за указание нужного направления, ушел курить интернет на эту тему...

Ответить
Yevhenii Lykholai

Одна из некомфортных для меня тем (девопсная), но считаю очень полезным все равно изучать это, так как хорошо расширяет кругозор. Да и взаимодействие с девопсами лучше, когда ты хотя бы отчасти понимаешь их работу.

Спасибо!

Ответить
Bondarenko Alexandr

Вакансии с высокими ценниками часто предполагают, что кандидат будет владеть devops-инструментами. Так что это уж точно не будет лишним

Ответить
slo_nik

Добрый день, Дмитрий.

Всё очень просто и доступно рассказано и показано, спасибо.

Но вот что-то на локалке не могу запустить по cron сохнанение backup-ов (на prod ещё не пробовал)

В crontab записываю команду

1 *  *  *  * sh -c "cd /home/slonik/localhost/www/project && docker-compose run --rm postgres-backup"

но она не срабатывает. Если записать другую команду, например создание файла, то всё работает.

С чем это может быть связано?

Ответить
slo_nik

В общем проблема на рабочем сервере решилась через указание полного пути к docker-compose и sh.

* * * * * /usr/bin/sh -c "cd /home/deploy/site && /usr/local/bin/docker-compose run --rm postgres-backup"

Вот так заработало. OC Ubuntu 20.04 LTS

На локальном не стал возиться с этим вопросом.

Ответить
slo_nik

Добрый вечер, Дмитрий.

Возникла проблема с backup-ами баз данных.

Сделал всё по Вашему уроку.

Поначалу всё работало. Cron команды отрабатывались без проблем в течении недели. Но в последнее время backup-ы перестали создаваться. Если запустить вручную создание backup, то в консоли заканчивается ошибкой

ERROR: pull access denied for slonikkh/project, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

Через playbook выполнил docker-login, скрипт отработал без ошибок, но ситуация не изменилась.

Зашёл на сервер по ssh. Выполнил docker login вручную. После этого начал создаваться backup одной базы данных. Но со второй базы всё равно не создаётся, всё та же ошибка доступа.

В syslog более подробная ошибка.

Sep 16 00:00:01 p586099 CRON[3926]: (root) CMD (/bin/sh -c "cd /home/deploy/site && /usr/local/bin/docker-compose run --rm postgres-backup")
Sep 16 00:00:01 p586099 CRON[3927]: (root) CMD (test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew)
Sep 16 00:00:05 p586099 dockerd[28771]: time="2021-09-16T00:00:05.021889587+03:00" level=error msg="Not continuing with pull after error: errors:\ndenied: requested access to the resource is denied\nunauthorized: authentication required\n"
Sep 16 00:00:05 p586099 dockerd[28771]: time="2021-09-16T00:00:05.022969485+03:00" level=info msg="Ignoring extra error returned from registry: unauthorized: authentication required"
Sep 16 00:00:05 p586099 CRON[3925]: (CRON) info (No MTA installed, discarding output)

В чём может быть причина такого поведения cron команд?

Ответить
Дмитрий Елисеев

В чём может быть причина такого поведения cron команд?

В том, что docker-login выполняется для пользователя deploy, а внешние cron-команды запускаются по умолчанию от root.

Ответить
slo_nik

Возможно я удалил ssh ключ для root, но как и зачем - не помню)

У меня тогда такой вопрос.

В видео про установку jenkins Вы создавали команду cron

0 2 * * * /bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=240h'

Эта команда, насколько я помню, для очистки образов для dind. Все образы, которые будут старше десяти дней будут удалены.

Но она не работает. Пробовал два варианта, с указанием полного пути к sh и docker-compose и без. На ubuntu указание полного пути помогло решить проблему, а вот в debian нет.

Хотя если зайти на сервер по ssh от root и вручную запустить, то она отработает.

В чём может быть причина, что cron команда не работает от root когда её выполняет cron?

Ответить
Дмитрий Елисеев

А какие логи вывоит cron?

Ответить
slo_nik

Вы имеете ввиду syslog?

Ответить
slo_nik

На сервере Debian 10, есть /var/log/faillog и /var/log/lastlog, но не могу прочитать их.

Ответить
Дмитрий Елисеев

Переустановите логи

apt-get install --reinstall rsyslog

и syslog появится.

Ответить
slo_nik

После ввода Вашей команды запустил задание на каждую минуту.

В syslog только такие записи

Oct  5 13:37:01 localhost CRON[19115]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=240h')
Oct  5 13:37:05 localhost crontab[19136]: (root) LIST (root)
Oct  5 13:38:01 localhost CRON[19139]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=240h')
Oct  5 13:39:01 localhost CRON[19162]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=240h')
Oct  5 13:40:01 localhost CRON[19184]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=240h')
Ответить
Дмитрий Елисеев

Значит работает?

Ответить
slo_nik

Вроде нет. Изменил значение until на 72h, запуск каждую минуту. Но ни один из образов, который создался 4 дня назад не удалился.

В логах

Oct  5 13:50:01 localhost CRON[19604]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=72h')
Oct  5 13:50:22 localhost systemd[18891]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.fiJshF.mount: Succeeded.

Oct  5 13:50:22 localhost systemd[1]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.fiJshF.mount: Succeeded.

Oct  5 13:50:33 localhost systemd[18891]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.QTgqHM.mount: Succeeded.

Oct  5 13:50:33 localhost systemd[1]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.QTgqHM.mount: Succeeded.

Oct  5 13:50:52 localhost systemd[18891]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.0voNWp.mount: Succeeded.

Oct  5 13:50:52 localhost systemd[1]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.0voNWp.mount: Succeeded.

Oct  5 13:51:01 localhost CRON[19721]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=72h')
Oct  5 13:52:01 localhost CRON[19744]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=72h')
Oct  5 13:52:09 localhost systemd[18891]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.6n430Q.mount: Succeeded.

Oct  5 13:52:09 localhost systemd[1]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.6n430Q.mount: Succeeded.

Oct  5 13:53:01 localhost CRON[19798]: (root) CMD (/bin/sh -c 'cd /home/deploy/jenkins && /usr/local/bin/docker-compose exec docker docker system prune -af --filter until=72h')
Oct  5 13:53:10 localhost systemd[18891]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.P4Xo2A.mount: Succeeded.

Oct  5 13:53:10 localhost systemd[1]: run-docker-runtime\x2drunc-moby-b0e74389e65a4f346f541552d34d6a3636584021ccd03818d2d606fb45648c3d-runc.P4Xo2A.mount: Succeeded.
Ответить
Дмитрий Елисеев

А какой командой список образов смотрите?

Ответить
slo_nik

docker exec jenkins_jenkins_1 docker images

Ответить
slo_nik

Нашёл решение, правда подсказали.

В конец команды добавил >/tmp/test-cron.log 2>&1

В файле появилась запись

the input device is not a TTY

На stackoverflow подобный вопрос, всё дело в флагах.

После exec необходимо указать флаг -T.

Вроде заработало, старые образы удалились, но будем посмотреть как дальше будет работать.

Ответить
slo_nik

Добрый вечер.

Возникла такая проблема.

Хочу полностью эмулировать работу с облачным хранилищем, но возникла проблема с получением файлов из локального облака.

При настройках nginx, из Ваших уроков, без проблем получается залить какой либо файл в локальное облако.

Но при получении, когда обращаюсь по адресу файла в облаке не всегда получаю файл.

Например

$path = 'http://backup-storage:9000/images/16786445.jpg';
 
$file = file_get_contents($path);

header('Content-Type: image/jpeg');

echo $file; // изображение выводится.

#############

$path = 'http://backup-storage:9000/images/16786445.jpg';

echo "<img src='" . $path . "'>"; // изображение не выводится. Error: NS_ERROR_UNKNOWN_HOST

#############

$path = 'http://172.19.0.5:9000/images/16786445.jpg';

 echo "<img src='" . $path . "'>"; // изображение выводится

 #############

 $path = 'http://localhost:8083/images/16786445.jpg';

 echo "<img src='" . $path . "'>"; // изображение не выводится, при этом ответ сервера 200

Если для последнего примера добавить заголовок с content-type, то ответ сервера тоже будет 200, но на самой странице будет такое сообщение (подставляется в alt img)

Изображение «http://localhost:8087/trade/test» не может быть показано, так как содержит ошибки.

Где искать проблему?

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Yandex
MailRu
GitHub
Google