Spis treści
- Trzy sposoby, w jakie backup zawodzi
- Krok 1: utwórz kanał, który przyciągnie Twoją uwagę
- Krok 2: wyłap awarie skryptem opakowującym
- borg i borgmatic
- Krok 3: wyłap backup, który nigdy się nie uruchomił
- Krok 4: sprawdź, czy backup jest świeży i da się go odtworzyć
- Krok 5: dzwoń tylko wtedy, gdy to ważne
- Najczęstsze pytania
- Jak dostać powiadomienie, gdy backup się nie powiedzie?
- Przy jakich kodach wyjścia restic warto alarmować?
- Skąd wiem, że backup po cichu przestał się uruchamiać?
- Czy pomyślny kod wyjścia wystarczy, by ufać backupowi?
- Czy mogę dostać telefon zamiast e-maila?
- Podsumowanie
- Powiązane artykuły
Większość ludzi odkrywa, że backupy były zepsute, dopiero w dniu, w którym są potrzebne. Zadanie zakończyło się błędem trzy tygodnie temu, nikt nie czytał logu, a najnowszy snapshot jest starszy niż pomyłka, którą chcesz cofnąć.
Rozwiązaniem nie jest lepsze narzędzie do backupu. Chodzi o to, by problem z backupem dotarł do człowieka w tej samej godzinie, w której się pojawia. Ten przewodnik pokazuje, jak to zrobić dla restic i borg (oraz wszystkiego, co uruchamia się z powłoki), z uwzględnieniem trzech sposobów, w jakie backupy naprawdę zawodzą, wraz ze skryptami do skopiowania. Ostatni krok wysyła alert na telefon przez Echobell, dzięki czemu zepsuty backup dzwoni, zamiast leżeć w skrzynce pocztowej.
Trzy sposoby, w jakie backup zawodzi
Monitorowanie tylko pierwszego to najczęstszy błąd.
- Uruchamia się i kończy błędem. Repozytorium zablokowane, dysk pełny, złe hasło, zerwana sieć. Narzędzie kończy działanie kodem innym niż zero.
- Uruchamia się i udaje się połowicznie. restic kończy z kodem
3, gdy snapshot powstał, ale części plików nie dało się odczytać. borg kończy z1przy ostrzeżeniach. Oba łatwo zbagatelizować i oba mogą ukrywać problem z uprawnieniami, który po cichu pomija Twój najważniejszy katalog. - Nigdy się nie uruchamia. Serwer był wyłączony, timer wyłączony, crontab nadpisany. Nie ma błędu, bo nie ma procesu. To awaria, która niszczy najwięcej.
Każda wymaga innego detektora, więc zbudujemy wszystkie trzy.
Krok 1: utwórz kanał, który przyciągnie Twoją uwagę
W Echobellu utwórz kanał o nazwie backups i ustaw typ powiadomienia na Połączenie dla zadań, które się liczą. Skopiuj jego adres webhooka:
https://hook.echobell.one/t/<channel-token>
Nadaj mu szablony, które będą zrozumiałe nawet na pół śpiąc, z polami, które wyślemy poniżej:
Tytuł: Backup {{status}} na {{host}}
Treść: {{job}}: {{detail}}
Składnię znajdziesz w dokumentacji szablonów.
Krok 2: wyłap awarie skryptem opakowującym
Mały wrapper zamienia kody wyjścia w alerty. Zapisz go jako /usr/local/bin/backup-run:
#!/usr/bin/env bash
set -uo pipefail
HOOK="https://hook.echobell.one/t/<channel-token>"
JOB="nightly-restic"
alert() {
curl -fsS -m 10 -X POST "$HOOK" \
-H "Content-Type: application/json" \
-d "{\"job\":\"$JOB\",\"host\":\"$(hostname)\",\"status\":\"$1\",\"detail\":\"$2\"}" || true
}
restic backup /srv /etc --exclude-caches
code=$?
case $code in
0) ;; # sukces: zachowaj ciszę
3) alert "incomplete" "Snapshot saved, but some files were unreadable" ;;
11) alert "locked" "Repository is locked by another process" ;;
12) alert "auth-failed" "Wrong repository password" ;;
*) alert "failed" "restic exited with code $code" ;;
esac
exit $code
Dlaczego szczegóły mają znaczenie:
set -ecelowo nie jest użyte, dzięki czemu skrypt dociera do alertu także po awarii restic.|| trueprzycurlsprawia, że niedostępny webhook nigdy nie zamaskuje prawdziwego kodu wyjścia.-m 10zapobiega temu, by zawieszone połączenie sieciowe blokowało kolejne zaplanowane uruchomienie.
Użyte wyżej kody wyjścia restic są opisane w jego podręczniku: 0 sukces, 1 błąd krytyczny, 3 snapshot utworzony, ale część plików źródłowych nieczytelna, 10 repozytorium nie istnieje, 11 nie udało się założyć blokady, 12 złe hasło. Sprawdź je przez restic version na własnej maszynie, bo kody były dodawane z czasem.
borg i borgmatic
borg zwraca 0 przy sukcesie, 1 przy ostrzeżeniach i 2 lub więcej przy błędach. Plik zmieniający się w trakcie backupu daje 1, co jest normalne dla katalogów z logami, więc częste podejście to dzwonić tylko od 2 wzwyż, a dla 1 wysyłać ciche powiadomienie:
borg create --stats ::'{hostname}-{now}' /srv /etc
code=$?
if [ "$code" -ge 2 ]; then
alert "failed" "borg exited with code $code"
elif [ "$code" -eq 1 ]; then
alert "warning" "borg finished with warnings"
fi
Jeśli używasz borgmatic, jego hook on_error uruchamia polecenie, gdy sam borgmatic napotka błąd, i to naturalne miejsce na ten sam curl. Pamiętaj o ograniczeniu, które sama dokumentacja borgmatic wskazuje: jeśli borgmatic w ogóle się nie uruchomi, on_error nigdy nie zadziała. To awaria numer trzy i potrzebny jest do niej Krok 3.
Krok 3: wyłap backup, który nigdy się nie uruchomił
Wrapper może zaraportować tylko uruchomienie, które się odbyło. Żeby wyłapać ciszę, odwróć logikę: backup wysyła ping do monitora, gdy się powiedzie, a monitor alarmuje, gdy ping jest spóźniony. To tzw. dead man's switch.
Healthchecks.io (hostowany lub własny) robi dokładnie to:
- Utwórz check z harmonogramem
0 3 * * *i czasem tolerancji na godzinę lub dwie. - Dodaj jego ping na końcu zadania, aby wysyłał się tylko po sukcesie.
- W integracjach checku dodaj Webhook wskazujący na adres Twojego kanału Echobell.
Ping trafia na koniec wrappera:
# w backup-run tuż przed końcowym `exit $code`; ping tylko przy sukcesie
if [ $code -eq 0 ]; then
curl -fsS -m 10 --retry 3 -o /dev/null https://hc-ping.com/<your-uuid>
fi
Healthchecks obsługuje też warianty pingu /start i /fail i potrafi przyjąć kod wyjścia w adresie URL, więc jeden check wyłapie także zadania, które się zawieszają. Efekt: martwy serwer, wyłączony timer i usunięta linia crontaba dają ten sam wynik, czyli dzwoniący telefon. Ogólny wzorzec i inne monitory znajdziesz w artykule alerty o awariach zadań cron.
Krok 4: sprawdź, czy backup jest świeży i da się go odtworzyć
Backup może uruchomić się o czasie, zakończyć kodem 0 i mimo to być bezużyteczny, na przykład gdy backupujesz pusty katalog po nieudanym zamontowaniu dysku. Dodaj dwie tanie kontrole poprawności w osobnym, codziennym zadaniu:
Wiek snapshotu. Alarmuj, jeśli najnowszy snapshot jest starszy, niż się spodziewasz:
latest=$(restic snapshots --latest 1 --json | jq -r '.[0].time')
age_h=$(( ( $(date +%s) - $(date -d "$latest" +%s) ) / 3600 ))
if [ "$age_h" -gt 30 ]; then
alert "stale" "Newest snapshot is ${age_h}h old"
fi
Integralność repozytorium. restic check weryfikuje strukturę repozytorium. Uruchamiaj go co tydzień; przy dużych repozytoriach restic check --read-data-subset=5% próbkuje dane bez czytania wszystkiego. Alarmuj przy niezerowym kodzie wyjścia.
Żadna z tych kontroli nie zastąpi prawdziwego testowego odtworzenia. Raz na kwartał odtwórz plik, który potrafisz zweryfikować, do katalogu tymczasowego. To jedyny test, który dowodzi, że backup działa.
Krok 5: dzwoń tylko wtedy, gdy to ważne
Jeśli każde ostrzeżenie dzwoni na telefon, wyciszysz kanał, a wtedy nie zadzwoni przy tym, który ma znaczenie. Użyj warunków Echobella, by rozdzielić poziomy na jednym kanale:
status == "failed" || status == "stale" || status == "auth-failed"
Wysyłaj incomplete i warning na drugi kanał, Pilne (Time Sensitive) lub zwykły, żeby pojawiały się na ekranie blokady bez dzwonka. Dodaj okno czasowe, jeśli chcesz, by awarie w ciągu dnia były ciche, używając zmiennych UTC opisanych w dokumentacji warunków.
Najczęstsze pytania
Jak dostać powiadomienie, gdy backup się nie powiedzie?
Opakuj polecenie backupu w wrapper, odczytaj jego kod wyjścia i wyślij webhook przy każdym kodzie innym niż zero. Dodaj dead man's switch, taki jak Healthchecks.io, żeby dowiadywać się też o uruchomieniach, które w ogóle nie wystartowały.
Przy jakich kodach wyjścia restic warto alarmować?
Alarmuj głośno przy 1, 10, 11 i 12, które oznaczają prawdziwą awarię. Kod 3 (snapshot utworzony, ale część plików nieczytelna) traktuj jako ostrzeżenie do zbadania, bo może ukrywać problem z uprawnieniami.
Skąd wiem, że backup po cichu przestał się uruchamiać?
Użyj heartbeatu: zadanie wysyła ping do monitora po sukcesie, a monitor alarmuje, gdy ping jest spóźniony. Hook błędu tego nie wyłapie, bo nic się nie uruchamia, by taki błąd zgłosić.
Czy pomyślny kod wyjścia wystarczy, by ufać backupowi?
Nie. Oznacza on, że narzędzie zakończyło pracę, a nie że dane są kompletne lub da się je odtworzyć. Sprawdzaj wiek snapshotów, regularnie uruchamiaj kontrole integralności i testuj odtwarzanie.
Czy mogę dostać telefon zamiast e-maila?
Tak. E-mail łatwo przeoczyć. Kanał telefoniczny w Echobellu zachowuje się jak połączenie przychodzące i przebija tryb Skupienia w iOS, więc nieudany backup o 3:00 nie umknie Twojej uwadze.
Podsumowanie
Trzy detektory pokrywają trzy tryby awarii: wrapper kodów wyjścia dla uruchomień, które się nie udają, kontrola świeżości dla tych, które kończą się sukcesem bez sensu, i heartbeat dla tych, które w ogóle nie następują. Skieruj je na kanał telefoniczny, ostrzeżenia zostaw na cichszym, a zepsuty backup stanie się pięciominutową naprawą zamiast straconego weekendu.
Pobierz Echobella na iPhone'a albo weź go z Google Play, utwórz kanał backups i uruchom wrapper raz z celowo błędnym hasłem, by usłyszeć dzwonek.