Info
Content

Borgmatic

Borgmatic это обертка вокруг Borg
В документации Borg есть такой раздел https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups, в нем предоставлен скрипт для автоматизации бэкапирования
По сути Borgmatic это и есть подобный скрипт - красивая запускалка для Borg


Можно установить через пакетный менеджер
Установится скорее всего старая версия в которой нет команды borgmatic config generate
Надо использовать отдельный скрипт generate-borgmatic-config (он уже идет в пакете borgmatic)

Запускаем:

root@borg-server:~# generate-borgmatic-config
Generated a sample configuration file at /etc/borgmatic/config.yaml.

Please edit the file to suit your needs. The values are representative.
All fields are optional except where indicated.

If you ever need help: https://torsion.org/borgmatic/#issues

Получаем огромный конфиг в котором все закомментировано и прокомментировано
То есть мы получаем базу на основе которой можно собирать свой конфиг


Ansible Playbook

Предлагаю использовать следующий плейбук

---

- name: Borg
  hosts: all
  become: true
  vars:
    borg_data_dir: /opt/data/borg
    borg_encryption_passphrase: CHANGEME
    borg_repository: "root@{{ hostvars[groups['borg'][0]].ansible_host }}:{{ borg_data_dir }}/{{ inventory_hostname }}"
    borg_ssh_key_file_path: "/root/.ssh/id_ed25519"
    borg_ssh_command: "ssh -o StrictHostKeyChecking=accept-new"
    borg_install_method: "pip"
      #    borg_source_directories: # this overrides values from inventory
      #      - /home
      #      - /etc
    borg_exclude_patterns:
      - "{{ borg_data_dir }}"
  tasks:
    - name: "Ensure {{ borg_data_dir }} exists"
      ansible.builtin.file:
        path: "{{ borg_data_dir }}"
        state: directory
        mode: "0755"
        owner: root
      tags:
        - never
        - backup_init_repo

    - name: Configure Borgbackup and Borgmatic
      tags:
        - always
        - install_backup
      ansible.builtin.include_role:
        name: borgbase.ansible_role_borgbackup
        apply:
          tags:
            - always
    - name: Copy SSH-Key to Target {{ borg_repository }} and Init Repo
      tags:
        - never
        - backup_init_repo
      block:
        - name: Read ssh key
          ansible.builtin.slurp:
            src: "{{ borg_ssh_key_file_path }}.pub"
          register: backup_local_ssh_key

        - name: Set authorized key taken from file
          ansible.posix.authorized_key:
            user: "{{ borg_repository | regex_search('(.*)@', '\\1') | first }}" # part a)
            state: present
            key_options: "command=\"borg serve --restrict-to-path {{ borg_data_dir }}\",restrict"
            key: "{{ backup_local_ssh_key['content'] | b64decode }}"
            comment: "{{ inventory_hostname }}"
          delegate_to: "{{ borg_repository | regex_search('@(.*):', '\\1') | first }}" # part b)

        - name: Init repository
          ansible.builtin.command:
            cmd: "sudo -u root borgmatic init --encryption none --append-only"

Ansible Inventory

Инвентори для этого плейбука прост (в базовом случае)
Главное определить группу borg и один хост в ней
Этот хост будет хранить бэкапы
Группа nodes может называться как угодно, потому что плейбук катится на all и использует хост из borg как адрес borg_repository в конфиге borgmatic

Ниже пример ini-inventory:

[borg] # хост из этой группы будет Borg-сервером
borg-server ansible_host=62.84.119.86

[nodes] # не важно как называется эта группа, плейбук катится на 'all'
borg-client-1 ansible_host=51.250.87.234
borg-client-2 ansible_host=51.250.66.184
borg-client-3 ansible_host=51.250.6.55

В самом низу страницы описан пример yaml-inventory который позволяет прописать кастомные параметры разным хостам (можно сделать и полноценный инвентори с host_vars/group_vars, тут как душе угодно)

Commands

Прикатить это все можно так
Сперва установим официальную роль конкретной версии (в моем случае были машины с ubuntu-18, актуальная версия роли не катится на такое старье):

ansible-galaxy role install borgbase.ansible_role_borgbackup,v0.9.4 --force # в моем случае были машины с ubuntu 18.04, поэтому пришлось использовать старую версию роли (новая не катится на такие старые машины)

Далее катим плейбук сперва базово, потом с тэгом который синхронизирует ssh-ключ и создаст репы на сервере из группы borg:

ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook -i inventory.mkrf-test.yaml -kK playbook.yaml
ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook -i inventory.mkrf-prod.yaml -kK -t backup_init_repo playbook.yaml

Что бэкапить задается через переменную borg_source_directories


Проверка:

root@mon-01:~# borgmatic
Fri Dec 22 17:44:08 MSK 2023 - Starting backup.
Fri Dec 22 17:44:08 MSK 2023 - Run pg_dumpall command.
could not change directory to "/root": Permission denied
Fri Dec 22 17:44:37 MSK 2023 - Command pg_dumpall is done.
Ignoring check_last option, as "archives" is not in consistency checks.
Ignoring consistency prefix option, as "archives" is not in consistency checks.
Fri Dec 22 18:32:27 MSK 2023 - Remove pg_dumpall file.
Fri Dec 22 18:32:27 MSK 2023 - Finished backup.

