mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-22 00:13:52 +01:00
docs: add backup-to-external-disk quick-start guide and convert existing tutorial to quick-start guide
refs #219 fixes #329
This commit is contained in:
parent
9a8d813d14
commit
a827894274
85
config/samples/quickstart_backup_to_external_disk.yml
Normal file
85
config/samples/quickstart_backup_to_external_disk.yml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# This config serves as an example for a local zrepl installation that
|
||||||
|
# backups the entire zpool `system` to `backuppool/zrepl/sink`
|
||||||
|
#
|
||||||
|
# The requirements covered by this setup are described in the zrepl documentation's
|
||||||
|
# quick start section which inlines this example.
|
||||||
|
#
|
||||||
|
# CUSTOMIZATIONS YOU WILL LIKELY WANT TO APPLY:
|
||||||
|
# - adjust the name of the production pool `system` in the `filesystems` filter of jobs `snapjob` and `push_to_derive`
|
||||||
|
# - adjust the name of the backup pool `backuppool` in the `backuppool_sink` job
|
||||||
|
# - adjust the occurences of `myhostname` to the name of the system you are backing up (cannot be easily changed once you start replicating)
|
||||||
|
# - make sure the `zrepl_` prefix is not being used by any other zfs tools you might have installed (it likely isn't)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# this job takes care of snapshot creation + pruning
|
||||||
|
- name: snapjob
|
||||||
|
type: snap
|
||||||
|
filesystems: {
|
||||||
|
"system<": true,
|
||||||
|
}
|
||||||
|
# create snapshots with prefix `zrepl_` every 15 minutes
|
||||||
|
snapshotting:
|
||||||
|
type: periodic
|
||||||
|
interval: 15m
|
||||||
|
prefix: zrepl_
|
||||||
|
pruning:
|
||||||
|
keep:
|
||||||
|
# fade-out scheme for snapshots starting with `zrepl_`
|
||||||
|
# - keep all created in the last hour
|
||||||
|
# - then destroy snapshots such that we keep 24 each 1 hour apart
|
||||||
|
# - then destroy snapshots such that we keep 14 each 1 day apart
|
||||||
|
# - then destroy all older snapshots
|
||||||
|
- type: grid
|
||||||
|
grid: 1x1h(keep=all) | 24x1h | 14x1d
|
||||||
|
regex: "^zrepl_.*"
|
||||||
|
# keep all snapshots that don't have the `zrepl_` prefix
|
||||||
|
- type: regex
|
||||||
|
negate: true
|
||||||
|
regex: "^zrepl_.*"
|
||||||
|
|
||||||
|
# This job pushes to the local sink defined in job `backuppool_sink`.
|
||||||
|
# We trigger replication manually from the command line / udev rules using
|
||||||
|
# `zrepl signal wakeup push_to_drive`
|
||||||
|
- type: push
|
||||||
|
name: push_to_drive
|
||||||
|
connect:
|
||||||
|
type: local
|
||||||
|
listener_name: backuppool_sink
|
||||||
|
client_identity: myhostname
|
||||||
|
filesystems: {
|
||||||
|
"system<": true
|
||||||
|
}
|
||||||
|
send:
|
||||||
|
encrypted: true
|
||||||
|
# disable incremental step holds so that
|
||||||
|
# - we can yank out the backup drive during replication
|
||||||
|
# - thereby sacrificing resumability
|
||||||
|
# - in exchange for the replicating snapshot not sticking around until we reconnect the backup drive
|
||||||
|
step_holds:
|
||||||
|
disable_incremental: true
|
||||||
|
snapshotting:
|
||||||
|
type: manual
|
||||||
|
pruning:
|
||||||
|
# no-op prune rule on sender (keep all snapshots), job `snapshot` takes care of this
|
||||||
|
keep_sender:
|
||||||
|
- type: regex
|
||||||
|
regex: ".*"
|
||||||
|
# retain
|
||||||
|
keep_receiver:
|
||||||
|
# longer retention on the backup drive, we have more space there
|
||||||
|
- type: grid
|
||||||
|
grid: 1x1h(keep=all) | 24x1h | 360x1d
|
||||||
|
regex: "^zrepl_.*"
|
||||||
|
# retain all non-zrepl snapshots on the backup drive
|
||||||
|
- type: regex
|
||||||
|
negate: true
|
||||||
|
regex: "^zrepl_.*"
|
||||||
|
|
||||||
|
# This job receives from job `push_to_drive` into `backuppool/zrepl/sink/myhostname`
|
||||||
|
- type: sink
|
||||||
|
name: backuppool_sink
|
||||||
|
root_fs: "backuppool/zrepl/sink"
|
||||||
|
serve:
|
||||||
|
type: local
|
||||||
|
listener_name: backuppool_sink
|
@ -0,0 +1,12 @@
|
|||||||
|
jobs:
|
||||||
|
- name: sink
|
||||||
|
type: sink
|
||||||
|
serve:
|
||||||
|
type: tls
|
||||||
|
listen: ":8888"
|
||||||
|
ca: "/etc/zrepl/prod.crt"
|
||||||
|
cert: "/etc/zrepl/backups.crt"
|
||||||
|
key: "/etc/zrepl/backups.key"
|
||||||
|
client_cns:
|
||||||
|
- "prod"
|
||||||
|
root_fs: "storage/zrepl/sink"
|
@ -0,0 +1,28 @@
|
|||||||
|
jobs:
|
||||||
|
- name: prod_to_backups
|
||||||
|
type: push
|
||||||
|
connect:
|
||||||
|
type: tls
|
||||||
|
address: "backups.example.com:8888"
|
||||||
|
ca: /etc/zrepl/backups.crt
|
||||||
|
cert: /etc/zrepl/prod.crt
|
||||||
|
key: /etc/zrepl/prod.key
|
||||||
|
server_cn: "backups"
|
||||||
|
filesystems: {
|
||||||
|
"zroot/var/db": true,
|
||||||
|
"zroot/usr/home<": true,
|
||||||
|
"zroot/usr/home/paranoid": false
|
||||||
|
}
|
||||||
|
snapshotting:
|
||||||
|
type: periodic
|
||||||
|
prefix: zrepl_
|
||||||
|
interval: 10m
|
||||||
|
pruning:
|
||||||
|
keep_sender:
|
||||||
|
- type: not_replicated
|
||||||
|
- type: last_n
|
||||||
|
count: 10
|
||||||
|
keep_receiver:
|
||||||
|
- type: grid
|
||||||
|
grid: 1x1h(keep=all) | 24x1h | 30x1d | 6x30d
|
||||||
|
regex: "^zrepl_"
|
@ -12,7 +12,7 @@ The following paths are considered:
|
|||||||
The ``zrepl configcheck`` subcommand can be used to validate the configuration.
|
The ``zrepl configcheck`` subcommand can be used to validate the configuration.
|
||||||
The command will output nothing and exit with zero status code if the configuration is valid.
|
The command will output nothing and exit with zero status code if the configuration is valid.
|
||||||
The error messages vary in quality and usefulness: please report confusing config errors to the tracking :issue:`155`.
|
The error messages vary in quality and usefulness: please report confusing config errors to the tracking :issue:`155`.
|
||||||
Full example configs such as in the :ref:`tutorial` or the :sampleconf:`/` directory might also be helpful.
|
Full example configs such as in the :ref:`quick-start guides <quickstart-toc>` or the :sampleconf:`/` directory might also be helpful.
|
||||||
However, copy-pasting examples is no substitute for reading documentation!
|
However, copy-pasting examples is no substitute for reading documentation!
|
||||||
|
|
||||||
Config File Structure
|
Config File Structure
|
||||||
|
@ -36,6 +36,7 @@ Filesystems matched by ``filesystems`` that are not encrypted are not sent and w
|
|||||||
|
|
||||||
If ``encryption=false``, zrepl expects that filesystems matching ``filesystems`` are not encrypted or have loaded encryption keys.
|
If ``encryption=false``, zrepl expects that filesystems matching ``filesystems`` are not encrypted or have loaded encryption keys.
|
||||||
|
|
||||||
|
.. _job-send-option-step-holds-disable-incremental:
|
||||||
|
|
||||||
``step_holds.disable_incremental`` option
|
``step_holds.disable_incremental`` option
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
@ -25,4 +25,8 @@
|
|||||||
.. |recv-options| replace:: :ref:`recv options<job-recv-options>`
|
.. |recv-options| replace:: :ref:`recv options<job-recv-options>`
|
||||||
.. |snapshotting-spec| replace:: :ref:`snapshotting specification <job-snapshotting-spec>`
|
.. |snapshotting-spec| replace:: :ref:`snapshotting specification <job-snapshotting-spec>`
|
||||||
.. |pruning-spec| replace:: :ref:`pruning specification <prune>`
|
.. |pruning-spec| replace:: :ref:`pruning specification <prune>`
|
||||||
.. |filter-spec| replace:: :ref:`filter specification<pattern-filter>`
|
.. |filter-spec| replace:: :ref:`filter specification<pattern-filter>`
|
||||||
|
|
||||||
|
.. |br| raw:: html
|
||||||
|
|
||||||
|
<br/>
|
@ -44,7 +44,7 @@ zrepl - ZFS replication
|
|||||||
Getting started
|
Getting started
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The :ref:`10 minutes tutorial setup <tutorial>` gives you a first impression.
|
The :ref:`10 minute quick-start guides <quickstart-toc>` give you a first impression.
|
||||||
|
|
||||||
Main Features
|
Main Features
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
@ -125,7 +125,7 @@ Table of Contents
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
tutorial
|
quickstart
|
||||||
installation
|
installation
|
||||||
configuration
|
configuration
|
||||||
usage
|
usage
|
||||||
|
@ -7,7 +7,7 @@ Installation
|
|||||||
|
|
||||||
.. TIP::
|
.. TIP::
|
||||||
|
|
||||||
Note: check out the :ref:`tutorial` if you want a first impression of zrepl.
|
Note: check out the :ref:`quick-start guides <quickstart-toc>` if you want a first impression of zrepl.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
|
@ -42,4 +42,4 @@ Either way, all build results are located in the ``artifacts/`` directory.
|
|||||||
.. NOTE::
|
.. NOTE::
|
||||||
|
|
||||||
It is your job to install the appropriate binary in the zrepl users's ``$PATH``, e.g. ``/usr/local/bin/zrepl``.
|
It is your job to install the appropriate binary in the zrepl users's ``$PATH``, e.g. ``/usr/local/bin/zrepl``.
|
||||||
Otherwise, the examples in the :ref:`tutorial` may need to be adjusted.
|
Otherwise, the examples in the :ref:`quick-start guides <quickstart-toc>` may need to be adjusted.
|
||||||
|
@ -126,7 +126,7 @@ Modify the ``/usr/local/etc/zrepl/zrepl.yml`` configuration file.
|
|||||||
|
|
||||||
.. TIP::
|
.. TIP::
|
||||||
|
|
||||||
Note: check out the :ref:`tutorial` for examples of a ``sink`` job.
|
Note: check out the :ref:`quick-start guides <quickstart-toc>` for examples of a ``sink`` job.
|
||||||
|
|
||||||
Now ``zrepl`` can be started.
|
Now ``zrepl`` can be started.
|
||||||
|
|
||||||
|
@ -5,4 +5,4 @@ What next?
|
|||||||
|
|
||||||
Read the :ref:`configuration chapter<configuration_toc>` and then continue with the :ref:`usage chapter<usage>`.
|
Read the :ref:`configuration chapter<configuration_toc>` and then continue with the :ref:`usage chapter<usage>`.
|
||||||
|
|
||||||
**Reminder**: If you want a quick introduction, please read the :ref:`tutorial`.
|
**Reminder**: If you want a quick introduction, please read the :ref:`quick-start guides <quickstart-toc>`.
|
||||||
|
87
docs/quickstart.rst
Normal file
87
docs/quickstart.rst
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
.. include:: global.rst.inc
|
||||||
|
|
||||||
|
.. _quickstart-toc:
|
||||||
|
|
||||||
|
***********************
|
||||||
|
Quick Start by Use Case
|
||||||
|
***********************
|
||||||
|
|
||||||
|
The goal of this quick-start guide is to give you an impression of how zrepl can accomodate your use case.
|
||||||
|
|
||||||
|
Install zrepl
|
||||||
|
=============
|
||||||
|
|
||||||
|
Follow the :ref:`OS-specific installation instructions <installation_toc>` and come back here.
|
||||||
|
|
||||||
|
Overview Of How zrepl Works
|
||||||
|
============================
|
||||||
|
|
||||||
|
Check out the :ref:`overview section <job-overview>` to get a rough idea of what you are going to configure in the next step, then come back here.
|
||||||
|
|
||||||
|
Configuration Examples
|
||||||
|
======================
|
||||||
|
|
||||||
|
zrepl is configured through a YAML configuration file in ``/etc/zrepl/zrepl.yml``.
|
||||||
|
We have prepared example use cases that show-case typical deployments and different functionality of zrepl.
|
||||||
|
We encourage you to read through all of the examples to get an idea of what zrepl has to offer, and how you can mix-and-match configurations for your use case.
|
||||||
|
Keep the :ref:`full config documentation <configuration_toc>` handy if a config snippet is unclear.
|
||||||
|
|
||||||
|
**Example Use Cases**
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:titlesonly:
|
||||||
|
|
||||||
|
quickstart/continuous_server_backup
|
||||||
|
quickstart/backup_to_external_disk
|
||||||
|
|
||||||
|
Use ``zrepl configcheck`` to validate your configuration.
|
||||||
|
No output indicates that everything is fine.
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
Please open an issue on GitHub if your use case for zrepl is significantly different from those listed above.
|
||||||
|
Or even better, write it up in the same style as above and open a PR!
|
||||||
|
|
||||||
|
.. _quickstart-apply-config:
|
||||||
|
|
||||||
|
Apply Configuration Changes
|
||||||
|
===========================
|
||||||
|
|
||||||
|
We hope that you have found a configuration that fits your use case.
|
||||||
|
Use ``zrepl configcheck`` once again to make sure the config is correct (output indicates that everything is fine).
|
||||||
|
Then restart the zrepl daemon on all systems involved in the replication, likely using ``service zrepl restart`` or ``systemctl restart zrepl``.
|
||||||
|
|
||||||
|
Watch it Work
|
||||||
|
=============
|
||||||
|
|
||||||
|
Run ``zrepl status`` on the active side of the replication setup to monitor snaphotting, replication and pruning activity.
|
||||||
|
To re-trigger replication (snapshots are separate!), use ``zrepl signal wakeup JOBNAME``.
|
||||||
|
(refer to the example use case document if you are uncertain which job you want to wake up).
|
||||||
|
|
||||||
|
You can also use basic UNIX tools to inspect see what's going on.
|
||||||
|
If you like tmux, here is a handy script that works on FreeBSD: ::
|
||||||
|
|
||||||
|
pkg install gnu-watch tmux
|
||||||
|
tmux new -s zrepl -d
|
||||||
|
tmux split-window -t zrepl "tail -f /var/log/messages"
|
||||||
|
tmux split-window -t zrepl "gnu-watch 'zfs list -t snapshot -o name,creation -s creation'"
|
||||||
|
tmux split-window -t zrepl "zrepl status"
|
||||||
|
tmux select-layout -t zrepl tiled
|
||||||
|
tmux attach -t zrepl
|
||||||
|
|
||||||
|
The Linux equivalent might look like this: ::
|
||||||
|
|
||||||
|
# make sure tmux is installed & let's assume you use systemd + journald
|
||||||
|
tmux new -s zrepl -d
|
||||||
|
tmux split-window -t zrepl "journalctl -f -u zrepl.service"
|
||||||
|
tmux split-window -t zrepl "watch 'zfs list -t snapshot -o name,creation -s creation'"
|
||||||
|
tmux split-window -t zrepl "zrepl status"
|
||||||
|
tmux select-layout -t zrepl tiled
|
||||||
|
tmux attach -t zrepl
|
||||||
|
|
||||||
|
What Next?
|
||||||
|
==========
|
||||||
|
|
||||||
|
* Read more about :ref:`configuration format, options & job types <configuration_toc>`
|
||||||
|
* Configure :ref:`logging <logging>` \& :ref:`monitoring <monitoring>`.
|
||||||
|
|
36
docs/quickstart/backup_to_external_disk.rst
Normal file
36
docs/quickstart/backup_to_external_disk.rst
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
.. include:: ../global.rst.inc
|
||||||
|
|
||||||
|
.. _quickstart-backup-to-external-disk:
|
||||||
|
|
||||||
|
Local Snapshots + Offline Backup to an External Disk
|
||||||
|
====================================================
|
||||||
|
|
||||||
|
This config example shows how we can use zrepl to make periodic snapshots of our local workstation and back it up to a zpool on an external disk which we occassionally connect.
|
||||||
|
|
||||||
|
The local snapshots should be taken every 15 minutes for pain-free recovery from CLI disasters (``rm -rf /`` and the like).
|
||||||
|
However, we do not want to keep the snapshots around for very long because our workstation is a little tight on disk space.
|
||||||
|
Thus, we only keep one hour worth of high-resolution snapshots, then fade them out to one per hour for a day (24 hours), then one per day for 14 days.
|
||||||
|
|
||||||
|
At the end of each work day, we connect our external disk that serves as our workstation's local offline backup.
|
||||||
|
We want zrepl to inspect the filesystems and snapshots on the external pool, figure out which snapshots were created since the last time we connected the external disk, and use incremental replication to efficiently mirror our workstation to our backup disk.
|
||||||
|
Afterwards, we want to clean up old snapshots on the backup pool: we want to keep all snapshots younger than one hour, 24 for each hor of the first day, then 360 daily backups.
|
||||||
|
|
||||||
|
A few additional requirements:
|
||||||
|
|
||||||
|
* Snapshot creation and pruning on our workstation should happen in the background, without interaction from our side.
|
||||||
|
* However, we want to explicitly trigger replication via the command line.
|
||||||
|
* We want to use OpenZFS native encryption to protect our data on the external disk.
|
||||||
|
It is absolutely critical that only encrypted data leaves our workstation.
|
||||||
|
**zrepl should provide an easy config knob for this and prevent replication of unencrypted datasets to the external disk.**
|
||||||
|
* We want to be able to put off the backups for more than three weeks, i.e., longer than the lifetime of the automatically created snapshots on our workstation.
|
||||||
|
**zrepl should use bookmarks and holds to achieve this goal**.
|
||||||
|
* When we yank out the drive during replication and go on a long vacation, we do *not* want the partially replicated snapshot to stick around as it would hold on to too much disk space over time.
|
||||||
|
Therefore, we want zrepl to deviate from its :ref:`default step-hold behavior <step-holds-and-bookmarks>` and sacrifice resumability, but nonetheless retain the ability to do incremental replication once we return from our vacation.
|
||||||
|
**zrepl should provide an easy config knob to disable step holds for incremental replication**.
|
||||||
|
|
||||||
|
The following config snippet implements the setup described above.
|
||||||
|
You will likely want to customize some aspects mentioned in the top comment in the file.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../config/samples/quickstart_backup_to_external_disk.yml
|
||||||
|
|
||||||
|
:ref:`Click here <quickstart-apply-config>` to go back to the quickstart guide.
|
97
docs/quickstart/continuous_server_backup.rst
Normal file
97
docs/quickstart/continuous_server_backup.rst
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
.. include:: ../global.rst.inc
|
||||||
|
|
||||||
|
.. _quickstart-continuous-replication:
|
||||||
|
|
||||||
|
Continuous Backup of a Server
|
||||||
|
=============================
|
||||||
|
|
||||||
|
This config example shows how we can backup our ZFS-based server to another machine using a zrepl push job.
|
||||||
|
|
||||||
|
* Production server ``prod`` with filesystems to back up:
|
||||||
|
|
||||||
|
* ``zroot/var/db``
|
||||||
|
* ``zroot/usr/home`` and all its child filesystems
|
||||||
|
* **except** ``zroot/usr/home/paranoid`` belonging to a user doing backups themselves
|
||||||
|
|
||||||
|
* Backup server ``backups`` with
|
||||||
|
|
||||||
|
* Filesystem ``storage/zrepl/sink/prod`` + children dedicated to backups of ``prod``
|
||||||
|
|
||||||
|
Our backup solution should fulfill the following requirements:
|
||||||
|
|
||||||
|
* Periodically snapshot the filesystems on ``prod`` *every 10 minutes*
|
||||||
|
* Incrementally replicate these snapshots to ``storage/zrepl/sink/prod/*`` on ``backups``
|
||||||
|
* Keep only very few snapshots on ``prod`` to save disk space
|
||||||
|
* Keep a fading history (24 hourly, 30 daily, 6 monthly) of snapshots on ``backups``
|
||||||
|
* The network is untrusted - zrepl should use TLS to protect its communication and our data.
|
||||||
|
|
||||||
|
Analysis
|
||||||
|
--------
|
||||||
|
|
||||||
|
We can model this situation as two jobs:
|
||||||
|
|
||||||
|
* A **push job** on ``prod``
|
||||||
|
|
||||||
|
* Creates the snapshots
|
||||||
|
* Keeps a short history of local snapshots to enable incremental replication to ``backups``
|
||||||
|
* Connects to the ``zrepl daemon`` process on ``backups``
|
||||||
|
* Pushes snapshots ``backups``
|
||||||
|
* Prunes snapshots on ``backups`` after replication is complete
|
||||||
|
|
||||||
|
* A **sink job** on ``backups``
|
||||||
|
|
||||||
|
* Accepts connections & responds to requests from ``prod``
|
||||||
|
* Limits client ``prod`` access to filesystem sub-tree ``storage/zrepl/sink/prod``
|
||||||
|
|
||||||
|
Generate TLS Certificates
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
We use the :ref:`TLS client authentication transport <transport-tcp+tlsclientauth>` to protect our data on the wire.
|
||||||
|
To get things going quickly, we skip setting up a CA and generate two self-signed certificates as described :ref:`here <transport-tcp+tlsclientauth-2machineopenssl>`.
|
||||||
|
For convenience, we generate the key pairs on our local machine and distribute them using ssh:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
:emphasize-lines: 6,13
|
||||||
|
|
||||||
|
openssl req -x509 -sha256 -nodes \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-days 365 \
|
||||||
|
-keyout backups.key \
|
||||||
|
-out backups.crt
|
||||||
|
# ... and use "backups" as Common Name (CN)
|
||||||
|
|
||||||
|
openssl req -x509 -sha256 -nodes \
|
||||||
|
-newkey rsa:4096 \
|
||||||
|
-days 365 \
|
||||||
|
-keyout prod.key \
|
||||||
|
-out prod.crt
|
||||||
|
# ... and use "prod" as Common Name (CN)
|
||||||
|
|
||||||
|
ssh root@backups "mkdir /etc/zrepl"
|
||||||
|
scp backups.key backups.crt prod.crt root@backups:/etc/zrepl
|
||||||
|
|
||||||
|
ssh root@prod "mkdir /etc/zrepl"
|
||||||
|
scp prod.key prod.crt backups.crt root@prod:/etc/zrepl
|
||||||
|
|
||||||
|
Note that alternative transports exist, e.g. via :ref:`TCP without TLS <transport-tcp>` or :ref:`ssh <transport-ssh+stdinserver>`.
|
||||||
|
|
||||||
|
Configure server ``prod``
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
We define a **push job** named ``prod_to_backups`` in ``/etc/zrepl/zrepl.yml`` on host ``prod`` :
|
||||||
|
|
||||||
|
.. literalinclude:: ../../config/samples/quickstart_continuous_server_backup_sender.yml
|
||||||
|
|
||||||
|
.. _tutorial-configure-prod:
|
||||||
|
|
||||||
|
Configure server ``backups``
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
We define a corresponding **sink job** named ``sink`` in ``/etc/zrepl/zrepl.yml`` on host ``backups`` :
|
||||||
|
|
||||||
|
.. literalinclude:: ../../config/samples/quickstart_continuous_server_backup_receiver.yml
|
||||||
|
|
||||||
|
Go Back To Quickstart Guide
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
:ref:`Click here <quickstart-apply-config>` to go back to the quickstart guide.
|
@ -1,177 +0,0 @@
|
|||||||
.. include:: global.rst.inc
|
|
||||||
|
|
||||||
.. _tutorial:
|
|
||||||
|
|
||||||
Tutorial
|
|
||||||
========
|
|
||||||
|
|
||||||
|
|
||||||
This tutorial shows how zrepl can be used to implement a ZFS-based push backup.
|
|
||||||
We assume the following scenario:
|
|
||||||
|
|
||||||
* Production server ``prod`` with filesystems to back up:
|
|
||||||
|
|
||||||
* ``zroot/var/db``
|
|
||||||
* ``zroot/usr/home`` and all its child filesystems
|
|
||||||
* **except** ``zroot/usr/home/paranoid`` belonging to a user doing backups themselves
|
|
||||||
|
|
||||||
* Backup server ``backups`` with
|
|
||||||
|
|
||||||
* Filesystem ``storage/zrepl/sink/prod`` + children dedicated to backups of ``prod``
|
|
||||||
|
|
||||||
Our backup solution should fulfill the following requirements:
|
|
||||||
|
|
||||||
* Periodically snapshot the filesystems on ``prod`` *every 10 minutes*
|
|
||||||
* Incrementally replicate these snapshots to ``storage/zrepl/sink/prod/*`` on ``backups``
|
|
||||||
* Keep only very few snapshots on ``prod`` to save disk space
|
|
||||||
* Keep a fading history (24 hourly, 30 daily, 6 monthly) of snapshots on ``backups``
|
|
||||||
|
|
||||||
Analysis
|
|
||||||
--------
|
|
||||||
|
|
||||||
We can model this situation as two jobs:
|
|
||||||
|
|
||||||
* A **push job** on ``prod``
|
|
||||||
|
|
||||||
* Creates the snapshots
|
|
||||||
* Keeps a short history of local snapshots to enable incremental replication to ``backups``
|
|
||||||
* Connects to the ``zrepl daemon`` process on ``backups``
|
|
||||||
* Pushes snapshots ``backups``
|
|
||||||
* Prunes snapshots on ``backups`` after replication is complete
|
|
||||||
|
|
||||||
* A **sink job** on ``backups``
|
|
||||||
|
|
||||||
* Accepts connections & responds to requests from ``prod``
|
|
||||||
* Limits client ``prod`` access to filesystem sub-tree ``storage/zrepl/sink/prod``
|
|
||||||
|
|
||||||
Install zrepl
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Follow the :ref:`OS-specific installation instructions <installation_toc>` and come back here.
|
|
||||||
|
|
||||||
Generate TLS Certificates
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
We use the :ref:`TLS client authentication transport <transport-tcp+tlsclientauth>` to protect our data on the wire.
|
|
||||||
To get things going quickly, we skip setting up a CA and generate two self-signed certificates as described :ref:`here <transport-tcp+tlsclientauth-2machineopenssl>`.
|
|
||||||
For convenience, we generate the key pairs on our local machine and distribute them using ssh:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
:emphasize-lines: 6,13
|
|
||||||
|
|
||||||
openssl req -x509 -sha256 -nodes \
|
|
||||||
-newkey rsa:4096 \
|
|
||||||
-days 365 \
|
|
||||||
-keyout backups.key \
|
|
||||||
-out backups.crt
|
|
||||||
# ... and use "backups" as Common Name (CN)
|
|
||||||
|
|
||||||
openssl req -x509 -sha256 -nodes \
|
|
||||||
-newkey rsa:4096 \
|
|
||||||
-days 365 \
|
|
||||||
-keyout prod.key \
|
|
||||||
-out prod.crt
|
|
||||||
# ... and use "prod" as Common Name (CN)
|
|
||||||
|
|
||||||
ssh root@backups "mkdir /etc/zrepl"
|
|
||||||
scp backups.key backups.crt prod.crt root@backups:/etc/zrepl
|
|
||||||
|
|
||||||
ssh root@prod "mkdir /etc/zrepl"
|
|
||||||
scp prod.key prod.crt backups.crt root@prod:/etc/zrepl
|
|
||||||
|
|
||||||
|
|
||||||
Configure server ``prod``
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
We define a **push job** named ``prod_to_backups`` in ``/etc/zrepl/zrepl.yml`` on host ``prod`` : ::
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- name: prod_to_backups
|
|
||||||
type: push
|
|
||||||
connect:
|
|
||||||
type: tls
|
|
||||||
address: "backups.example.com:8888"
|
|
||||||
ca: /etc/zrepl/backups.crt
|
|
||||||
cert: /etc/zrepl/prod.crt
|
|
||||||
key: /etc/zrepl/prod.key
|
|
||||||
server_cn: "backups"
|
|
||||||
filesystems: {
|
|
||||||
"zroot/var/db": true,
|
|
||||||
"zroot/usr/home<": true,
|
|
||||||
"zroot/usr/home/paranoid": false
|
|
||||||
}
|
|
||||||
snapshotting:
|
|
||||||
type: periodic
|
|
||||||
prefix: zrepl_
|
|
||||||
interval: 10m
|
|
||||||
pruning:
|
|
||||||
keep_sender:
|
|
||||||
- type: not_replicated
|
|
||||||
- type: last_n
|
|
||||||
count: 10
|
|
||||||
keep_receiver:
|
|
||||||
- type: grid
|
|
||||||
grid: 1x1h(keep=all) | 24x1h | 30x1d | 6x30d
|
|
||||||
regex: "^zrepl_"
|
|
||||||
|
|
||||||
.. _tutorial-configure-prod:
|
|
||||||
|
|
||||||
Configure server ``backups``
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
We define a corresponding **sink job** named ``sink`` in ``/etc/zrepl/zrepl.yml`` on host ``backups`` : ::
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- name: sink
|
|
||||||
type: sink
|
|
||||||
serve:
|
|
||||||
type: tls
|
|
||||||
listen: ":8888"
|
|
||||||
ca: "/etc/zrepl/prod.crt"
|
|
||||||
cert: "/etc/zrepl/backups.crt"
|
|
||||||
key: "/etc/zrepl/backups.key"
|
|
||||||
client_cns:
|
|
||||||
- "prod"
|
|
||||||
root_fs: "storage/zrepl/sink"
|
|
||||||
|
|
||||||
|
|
||||||
Apply Configuration Changes
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
We use ``zrepl configcheck`` to catch any configuration errors: no output indicates that everything is fine.
|
|
||||||
If that is the case, restart the zrepl daemon on **both** ``prod`` and ``backups`` using ``service zrepl restart`` or ``systemctl restart zrepl``.
|
|
||||||
|
|
||||||
|
|
||||||
Watch it Work
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Run ``zrepl status`` on ``prod`` to monitor the replication and pruning activity.
|
|
||||||
To re-trigger replication (snapshots are separate!), use ``zrepl signal wakeup prod_to_backups`` on ``prod``.
|
|
||||||
|
|
||||||
If you like tmux, here is a handy script that works on FreeBSD: ::
|
|
||||||
|
|
||||||
pkg install gnu-watch tmux
|
|
||||||
tmux new -s zrepl -d
|
|
||||||
tmux split-window -t zrepl "tail -f /var/log/messages"
|
|
||||||
tmux split-window -t zrepl "gnu-watch 'zfs list -t snapshot -o name,creation -s creation | grep zrepl_'"
|
|
||||||
tmux split-window -t zrepl "zrepl status"
|
|
||||||
tmux select-layout -t zrepl tiled
|
|
||||||
tmux attach -t zrepl
|
|
||||||
|
|
||||||
The Linux equivalent might look like this: ::
|
|
||||||
|
|
||||||
# make sure tmux is installed & let's assume you use systemd + journald
|
|
||||||
tmux new -s zrepl -d
|
|
||||||
tmux split-window -t zrepl "journalctl -f -u zrepl.service"
|
|
||||||
tmux split-window -t zrepl "watch 'zfs list -t snapshot -o name,creation -s creation | grep zrepl_'"
|
|
||||||
tmux split-window -t zrepl "zrepl status"
|
|
||||||
tmux select-layout -t zrepl tiled
|
|
||||||
tmux attach -t zrepl
|
|
||||||
|
|
||||||
Summary
|
|
||||||
-------
|
|
||||||
|
|
||||||
Congratulations, you have a working push backup. Where to go next?
|
|
||||||
|
|
||||||
* Read more about :ref:`configuration format, options & job types <configuration_toc>`
|
|
||||||
* Configure :ref:`logging <logging>` \& :ref:`monitoring <monitoring>`.
|
|
Loading…
Reference in New Issue
Block a user