Back-ups zijn niet eenvoudig
Zie ook: de uitstekende blog van John Salvatier, "Reality has a surprising amount of detail".
Ik las ergens een reactie die me bijbleef, die ongeveer als volgt luidde: “Er zijn twee soorten mensen: zij die een catastrofaal verlies van gegevens hebben geleden, en zij die dat nog zullen doen.”
Toen ik probeerde de bron hiervoor te vinden voor deze blog, bleek dat bijna elke systeembeheerder zijn eigen versie van het citaat heeft, maar de kern is overal hetzelfde. Dataverlies gebeurt vaker dan we zouden hopen, en de meesten van ons zijn jammerlijk onvoorbereid wanneer het ons overkomt (wat bijna altijd op het slechtst denkbare moment is).
Ik kan bevestigen dat ik een soortgelijke ervaring heb gehad. Toen ik klein was, hadden we alle familiefoto's van onze laptops en pc's naar een externe harde schijf gekopieerd om ruimte vrij te maken. Dit werkte prachtig tot de dag dat mijn vader de schijf wilde gebruiken als opslag voor ons tv-settopbox (zo'n oud ding) en werd gevraagd de schijf te formatteren. Hij deed dit, en de schijf werd geformatteerd. De index van bestanden werd verwijderd en we zaten op met een nominaal lege schijf.
Het zou makkelijk zijn om hem de schuld te geven van deze fout, maar je moet een carrière in de techniek beginnen om te beseffen dat er een reeks fouten aan dit soort vergissingen voorafgaat. Ten eerste hadden we al onze foto's op één plek gezet en geen back-ups gemaakt. Ten tweede hebben de meeste consumentenprogramma's duidelijke waarschuwingen die vertellen dat het formatteren van een schijf betekent dat je gegevens verliest (wat de settopbox niet deed; een verschrikkelijke gebruikersinterface). Bovendien, waarom zou je van een niet-technisch persoon verwachten dat hij dit alles weet?
Gelukkig konden we de foto's herstellen, en het bleek een goedkope les in het omgaan met data te zijn. Je bewaart belangrijke zaken nooit op slechts één plek. Er kunnen een miljoen dingen misgaan. Je schijf kan kapotgaan, hij kan gestolen worden, of bits kunnen wegrotten in cold storage (harde schijven hebben magnetische deeltjes die onverklaarbaar kunnen verschuiven, en SSD's zijn gemaakt van NAND-transistoren die elektriciteit lekken en na verloop van tijd je gegevens corrupt maken).
De basisprincipes van back-ups
Ons eerste principe is dus om een back-up te hebben: een kopie van je bestanden op een andere plek. Tot zover alles goed.
Dit lost echter niet de problemen op van wat een aangesloten schijf kan veroorzaken. Ransomware kan je bestanden versleutelen, en je kunt alles doen van een eerlijke fout, zoals het verwijderen van het verkeerde bestand, tot catastrofale fouten zoals het uitvoeren van een script dat alles overschrijft met nullen.
Daarom mag onze back-up geen spiegelbeeld (mirror) zijn van de eerste schijf, omdat we ook terug in de tijd willen kunnen gaan als we een fout maken. Dit betekent concreet dat het spiegelen van je schijf met iets als RAID 1 geen optie is. We hebben een andere methode nodig die snapshots maakt.
RPO en rotatie
Hoe vaak willen we snapshots maken? In het geval van de foto's had ik misschien elke week een back-up moeten maken. Als we 6 dagen en 23 uur aan data verliezen, is dat acceptabel. In de IT wordt dit het Recovery Point Objective (RPO) genoemd. In de praktijk varieert dit van minder dan 30 seconden voor kritieke financiële instellingen die het zich echt niet kunnen veroorloven data te verliezen, tot 24 uur of meer voor sommige kleine bedrijven (als ze überhaupt een strategie voor rampenherstel hebben).
Het maken van snapshots betekent dat de druk op onze opslag toeneemt. Met een RPO van 24 uur eindig je met 7 snapshots per week. 30 per maand. 365 per jaar, als je de snapshots niet opschoont. Je moet je back-ups dus roteren.
Stel dat ik de naïeve aanpak kies en besluit om snapshots van 14 dagen te bewaren. Wanneer ik een nieuwe snapshot maak, verwijder ik de oudste en voeg ik de nieuwe toe. Dat is simpel, maar het dwingt me om alert te blijven. Misschien bewaar ik veel data en heb ik geen zin om te controleren of er in de afgelopen twee weken iets corrupt is geraakt? Maar aan de andere kant kan ik niet zomaar een jaar aan back-ups opslaan; die zijn simpelweg niet meer relevant voor me. Wat er tussen dag 2 en dag 3 van het jaar gebeurde, heeft bijna geen betekenis wanneer het dag 364 is. De granulariteit waarmee we back-ups maken moet dus veranderen: hoe dichter we bij vandaag zijn, hoe frequenter de snapshots; hoe verder terug in de tijd, hoe minder frequent.
Dus misschien roteren we onze dagelijkse back-ups elke 14 dagen, maar maken we ook wekelijkse back-ups die we elke 7 weken roteren, en maandelijkse back-ups die we elke 12 maanden roteren. Dit zou veel efficiënter moeten zijn. Maar opnieuw groeit de complexiteit. We hebben nu iets dat een GFS-rotated, snapshot-based backup wordt genoemd. Deze lijst met bijvoeglijke naamwoorden zal blijven groeien.
Efficiëntie door deduplicatie
Misschien kijk je daarna naar hoe MPEG video comprimeert en raak je gefascineerd door hoe een rustige scène in een film — waarin de protagonist spreekt maar verder niet beweegt tegen een volledig stilstaande achtergrond — gebruikt kan worden voor videocompressie. Je merkt dat video's zijn samengesteld uit frames die grotendeels op elkaar lijken en alleen veranderen met een bepaalde beweging die voor een fractie van de opslag als een vector kan worden weergegeven. Dit leidt tot de zeer logische conclusie dat jouw snapshots hetzelfde patroon volgen! Bovendien blijkt dat wijzigingen in bestanden een fat-tailed distributie volgen: over een bepaalde periode is er een enorme meerderheid van bestanden die helemaal niet worden gewijzigd, en een zeer kleine minderheid die constant verandert.
Het wordt dus duidelijk dat we geen identieke kopieën van bestanden moeten opslaan, maar moeten dedupliceren. We kunnen hard links gebruiken wanneer we naar een reeds bestaand bestand moeten verwijzen. Op deze manier slaan we één bestand op schijf op en verwijzen we vanuit elk van onze snapshots naar dit bestand. Dit overleeft ook de back-uprotatie, omdat we nooit bestanden verwijderen, maar alleen directory-vermeldingen. Exact deze aanpak wordt gebruikt door rsnapshot en wordt het best beschreven als een incrementele back-up, omdat we alleen de wijzigingen tussen twee opeenvolgende snapshots opslaan, in plaats van alle wijzigingen sinds de laatste volledige back-up (dit laatste worden differentiële back-ups genoemd; deze zijn robuuster bij het herstellen, maar voor de beknoptheid ga ik daar niet verder op in).
De besparing in opslag is niet het enige voordeel. We noemden aan het begin kort dat we niet alles op één machine opslaan. Uiteraard is er ook netwerkintegratie nodig, aangezien we de bestanden van de ene naar de andere machine moeten overzetten. Gedupliceerde back-ups besparen veel bandbreedte, wat vooral belangrijk is als je een clouddienst als tweede machine gebruikt. Dit heeft direct financiële gevolgen.
Op dit punt hebben we dus een incrementele, gedupliceerde, GFS-roterende back-up op basis van snapshots gecreëerd. We kunnen rsync gebruiken om de bestanden van de hoofdmachine op te halen en cronjobs om onze back-upscripts uit te voeren. We kunnen back-ups draaien op zoveel machines als we willen, en een extra machine toevoegen is triviaal. Nog beter is dat metadata van bestanden behouden blijft, waardoor zaken als toegangsrechten en bestandseigenaarschap correct blijven.
De complexiteit van de praktijk
Gemotiveerd door het succes van deze oplossing, proberen we het te gebruiken voor de back-up van de homelab met 10 Docker-containers. Maar later ontdekken we uit de logs op de individuele machines dat de back-ups mislukken. De reden is dat veel Docker-containers bestanden maken die eigendom zijn van de root-gebruiker, en als je niet voorzichtig bent, maak je een cronjob aan die draait als de standaardgebruiker.
Om het erger te maken: bijna elke webapplicatie gebruikt een database. Databases slaan gegevens soms in het geheugen op en schrijven deze in batches naar de schijf om de prestaties te verbeteren. Dit betekent in de praktijk dat herstel uit een back-up kan mislukken door data-corruptie als we pech hebben. Daarom zorgen we ervoor dat de back-up ook dumps van de databases maakt en volledige bestandssysteemrechten geeft op onze Docker-volumes. Dat zou het moeten oplossen!
Vervolgens lees je over incidenten waarbij een specifiek model harde schijf een berucht hoog uitvalpercentage had, en begin je je af te vragen of je je back-ups misschien op twee machines met verschillende soorten media moet bewaren. Op die manier is een hardware-specifiek defect minder waarschijnlijk om al je back-ups weg te vagen. En nu we het over fysieke beveiliging hebben: zorg voor één offsite back-up in de cloud of op een machine bij een familielid. Zo is het zeer onwaarschijnlijk dat een piekspanning, overstroming of brand alles vernietigt. Dit is waar de 3-2-1 back-up zijn naam aan ontleent: 3 kopieën, op 2 verschillende soorten media, waarvan 1 offsite.
De uitdagingen van de Cloud
Stel dat je kiest voor een cloudaanbieder voor je offsite back-up, specifiek object storage zoals Amazon S3. Je merkt al snel dat onze huidige opzet niet werkt, omdat:
- Bestanden hun metadata verliezen wanneer je ze uploadt naar S3.
- De prijs voor het uploaden van veel kleine bestanden naar S3 punitief hoog is (bestandsgroottes volgen namelijk ook een fat-tailed distributie).
Deze twee feiten maken het het beste om veel bestanden in een tarball te stoppen. Zo behoud je zowel de metadata van je bestanden als de lage kosten. Maar de vraag is: hoe doe je dat? Stop je alles in één gigantische tarball? Voor de zekerheid niet, want dan verliezen je incrementele back-ups met hard links hun zin. Het beste is om alles op te splitsen in nette brokken van 50 MB, maar veel succes om dat op een verifieerbaar veilige manier te doen!
Conclusie: Gebruik bewezen tools
Tot dit punt klonk het zelf bouwen van je back-ups als iets wat je in een middag zou moeten kunnen doen, maar dit is het punt waar ik zou opgeven. De mentale belasting om dit allemaal zelf te doen is het simpelweg niet waard. Gebruik in plaats daarvan beproefde tools zoals Borg of Restic, die dit alles en veel meer afhandelen (versleuteling, deduplicatie op chunk-niveau, checksums). Wees vooral zeer dankbaar naar de geweldige open-source gemeenschap die deze tools bouwt, onderhoudt en live test, en respecteer hoeveel trial-and-error nodig was om tot het punt te komen waar al deze complexiteit voor ons is geabstraheerd.
Uiteraard is niets hiervan iets waard als je het herstel niet daadwerkelijk test. Dat is dus een klein artikel over digitale hygiëne dat je aan je to-do lijst kunt toevoegen. Zolang je elke 6 maanden hersteltests uitvoert, kun je genieten van je:
versleutelde, op chunk-niveau gedupliceerde, GFS-roterende, point-in-time gearchiveerde, cloud-gebaseerde 3-2-1 back-uploosing.
En zorg ervoor dat je back-ups niet om 2:00 of 3:00 uur 's nachts draaien, want dan kunnen de dingen eng worden.
Groetjes,