root@mon-01:~# cat /etc/cron.d/borgmatic
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
#Ansible: borgmatic
53 4 * * * root borgmatic -c /etc/borgmatic/config.yaml -C -p
#Ansible: borgmatic-check
53 22 27 * * root borgmatic -c /etc/borgmatic/config.yaml -k
root@vm-bkpp-01:~# du -sch /opt/data/borg/vm-mon-01/
18G	/opt/data/borg/vm-mon-01/
18G	total

root@vm-bkpp-01:~# borg list /opt/data/borg/vm-mon-01/
Warning: Attempting to access a previously unknown unencrypted repository!
Do you want to continue? [yN] y
mon-01-2023-12-22-174440     Fri, 2023-12-22 17:44:41 [dd517ed98188876bc68704f5882c1610421aa9e742584ee4acb27ff8e5ab7a89]

root@vm-bkpp-01:~# borg list /opt/data/borg/vm-mon-01/::mon-01-2023-12-22-174440 | head
drwxr-xr-x root   root          0 Fri, 2023-12-22 17:39:38 etc
drwxr-xr-x root   root          0 Tue, 2019-12-03 12:12:55 etc/update-manager
-rw-r--r-- root   root        235 Thu, 2019-06-06 21:46:11 etc/update-manager/meta-release
-rw-r--r-- root   root        807 Wed, 2019-06-19 19:49:56 etc/update-manager/release-upgrades
drwxr-xr-x root   root          0 Wed, 2019-06-19 19:49:56 etc/update-manager/release-upgrades.d
drwxr-xr-x root   root          0 Tue, 2019-12-03 11:54:23 etc/update-notifier
-rw-r--r-- root   root          0 Tue, 2019-12-03 11:54:23 etc/update-notifier/hooks_seen
drwxr-xr-x root   root          0 Tue, 2019-12-03 11:53:08 etc/gss
drwxr-xr-x root   root          0 Fri, 2019-01-11 18:48:01 etc/gss/mech.d
drwxr-xr-x root   root          0 Tue, 2019-12-03 11:53:22 etc/polkit-1

Ansible Inventory YAML

borg:
  hosts:
    vm-bkp-01:
      ansible_host: 192.168.50.140
nodes:
  hosts:
    grun-01:
      ansible_host: 192.168.50.129
    vm-db-01:
      ansible_host: 192.168.50.124
      borgmatic_hooks:
        on_error:
          - echo "`date` - Error while creating a backup."
        before_backup:
          - echo "`date` - Starting backup."
          - echo "`date` - Run pg_dumpall command."
          - mkdir -p /tmp/pg_dumpall; chmod 777 /tmp/pg_dumpall; sudo -u postgres pg_dumpall -f "/tmp/pg_dumpall/`hostname`_`date +%d-%m-%Y`_dumpall.sql"
          - echo "`date` - Command pg_dumpall is done."
        after_backup:
          - echo "`date` - Remove pg_dumpall file."
          - rm /tmp/pg_dumpall/`hostname`_`date +%d-%m-%Y`_dumpall.sql
          - echo "`date` - Finished backup."
      borg_source_directories:
        - /etc/
        - /home/
        - /tmp/pg_dumpall/
    vm-docs-01:
      ansible_host: 192.168.50.125
      borg_source_directories:
        - /etc/
        - /home/
        - /opt/
    vm-glog-01:
      ansible_host: 192.168.50.127
      borgmatic_hooks:
        on_error:
          - echo "`date` - Error while creating a backup."
        before_backup:
          - echo "`date` - Starting backup."
          - echo "`date` - Run mongodump command."
          - mkdir -p /tmp/mongodump; chmod 777 /tmp/mongodump; mongodump --gzip --archive=/tmp/mongodump/`hostname`_`date +%d-%m-%Y`_mongodump.gz
          - echo "`date` - Command mongodump is done."
        after_backup:
          - echo "`date` - Remove mongodump file."
          - rm /tmp/mongodump/`hostname`_`date +%d-%m-%Y`_mongodump.gz
          - echo "`date` - Finished backup."
      borg_source_directories:
        - /etc/
        - /home/
        - /tmp/mongodump/
        - /usr/share/elasticsearch/
        - /usr/share/graylog-server/
    vm-k8sm-01:
      ansible_host: 192.168.50.121
    vm-k8sw-01:
      ansible_host: 192.168.50.122
    vm-k8sw-02:
      ansible_host: 192.168.50.123
    vm-mon-01:
      ansible_host: 192.168.50.128
      borgmatic_hooks:
        on_error:
          - echo "`date` - Error while creating a backup."
        before_backup:
          - echo "`date` - Starting backup."
          - echo "`date` - Run pg_dumpall command."
          - mkdir -p /tmp/pg_dumpall; chmod 777 /tmp/pg_dumpall; sudo -u postgres pg_dumpall -f "/tmp/pg_dumpall/`hostname`_`date +%d-%m-%Y`_dumpall.sql"
          - echo "`date` - Command pg_dumpall is done."
        after_backup:
          - echo "`date` - Remove pg_dumpall file."
          - rm /tmp/pg_dumpall/`hostname`_`date +%d-%m-%Y`_dumpall.sql
          - echo "`date` - Finished backup."
      borg_source_directories:
        - /etc/
        - /home/
        - /var/lib/grafana/
        - /tmp/pg_dumpall/
        - /opt/
      borg_exclude_patterns:
        - /opt/data/

    vm-mq-01:
      ansible_host: 192.168.50.126
all:
  vars:
    ansible_user: user # от этого пользователя ансибл спросит пароль
    borg_source_directories:
      - /etc
      - /home
No Comments
Back to top