backups_role
Роль резервного копирования
Стратегии резервного копирования и восстановления для проектов Coopdevs.
Требования
Эта роль использует Restic с помощью restic-ansible
Переменные роли
# Версия Restic
backups_role_restic_version: '0.16.4'
# Местоположение скриптов
backups_role_path: '/opt/backup'
backups_role_script_dir: "{{ backups_role_path }}/bin"
# Перенаправляемое имя шаблона для генерации
#+ скрипта "prepare", который будет вставлен внутри
#+ сгенерированного скрипта `backups_role_script_path`
backups_role_script_prepare_template: "cron-prepare.sh.j2"
# Если вы изменяете backups_role_script_prepare_template, это означает, что вы не используете
#+ шаблон по умолчанию и, следовательно, нам не нужно создавать роли postgres и т.д.
#+ и вам, возможно, не нужны права sudo для tar. Поэтому по умолчанию мы отключаем
#+ соответствующие задачи. Однако, если вы хотите включить эти задачи,
#+ установите соответствующие переменные в true:
backups_role_postgresql_enabled:
backups_role_sudoers_enabled:
# Полный путь к сгенерированному скрипту, сформированному из главного, подготовительного и загрузочного.
backups_role_script_path: "{{ backups_role_script_dir }}/backup.sh"
# Местоположение файлов, генерируемых cron заданиями
backups_role_tmp_path: '/tmp/backups'
# Списки путей для резервного копирования
backups_role_assets_paths: []
# Системный пользователь, его основная группа и дополнительные.
#+ Кто будет запускать скрипты, restic и cron задания
#+ и владеть директориями и файлами
backups_role_user_name: 'backups'
backups_role_user_group: 'backups'
backups_role_user_groups: ''
# Внутренняя роль PostgreSQL с доступом только для чтения для выполнения дампа
backups_role_postgresql_user_name: "{{ backups_role_user_name }}"
# Внутренняя администраторская роль Postgres
postgresql_user: "postgres"
backups_role_db_names: [ "postgres" ]
# Имя репозитория Restic, используемое только в случае
#+ если нам нужно обратиться к различным репозиториям restic
backups_role_restic_repo_name: {{ escaped_inventory_hostname }}
#########################################
### ВНИМАНИЕ! Чувствительные переменные ниже ###
#########################################
### Рекомендуется разместить их внутри ###
### ansible-vault. Например, смотрите ###
### defaults/secrets.yml.example ###
#########################################
# Пароль для непривилегированного пользователя для резервного копирования PostgreSQL
backups_role_postgresql_user_password:
# Пароль для репозитория Restic. Новый пароль, который вы предоставляете для шифрования резервных копий.
backups_role_restic_repo_password:
# URL удаленного хранилища в формате restic
# Пример для Backblaze: "b2:bucketname:path/to/repo". Возможно, что
# "b2:bucketname:/" будет работать для вас.
# Пример для локального репозитория: "/var/backups/repo"
backups_role_restic_repo_url:
# Ключ приложения Backblaze, ограниченный для указанного выше хранилища
# Подробности смотрите в примере файла секретов и
# на https://gitlab.com/coopdevs/b2-bucket-and-key
backups_role_b2_app_key_id:
backups_role_b2_app_key:
Зависимости
Использование
Вам нужно подготовить инвентарь для ваших хостов с вышеуказанными переменными. Например, в inventory/hosts
Образец плейбука PostgreSQL с резервным копированием
# playbooks/main.yml
---
- name: Установить PostgreSQL с автоматическим резервным копированием
hosts: servers
become: yes
roles:
- role: geerlingguy.postgresql
- role: coopdevs.backups_role
Плейбук для восстановления резервной копии на контроллер
# playbooks/restore.yml
---
- name: Восстановить резервную копию локально
hosts: servers
connection: local
tasks:
- import_role:
name: coopdevs.backups_role
tasks_from: restore-to-controller.yml
Плейбук для восстановления резервной копии на хост
# playbooks/restore-in-situ.yml
---
- name: Восстановить резервную копию на хост
hosts: servers
tasks:
- import_role:
name: coopdevs.backups_role
tasks_from: restore-to-host.yml
Восстановление снимка с использованием плейбука из выше
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servers
Этот плейбук не установит никаких двоичных файлов глобально, но все же требует прав администратора. Поэтому вам может потребоваться ввести пароль sudo:
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servers --ask-become-pass
По умолчанию он создает директорию с restic и удобным оберткой и восстанавливает последний снимок. Наконец, он безопасно удаляет обертку, поскольку она содержит учетные данные, которые мы не хотим оставлять. Однако, если вы предпочитаете установить обертку и использовать ее вручную, вы можете запустить плейбук с помощью тега install
:
ansible-playbook playbooks/restore.yml -i inventory/hosts -l servers --tags install
Пользовательский скрипт резервного копирования
Когда ваше приложение не использует PostgreSQL или скрипт резервного копирования не соответствует вашим требованиям, вы можете предоставить свой, передав новый шаблон в backups_role_script_prepare_template
. Вы можете использовать те же вспомогательные методы log
и run
, указанные в cron-main.sh.j2. Вы можете ссылаться на любые переменные, которые могли быть указаны в декларации include_role
.
Загрузка резервной копии в объектное хранилище не может быть настроена, и поэтому вам по-прежнему нужно указать пути, где ваш скрипт оставляет файлы резервных копий, с помощью backups_role_assets_paths
. Да, эта переменная должна называться как-то вроде backups_role_file_to_upload
или подобным образом :shrug:. Смотрите cron-upload.sh.j2 для подробностей.
Обратите внимание, что, хотя в этом случае это не применяется, эта переменная также используется в cron-prepare.sh для перечисления файлов для резервного копирования, и это может быть очень запутанным. У нее два разных использования.
См. https://github.com/coopdevs/donalo/pull/82 или https://gitlab.com/coopdevs/odoo-provisioning/-/tree/master/roles/backups для примеров, готовых к производству.
Чувствительные переменные
Пожалуйста, защитите как минимум переменные ниже "чувствительных переменных". Для этого используйте Ansible Vault для шифрования с помощью пароля конфигурационного файла с этими переменными.
Backblaze
Backblaze предоставляет два типа ключей: учетный или основной и ключ приложения. Существует только один ключ учетной записи, и у него есть полномочия над всеми другими ключами и всеми хранилищами. Мы можем иметь много ключей приложений, которые могут иметь доступ на чтение и запись ко всем или именно к одному хранилищу.
Мы не должны использовать ключ учетной записи для доступа к хранилищу или повторно использовать ключи приложений. Даже если пароли restic разные, и хранилища разные, один сервер может быть в состоянии удалить резервные копии других или даже создать больше хранилищ, заполнить их и ухудшить положение дел.
Поэтому мы используем ключи приложений вместо основного ключа. Согласно ansible-restic
, он просто передает учетные данные restic, независимо от типа ключа. На самом деле, мы устанавливаем ansible-restic
's b2_account_key
(рекомендуется использовать основной ключ) с backup-role
's backups_role_b2_app_key
(рекомендуется использовать ключ приложения).
То, что restic называет "ключом учетной записи", на веб-сайте B2 отображается как "Ключ основного приложения".
Если вы хотите создать новое хранилище и ограниченный ключ приложения, вы можете использовать скрипт Backblaze bucket and key.
Restic
Restic создаст "репозиторий" во время развертывания Ansible. Это похоже на директорию внутри хранилища BackBlaze, являясь путём внутри хранилища последней частью backups_role_bucket_url
, разделённой по :
. Если вы хотите разместить его в корне, попробуйте что-то вроде b2:mybucket:/
. Подробнее смотрите в документации restic. Снаружи вы увидите:config data index keys locks snapshots
А если вы расшифруете его, например, при монтаже:hosts ids snapshots tags
Тем не менее, вы, вероятно, захотите восстановить только конкретный снимок из репозитория. Для этого используйте restic restore
. Вам нужно будет предоставить идентификатор снимка, который вы хотите восстановить, и целевую папку, чтобы выгрузить его. Вы можете просмотреть снимки, выполнив restic snapshots
. Особый случай — восстановление последнего снимка, для этого вы можете использовать latest
в качестве идентификатора снимка.
Чтобы восстановить только файл из последнего снимка, а не весь репозиторий, вы можете использовать подкоманду dump
: restic dump latest myfile > /home/user/myfile
Помните, что всем командам restic нужно знать, куда обращаться и с какими учетными данными. Поэтому вы можете передать их как параметры или экспортировать как переменные окружения. В этом случае нам нужны:
export RESTIC_REPOSITORY="b2:mybucketname:/"
export RESTIC_PASSWORD="долгое предложение с как минимум 7 словами"
export B2_ACCOUNT_ID="наш идентификатор ключа приложения"
export B2_ACCOUNT_KEY="наш ключ приложения, который очень длинный и содержит цифры и заглавные буквы"
Лицензия
GPLv3
ansible-galaxy install coopdevs/backups_role