coopdevs.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 角色等。
# + 你可能不需要 tar 的 sudo 权限。因此我们默认禁用相关任务。
# + 如果你希望启用这些任务,请将相应变量设为 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 }}"
# PostgreSQL 内部管理员角色
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:
# 以 restic 格式的远程存储桶 URL
# 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
该剧本不会在全球范围内安装任何二进制文件,但仍然需要 root 权限。因此,您可能需要提供 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
提供自己的模板。您可以使用 cron-main.sh.j2 中指定的相同辅助方法 log
和 run
。您可以引用在 include_role
声明中指定的任何变量。
备份上传到对象存储的过程无法自定义,因此您仍需使用 backups_role_assets_paths
指定脚本保存的备份文件路径。是的,该变量应该命名为类似 backups_role_file_to_upload
之类的名称。有关详细信息,请参见 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
设置的 b2_account_key
(建议使用主密钥)和 backup-role
的 backups_role_b2_app_key
(建议使用应用密钥)。
Restic 所称的“账户密钥”在 B2 网页中显示为“主应用密钥”。
如果您想创建一个新的存储桶和一个受限的应用密钥,可以使用 Backblaze bucket and key 脚本。
Restic
在 Ansible 配置期间,Restic 将创建一个“仓库”。这看起来像是在 BackBlaze 存储桶中的一个目录,路径为在 backups_role_bucket_url
中的最后一部分,按 :
分割。如果想将其放置在根目录,请尝试 b2:mybucket:/
。有关更多信息,请参见 restic 文档。从外部,您将看到:config data index keys locks snapshots
如果您解密它,例如在 挂载 时:hosts ids snapshots tags
但是,您可能只想从仓库中恢复一个特定的快照。要做到这一点,请使用 restic restore
。您需要提供要恢复的快照 ID 和卸载到的目标目录。您可以通过 restic snapshots
浏览快照。特别的情况是恢复最后一个快照,您可以使用 latest
作为快照 ID。
要从最后一个快照恢复单个文件而不是整个仓库,您可以使用 dump
子命令:restic dump latest myfile > /home/user/myfile
请记住,所有 restic 命令都需要知道与之通信的地方和凭据。因此,您可以将它们作为参数传递,也可以将其导出为环境变量。对于此情况,我们需要:
export RESTIC_REPOSITORY="b2:mybucketname:/"
export RESTIC_PASSWORD="长句子,至少 7 个单词"
export B2_ACCOUNT_ID="我们的应用密钥 ID"
export B2_ACCOUNT_KEY="我们的应用密钥,包含多个字母和大写字母"
许可证
GPLv3