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] deactivatePour 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.confhost 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.confuuidbackups, 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-reposbackups avec : chown backups: /data/borg-reposmv /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-srvborg 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/*.customborg umount /tmp/reposcp 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.exitsudo 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;
exitborg delete --cache-only <repo>
borg break-lock <repo>