2017-11-10 12:48:41 +01:00
.. include :: global.rst.inc
2017-11-09 21:17:09 +01:00
.. _tutorial:
2017-11-09 20:33:09 +01:00
Tutorial
========
2018-10-21 22:20:35 +02:00
This tutorial shows how zrepl can be used to implement a ZFS-based push backup.
2017-11-09 20:33:09 +01:00
We assume the following scenario:
2018-10-11 17:46:26 +02:00
* Production server `` prod `` with filesystems to back up:
2017-11-09 20:33:09 +01:00
2017-11-09 21:17:09 +01:00
* `` zroot/var/db ``
* `` zroot/usr/home `` and all its child filesystems
* **except** `` zroot/usr/home/paranoid `` belonging to a user doing backups themselves
2017-11-09 20:33:09 +01:00
2018-10-11 17:46:26 +02:00
* Backup server `` backups `` with
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
* Filesystem `` storage/zrepl/sink/prod `` + children dedicated to backups of `` prod ``
2017-11-09 20:33:09 +01:00
Our backup solution should fulfill the following requirements:
2018-10-11 17:46:26 +02:00
* Periodically snapshot the filesystems on `` prod `` *every 10 minutes*
2018-10-21 22:20:35 +02:00
* Incrementally replicate these snapshots to `` storage/zrepl/sink/prod/* `` on `` backups ``
2018-10-11 17:46:26 +02:00
* 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 ``
2017-11-09 20:33:09 +01:00
Analysis
--------
We can model this situation as two jobs:
2018-10-21 22:20:35 +02:00
* A **push job** on `` prod ``
2017-11-09 20:33:09 +01:00
* Creates the snapshots
2018-10-21 22:20:35 +02:00
* 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
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
* A **sink job** on `` backups ``
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
* Accepts connections & responds to requests from `` prod ``
* Limits client `` prod `` access to filesystem sub-tree `` storage/zrepl/sink/prod ``
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
Install zrepl
-------------
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
Follow the :ref: `OS-specific installation instructions <installation>` and come back here.
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
Generate TLS Certificates
-------------------------
2017-11-09 20:33:09 +01:00
2020-01-15 19:12:09 +01:00
We use the :ref: `TLS client authentication transport <transport-tcp+tlsclientauth>` to protect our data on the wire.
2018-10-21 22:20:35 +02:00
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>` .
2020-01-15 19:12:09 +01:00
For convenience, we generate the key pairs on our local machine and distribute them using ssh:
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
.. code-block :: bash
:emphasize-lines: 6,13
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
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
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
ssh root@prod "mkdir /etc/zrepl"
scp prod.key prod.crt backups.crt root@prod:/etc/zrepl
Configure server `` prod ``
2018-10-26 21:52:29 +02:00
-------------------------
2017-11-09 20:33:09 +01:00
2018-10-21 22:20:35 +02:00
We define a **push job** named `` prod_to_backups `` in `` /etc/zrepl/zrepl.yml `` on host `` prod `` : ::
2017-11-09 20:33:09 +01:00
jobs:
2018-10-21 22:20:35 +02:00
- name: prod_to_backups
type: push
2017-11-16 09:14:01 +01:00
connect:
2018-10-21 22:20:35 +02:00
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: {
2019-10-05 14:45:53 +02:00
"zroot/var/db": true,
2018-10-21 22:20:35 +02:00
"zroot/usr/home<": true,
"zroot/usr/home/paranoid": false
}
snapshotting:
type: periodic
prefix: zrepl_
interval: 10m
2018-10-11 17:46:26 +02:00
pruning:
keep_sender:
- type: not_replicated
- type: last_n
count: 10
keep_receiver:
- type: grid
grid: 1x1h(keep=all) | 24x1h | 30x1d | 6x30d
regex: "^zrepl_"
2018-04-01 14:53:44 +02:00
2018-10-11 17:46:26 +02:00
.. _tutorial-configure-prod:
2018-04-01 14:53:44 +02:00
2018-10-26 21:52:29 +02:00
Configure server `` backups ``
----------------------------
2017-11-09 20:33:09 +01:00
2019-11-01 01:45:16 +01:00
We define a corresponding **sink job** named `` sink `` in `` /etc/zrepl/zrepl.yml `` on host `` backups `` : ::
2017-11-09 20:33:09 +01:00
jobs:
2018-10-21 22:20:35 +02:00
- name: sink
type: sink
2017-11-16 09:14:01 +01:00
serve:
2018-10-21 22:20:35 +02:00
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"
2017-11-09 20:33:09 +01:00
Apply Configuration Changes
---------------------------
2020-01-15 19:12:09 +01:00
We use `` zrepl configcheck `` to catch any configuration errors: no output indicates that everything is fine.
2018-10-21 22:20:35 +02:00
If that is the case, restart the zrepl daemon on **both** `` prod `` and `` backups `` using `` service zrepl restart `` or `` systemctl restart zrepl `` .
2017-11-09 20:33:09 +01:00
Watch it Work
-------------
2018-10-11 17:46:26 +02:00
Run `` zrepl status `` on `` prod `` to monitor the replication and pruning activity.
2018-10-21 22:20:35 +02:00
To re-trigger replication (snapshots are separate!), use `` zrepl signal wakeup prod_to_backups `` on `` prod `` .
2017-11-09 20:33:09 +01:00
2017-11-10 14:30:51 +01:00
If you like tmux, here is a handy script that works on FreeBSD: ::
2017-11-09 20:33:09 +01:00
pkg install gnu-watch tmux
2018-10-21 22:20:35 +02:00
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
2017-11-09 20:33:09 +01:00
2017-11-10 14:30:51 +01:00
The Linux equivalent might look like this: ::
2017-11-09 20:33:09 +01:00
# make sure tmux is installed & let's assume you use systemd + journald
2018-10-21 22:20:35 +02:00
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
2017-11-09 20:33:09 +01:00
Summary
-------
2019-03-18 14:56:32 +01:00
Congratulations, you have a working push backup. Where to go next?
2017-11-09 20:33:09 +01:00
2017-11-09 21:17:09 +01:00
* Read more about :ref: `configuration format, options & job types <configuration_toc>`
2018-04-14 11:24:47 +02:00
* Configure :ref: `logging <logging>` \& :ref: `monitoring <monitoring>` .