Cпособ создания ежедневных бэкапов PostgreSQL из Docker Swarm
15 мая 2021 г.
•
8 минут чтения
Как делать резервные копии из PostgreSQL, запущенного в Docker Swarm?
Бэкапы PostgreSQL
У запущенного Docker контейнера всегда есть уникальный идентификатор. Docker Swarm (фактически Docker) запускает сервисы с динамическими идентификаторами.
У Docker есть имя службы с фиксированным именем. Мы можем использовать это имя для получения динамического идентификатора службы.
Вы можете просмотреть список всех сервисов с помощью следующей команды
docker service ls
У меня имя сервиса swarm_postgres. Фактически нам нужно получить ID задачи (контейнера), на которой запущен сервис PostgreSQL. Мы можем сделать это с помощью следующей команды:
docker service ps -f "name=swarm_postgres" swarm_postgres -q --no-trunc | head -n1
Эта команда вернет вам идентификатор задачи (контейнера) Docker Swarm из службы postgres. Например: m4q72hmem43talp8ndxn6a37r
Итак, мы знаем идентификатор контейнера и можем сделать резервную копию PostgreSQL, используя pg_dump
docker exec -t swarm_postgres.1.m4q72hmem43talp8ndxn6a37r pg_dump -U dbusername dbname > dump_dbname.sql
В результате этой команды вы получите файл dump_dbname.sql, содержащий дамп SQL.
Все эти действия можно выполнить с помощью одного bash скрипта. Назовем его postgres-backup.sh
#!/bin/bash
#configuration settings
POSTGRES_USER=dbusername
POSTGRES_DB=dbname
CURRENT_MONTH=$(date +%Y-%m)
CURRENT_DATE=$(date +%Y-%m-%d)
CURRENT_DATETIME=$(date +%d-%b-%Y_%H_%M_%Z)
BACKUPS_PATH=/backups
DOCKER_SWARM_SERVICE_NAME=swarm_postgres
####################################
#backup PostgreSQL database
BACKUP_FOLDER=$BACKUPS_PATH/$CURRENT_MONTH/$CURRENT_DATE
if [ ! -d "$BACKUP_FOLDER" ]; then
mkdir -p "$BACKUP_FOLDER"
fi
echo 'Creating PostgreSQL backups...'
cd "$BACKUP_FOLDER"
if [ -f 'dump_'"$POSTGRES_DB"'.sql' ]; then
rm 'dump_'"$POSTGRES_DB"'.sql'
fi
db_backup_filename=$POSTGRES_DB'_'$CURRENT_DATETIME'.tar.gz'
postgres_container_id=$(docker service ps -f "name=$DOCKER_SWARM_SERVICE_NAME" $DOCKER_SWARM_SERVICE_NAME -q --no-trunc | head -n1)
docker exec -t symfony-blog_postgres.1."$postgres_container_id" pg_dump -U $POSTGRES_USER $POSTGRES_DB > 'dump_'"$POSTGRES_DB"'.sql'
tar -cf - 'dump_'"$POSTGRES_DB"'.sql' | gzip -9 > "$db_backup_filename"
rm 'dump_'"$POSTGRES_DB"'.sql'
cd "$BACKUP_FOLDER"
md5sum * > MD5SUMS
echo 'Done.'
Есть несколько дополнительных действий. Скрипт создает архив tar.gz, создает файл MD5SUMS, содержащий сумму md5 архива.
Вы можете добавить эту команду в cron и запускать ее каждый день. Просто добавьте строку в /etc/crontab
0 8 * * * root /root/postgres-backup.sh
В этом примере я запускаю этот скрипт каждый день в 8 утра.
Удаление устаревших резервных копий PostgreSQL
Через некоторое время у вас будет много архивов с дампами базы PostgreSQL. Они не нужны все. Я предлагаю хранить резервные копии за последние 14 дней.
Есть способ проверить дату создания файла и удалить устаревшие файлы. Мы можем сделать это с помощью bash скрипта. Назовем его postgres-backups-cleaner.sh
#!/bin/bash
EXPIRE_DAYS=14
SCAN_DIR=/backups
FILES=$(find $SCAN_DIR -type f)
for file in $FILES;
do
timestamp=$(date -r $file +%Y%m%d);
echo "Processing $file file..";
date1yrs=$(date -d "$timestamp" +%Y);
date1days=$(date -d "$timestamp" +%j);
date2yrs=$(date +%Y);
date2days=$(date +%j);
diffYear=$(expr "$date2yrs" - "$date1yrs");
diffYear2days=$(expr "$diffYear" \* 365);
diffDays=$(expr "$date2days" - "$date1days");
DAYS=$(expr "$diffYear2days" + "$diffDays");
if [ "$DAYS" -ge $EXPIRE_DAYS ]
then
echo "Deleting $file file...";
rm "$file";
fi
done
Нам нужно запускать этот скрипт ежедневно. Так же, как и с ежедневным бэкапами. Cron - хороший вариант для этого. Отредактируйте файл /etc/crontab и добавьте туда дополнительную строку
0 9 * * * root /root/postgres-backups-cleaner.sh
В этом примере я запускаю этот скрипт каждый день в 9 утра.
Копирование резервных копий в безопасное место
Созданные резервные копии хранятся на хост-машине, на которой запущен Docker Swarm. Будет плохо если что-то случиться с хост-машиной. Можно потерять данные и бэкапы, в том числе.
Я решил копировать бэкапы на домашний компьютер. У меня компьютер работает постоянно. Так что в моем случае это самый дешевый способ хранить бэкапы PostgreSQL. Я добавил cron задачу для копирования бэкапов с хост-машины на мой компьютер с помощью команды rsync
30 21 * * * luxurydab /usr/bin/rsync --progress -zoguhvr --compress-level=9 sshusername@domain.example.com:/backups/ /media/storage/Backups/
Вы можете использовать любое облачное хранилище, такое как Amazon S3, Google Cloud Storage, DigitalOcean Spaces и т. д. Просто добавьте дополнительные действия копирования в bash скрипт создания бекапов.