ssh admin@bkp-<region>-sinp
sudo -i
useradd backups --create-home --home-dir /home/backups/ --shell /bin/bash
mkdir /home/backups/.ssh ; chmod 700 /home/backups/.ssh
touch /home/backups/.ssh/authorized_keys ; chmod 600 /home/backups/.ssh/authorized_keys
chown -R backups: /home/backups/.ssh
Afin d'autoriser les machines accédant à l'utilsateur admin sur "bkp-srv" à accéder à l'utilisateur backups, nous allons copier le contenu du fichier /home/admin/.ssh/authorized_keys :
cat /home/admin/.ssh/authorized_keys >> /home/backups/.ssh/authorized_keys
ssh backups@bkp-<region>-sinp
Sur l'instance "bkp-srv" hébergeant les dépôts Borg, nous installerons Borg avec Pip afin d’accéder aux dernières versions disponibles rapidement :
ssh admin@bkp-<region>-sinp
sudo -i
apt install python3 python3-pip python3-virtualenv openssl libssl-dev libacl1-dev libacl1 build-essential pkg-config fuse3 libfuse3-dev
apt install python3 python3-pip python3-virtualenv openssl libssl-dev libacl1-dev libacl1 build-essential pkg-config fuse libfuse-dev
virtualenv --python=python3 borg-env
source borg-env/bin/activate
pip install -U pip setuptools wheel
pip install borgbackup[pyfuse3]
pip install borgbackup[llfuse]
deactivate
Pour accéder à Borg sans activer l'environnement virtuel :
mkdir ~/bin
vi ~/.profile
# Set PATH here to include user's private bin for SSH login # It's necessary for using Borg ! if [[ -d "${HOME}bin" && ":$PATH:" != *":${HOME}bin:"* ]] ; then PATH="${HOME}bin:${PATH}" fi
# Set PATH here to include user's private bin for SSH login # It's necessary for using Borg ! if [[ -d "/root/bin" && ":$PATH:" != *":/root/bin:"* ]] ; then PATH="/root/bin:${PATH}" fi
deactivate
source ~/.bashrc
ln -s ~/borg-env/bin/borg ~/bin/borg
borg --version
source borg-env/bin/activate
pip install -U borgbackup[pyfuse3]
pip install -U borgbackup[llfuse]
Le dépôt Borg étant distant (hébergé sur l'instance "bkp-srv"), il est nécessaire de créer un clé SSH pour l'utilisateur admin (qui héberge les containers Docker). La clé publique générée sera ensuite copier ans le fichier ~/.ssh/authorized_keys de l'utilisateur backups de l'instance "bkp-srv" afin d'autoriser l'accès au dépôt depuis l'instance à sauvegarder.
ssh admin@<instance>-<region>-sinp
ssh-keygen
scp -P <port-ssh-bkp-srv> ~/.ssh/id_rsa.pub geonat@bkp-<region>-sinp:~/.ssh/id_rsa.<instance>-srv.pub
ssh admin@bkp-<region>-sinp
sudo -i
cat /home/geonat/.ssh/id_rsa.<instance>-srv.pub >> /home/backups/.ssh/authorized_keys
ssh -p <port-ssh-bkp-srv> backups@bkp-<region>-sinp
rm -f /home/geonat/.ssh/id_rsa.<instance>-srv.pub
touch ~/.ssh/config; chmod 644 ~/.ssh/config ; vi ~/.ssh/config
Host *
ServerAliveInterval 240
ssh -p <port-ssh-bkp-srv> backups@bkp-<region>-sinp
mkdir -p ~/docker/borgmatic/data/.ssh
sudo cp -r ~/.ssh/ ~/docker/borgmatic/data/
sudo chown root: -R ~/docker/borgmatic/data/.ssh
~/docker/borgmatic/data/.ssh
.vi postgresql.conf
/16
un ensemble d'IP privé qui devrait convenir dans la plupart des cas. Si nécessaire vérifier l'IP obtenu par votre container à l'aide de Portainer par exemple. Pour éditer la config de Postgresql : vi pg_hba.conf
host geonature2db geonatadmin 172.18.5.1/16 scram-sha-256 host gnatlas geonatadmin 172.18.5.1/16 scram-sha-256 # Voir s'il n'est pas possible d'utiliser l'utilisateur geonatadmin à la place de postgres... host gnatlas postgres 172.18.5.1/16 trust host geonature2db postgres 172.18.5.1/16 trust
systemctl edit postgresql@.service
[Unit] After=docker.service
vi /etc/systemd/system/postgresql@.service.d/override.conf
uuid
backups
, créer le dossier qui contiendra les dépôts : sudo -i ; su - backups ; mkdir ~/<instance>-srv
ssh admin@<instance>-<region>-sinp
BORG_PASSPHRASE
: vi ~/docker/borgmatic/.env
docker exec -it borgmatic /bin/bash
ssh -p <port-ssh-bkp-srv> backups@<bkp-srv-private-ip>
borgmatic init --encryption repokey-blake2
borg info ssh://backups@10.0.1.30:<ssh-port-bkp-srv>/home/backups/db-srv/
borg info ssh://backups@10.0.1.30:<ssh-port-bkp-srv>/home/backups/web-srv/
borg info /mnt/borg-repository
borg key export ssh://backups@10.0.1.30:<ssh-posrt-bkp-srv>/home/backups/db-srv/ /root/.config/borg/db-srv-dist.repo-conf-file.txt ; cat /root/.config/borg/db-srv-dist.repo-conf-file.txt
borg key export /mnt/borg-repository /root/.config/borg/db-srv-local.repo-conf-file.txt ; cat /root/.config/borg/db-srv-local.repo-conf-file.txt
borg key export ssh://backups@10.0.1.30:<ssh-posrt-bkp-srv>/home/backups/web-srv/ /root/.config/borg/web-srv-dist.repo-conf-file.txt ; cat /root/.config/borg/web-srv-dist.repo-conf-file.txt
borg key export /mnt/borg-repository /root/.config/borg/web-srv-local.repo-conf-file.txt ; cat /root/.config/borg/web-srv-local.repo-conf-file.txt
/data
, il peut être intéressant de déplacer via un lien symbolique les dépôts Borg créés :mkdir /data/borg-repos
backups
avec : chown backups: /data/borg-repos
mv /home/backups/*-srv /data/borg-repos/
ln -s /data/borg-repos/web-srv /home/backups/web-srv ; ln -s /data/borg-repos/db-srv /home/backups/db-srv
borg info ssh://backups@10.0.1.30:<ssh-posrt-bkp-srv>/home/backups/web-srv/
borgmatic --verbosity 2 --stats --files
S'il s'avérait nécessaire de réinitialiser un dépôt, la démarche à suivre est la suivante :
borgmatic list
borgmatic borg delete <repo>
borgmatic borg delete /mnt/borg-repository/
borgmatic borg delete
. La commande devrait demander confirmation de la suppression de chaque dépôt. borgmatic init --encryption repokey-blake2
borgmatic list
Accéder au container borgmatic pour vérifier et tester son contenu : docker exec -it borgmatic /bin/bash
echo "THIS IS A TEST EMAIL sended to adminsys at $(date "+%F %H:%M")" | mail -s "[${HOSTNAME}] Test email" adminsys@<domaine-sinp>
echo "THIS IS A TEST EMAIL sended to root at $(date "+%F %H:%M")" | mail -s "[${HOSTNAME}] Test email" root
telegram-send "Test at `date`"
borgmatic config validate
(anciennement validate-borgmatic-config
) borgmatic --verbosity 2 --stats --files
vi /etc/cron.d/borgmatic
PGPASSWORD=<password-geonatadmin> pg_dump --verbose --no-password --clean --if-exists --host 172.18.5.1 --port 5432 --username geonatadmin --format custom geonature2db > /root/geonature2db
Configurer Telegram pour l'utiliser avec Ntfy
ou le script telegram-send
et envoyer des alertes à l'aide de Borgmatic.
Ntfy nécessite d'autoriser manuellement un bot après chaque build/lancement d'un container. Ce n'est pas très pratique. Il vaut mieux utiliser le script telegram-send
à la place.
/newbot
<region> SINP Alert Bot
<region>SinpAlertBot
/mybots
<region>SinpAlertBot
telegram-send
peut être utilisé pour envoyer des messages directement à un utilisateur ou à un canal (=group) <region>SinpAlertBot
au canal docker-compose down ; docker-compose up -d
docker exec -it borgmatic /bin/bash
telegram-send "Test at `date`"
docker exec -it borgmatic /bin/bash
ntfy -b telegram send "Telegram configured for ntfy"
/start
ntfy -b telegram -t Borgmatic send "Borgmatic: test at `date` on ${HOSTNAME} !"
ssh admin@<instance>-<region>-sinp
cd ~/docker/borgomatic
docker compose down
sudo rm -fR /tmp/restore ; mkdir /tmp/restore
docker compose -f docker-compose.yml -f docker-compose.restore.yml run -v /tmp/restore:/tmp/restore borgmatic
borg list /home/backups/db-srv
borg list /home/backups/web-srv
mkdir /tmp/repo
mkdir /tmp/restore
borg mount <repo> /tmp/repo
borg mount /home/backups/db-srv /tmp/repo
web-srv-2021-05-17T13:57:02
cp -r "/tmp/repo/web-srv-2021-05-17T13:57:02/mnt/source/etc/cron.d/" /tmp/restore/$(date +'%Y-%m-%d')_gnatlas.custom
cp -r /tmp/repo/db-srv-2022-04-08T01\:07\:55/root/.borgmatic/postgresql_databases/172.18.5.1/geonature2db /tmp/restore/$(date +'%Y-%m-%d')_geonature2db.custom
ls -al /tmp/restore
chmod 644 /tmp/restore/*.custom
borg umount /tmp/repo
scp admin@bkp-<region>-sinp:/tmp/restore/*.custom ./
borgmatic extract
extrait par défaut une archive ou un chemin particulier dans le dossier courant : cd /tmp/restore
--destination
pour préciser l'emplacement de destination. borgmatic list
borgmatic extract --repository <repo> --archive "<archive-name>" --destination /tmp/restore
borgmatic extract --repository /mnt/borg-repository --archive "web-srv-2021-05-17T13:57:02" --destination /tmp/restore
--path
avec le chemin du dossier sans slash au début. Ex. : borgmatic extract --repository /mnt/borg-repository --archive "web-srv-2021-05-17T13:57:02" --path "mnt/source/etc" --destination /tmp/restore
/tmp/restore/
(si le dossier d'extraction est /tmp/restore/
) : /tmp/restore/mnt/…
/tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/..
exit
sudo cp -r /tmp/restore/cron.d/ /etc/
rm -fR /tmp/restore
${VOLUME_SOURCE}:/mnt/source
afin de remplacer les fichiers de l'hôte directement depuis le shell interactif. borgmatic list
borgmatic restore --repository <repo> --archive <archive> --database <db-name>
borgmatic restore --repository /mnt/borg-repository/ --archive "db-srv-2021-05-17T01:00:02" --database geonature2db
--no-password
et lancer la commande manuellement. Des erreurs plus détaillées s'afficheront.exit
sudo cp /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/geonature2db "/tmp/$(date +'%Y-%m-%d')_geonature2db.custom"
sudo chown admin: "/tmp/$(date +'%Y-%m-%d')_geonature2db.custom"
scp admin@db-<region>-sinp:/tmp/$(date +'%Y-%m-%d')_geonature2db.custom ./
docker compose up -d
borg break-lock <repo>
/tmp/restore
comme indiqué ci-dessus.borgmatic extract --repository ssh://backups@10.0.1.30:<port-ssh-bkp-srv>/home/backups/db-srv/ --archive "db-srv-2021-05-19T16:09:01" --destination /tmp/restore
psql -U postgres -h 172.18.0.1 -d gnatlas -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'geonature2db' ; "
psql -U postgres -h 172.18.0.1 -d gnatlas -c "DROP DATABASE geonature2db;"
psql -U postgres -h 172.18.0.1 -d gnatlas -c "CREATE DATABASE geonature2db;"
pg_restore --if-exists --exit-on-error --clean --dbname geonature2db --host 172.18.0.1 --port 5432 --username postgres /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/geonature2db
Si nécessaire, il est aussi possible de manipuler les éléments à restaurer :
pg_restore --list /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/geonature2db > gn2.list
vi gn2.list
EXTENSION
puis enregistrer et quitter.pg_restore --if-exists --exit-on-error --clean --dbname geonature2db --host 172.18.0.1 --port 5432 --username postgres --use-list gn2.list /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/geonature2db
En fonction du format de sauvegarde de la base et de l'utilisateur qui l'effectue, la restauration de la base de données ne pourra pas se faire avec la commande borgmatic restore
. La base gnatlas contient des vues matérialisées qui posent problèmes car elles sont basées sur des tables "étrangères" (FDW). Or, les informations du Foreign Data Wrapper ne sont pas correctement restaurées (utilisateur, mot de passe) par pg_restore quand la sauvegarde est au format "directory". Avec la version 13+ de Postgresql ce comportement devrait être amélioré. Du coup, la restauration par borgmatic ne fonctionne pas et celle par pg_restore échoue si l'on ne supprime pas les requêtes de rafraîchissement des VM car les tables FDW ne contiennent pas de données et le rafraîchissement des vues échoue.
/tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/gnatlas
psql -U postgres -h 172.18.0.1 -p 5432 -d gnatlas -f "/tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/gnatlas"
pg_restore --list /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/gnatlas | grep -v "MATERIALIZED VIEW DATA" > without_refresh.list
without_refresh.list
: pg_restore --if-exists --exit-on-error --clean --dbname gnatlas --host 172.18.0.1 --port 5432 --username postgres --use-list without_refresh.list /tmp/restore/root/.borgmatic/postgresql_databases/172.18.0.1/gnatlas
sudo -u postgres -s psql -d gnatlas -c "ALTER USER MAPPING FOR geonatadmin SERVER geonaturedbserver OPTIONS (ADD user 'geonatadmin');"
sudo -u postgres -s psql -d gnatlas -c "ALTER USER MAPPING FOR geonatadmin SERVER geonaturedbserver OPTIONS (ADD password '<pwd>');"
psql -h localhost -U geonatadmin -d gnatlas -f /home/geonat/data/atlas/data/sql/02_refresh_mv_data.sql
Si besoin, pour voir ce qui existe dans la base concernant FDW:
sudo -u postgres -s psql -d gnatlas
SELECT * FROM pg_foreign_server;
SELECT um.*,rolname FROM pg_user_mapping um JOIN pg_roles r ON r.oid = umuser JOIN pg_foreign_server fs ON fs.oid = umserver;
exit
borg delete --cache-only <repo>
borg break-lock <repo>