Forum: PC Hard- und Software InfluxDB (1.8) im Docker aus "BackUp" wieder herstellen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Matthias S. (da_user)


Lesenswert?

Hi,
ich habe mir einen Rechner mit div. Docker-Containern zerschossen. Dabei 
durfte ich feststellen, dass meine BackUp-Strategrie wohl nicht die 
beste war. Die beruhte drauf mit Resiliosync das 
Docker-Volume-Verzeichnis /var/lib/docker/volumes auf einen anderen 
Rechner zu synchronisieren.

Einige Container konnte ich ganz gut wieder zu laufen bringen, in dem 
ich nach dem zurück kopieren (mithilfe eines Docker-Containers) ein 
'chmod -R 777 ./' über das Volume ausgeführt habe. NodeRed konnte ich 
zumindest soweit wieder zum laufen bringen, dass ich alle Flows 
exportieren konnte ich nachsehen konnte, welche Nodes installiert waren. 
War halt Handarbeit.

Etwas kurios ist dagegen InfluxDB (1.8):
Daten des Volumes zurück kopiert, 'chmod -R 777 ./' darüber ausgeführt. 
Container läuft, Datenbanken sind da, Benutzer sind da, NodeRed kann 
Daten reinschreiben, Grafana kann Daten auslesen. Aber: alle bisherigen 
Daten sind irgendwie weg, bzw. Grafana zeigt diese nicht mehr an - 
obwohl die ja eigentlich da drinnen stecken sollten?

Kennt jemand dieses Phänomen und/oder kann mir evlt. helfen?

Nebenfrage:
Bessere Idee für BackUps? Interessant wäre ja: 
https://github.com/alaub81/backup_docker_scripts
Da ich über das BackUp dann auch noch ein versioniertes BackUp laufen 
lasse (Duplicati), würde ich mir in dieses jede Menge große Volumes 
reinspeichern, was auch irgendwie doof ist...

von Lu (oszi45)


Lesenswert?

Ein einfaches Kopieren ist nicht die Ideallösung, wie man merkt. Eine 
Datenbank exportiert man. Evtl. ein Zeitproblem wie Räder wechseln am 
fahrenden ICE?

: Bearbeitet durch User
von Speedy G. (Firma: ACME) (speedy-g)


Lesenswert?

Kann man schon machen, man sollte aber Filesystem-Snapshots nutzen. 
Datenbanken zu exportieren ist keine Lösung, dauert viel zu lange und 
führt u.U. zu lange bestehenden Writelocks. Ich meine mich erinnern zu 
können, dass die offizielle Empfehlung von mySQL Snapshot kopieren ist.

von Jens G. (jensig)


Lesenswert?

Files unter einer laufenden DB einfach so zu kopieren ist schon immer 
eine schlechte Idee gewesen, da nie sichergestellt werden kann, dass die 
Daten da drin über die gesamte Backup-Dauer konstant und konsistent 
sind/bleiben, und somit inkonsistente und kaputte Backups entstehen. 
Deswegen bieten Datenbanken ja extra Backup-/Restore-Tools an, die das 
sicherstellen, bzw. den konkurrenten Zugriff entsprechend regeln.

von Andreas M. (amesser)


Lesenswert?

"chmod 777" Nicht dein Ernst - oder? Dateiberechtigungen sind nicht zum 
Spaß da. Dateisystembackups macht man unter Linux am besten mit "tar". 
Das speichert auch alle Besitzverhältnisse und kann die auch sauber 
wiederherstellen, wenn man es denn richtig benutzt. InfluxDB Backups 
werden mit dem Befehl "backup" gemacht. Dabei entsteht dann ein 
Verzeichnis. Dieses sichert man danach weg.

von Εrnst B. (ernst)


Lesenswert?

Jens G. schrieb:
> Files unter einer laufenden DB einfach so zu kopieren ist schon immer
> eine schlechte Idee gewesen, da nie sichergestellt werden kann, dass die
> Daten da drin über die gesamte Backup-Dauer konstant und konsistent
> sind/bleiben,

Postgres unterstützt das, aber: dazu muss mit pg_backup_start & 
pg_backup_stop der Datenbank mitgeteilt werden, wann du mit dem Kopieren 
(oder snapshot-erstellen) anfängst, und wann du damit fertig bist.
Wartet auf einen Checkpoint (oder löst einen aus), und hält danach die 
Daten-Dateien unverändert, bis das Backup fertig ist.
Änderungen die zwischendurch gemacht werden bleiben bis zum Abschluss 
des Backups im WAL, die Datenbank läuft also uneingeschränkt weiter, 
solange der Platz für das WAL reicht.

von Jens G. (jensig)


Lesenswert?

Εrnst B. schrieb:
> Jens G. schrieb:
>> Files unter einer laufenden DB einfach so zu kopieren ist schon immer
>> eine schlechte Idee gewesen, da nie sichergestellt werden kann, dass die
>> Daten da drin über die gesamte Backup-Dauer konstant und konsistent
>> sind/bleiben,
>
> Postgres unterstützt das, aber: dazu muss mit pg_backup_start &
> pg_backup_stop der Datenbank mitgeteilt werden, wann du mit dem Kopieren
> (oder snapshot-erstellen) anfängst, und wann du damit fertig bist.

Was ja meine Aussage bestätigt. Schließlich schrieb ich ja von "einfach 
so".

von Matthias S. (da_user)


Lesenswert?

Andreas M. schrieb:
> "chmod 777" Nicht dein Ernst - oder?

"chmod 777" ist ein nicht zu Unterschätzendes Tool zur Fehlerbehebung 
für blauäugige Hobby-Linux-Heim-Admins ;-)

Ich habe von der Platte noch vor der Neuinstallation mit Rescuezilla ein 
Image gezogen. Eigentlich sollte es ja möglich sein, das in eine 
Linux-VM einzubinden und dann mit einem Influx-DB-Container per binding 
in das Volume die Datenbank wieder zum laufen zu bekommen.
Liesen sich dann die Daten der alten Datenbank irgendwie extrahieren und 
in die neue schreiben?

von Matthias S. (da_user)


Lesenswert?

Kurze Zwischenmeldung:

der InfluxDB-Container konnte per Binding ohne Probleme auf die Daten 
zugreifen. Davon ist jetzt erstmal ein BackUp gezogen.
Jetzt muss ich nur noch gucken, wie ich beide Datenbanken zusammenführe. 
ChatGPT hat mir dazu immerhin schonmal drei Vorschläge gemacht. Die muss 
ich aber nochmal abfragen und testen.

von Sheeva P. (sheevaplug)


Lesenswert?

Matthias S. schrieb:
> ich habe mir einen Rechner mit div. Docker-Containern zerschossen. Dabei
> durfte ich feststellen, dass meine BackUp-Strategrie wohl nicht die
> beste war. Die beruhte drauf mit Resiliosync das
> Docker-Volume-Verzeichnis /var/lib/docker/volumes auf einen anderen
> Rechner zu synchronisieren.

"Nicht die beste BackUp-Strategrie" ist eine feine Untertreibung. :-)

> Einige Container konnte ich ganz gut wieder zu laufen bringen, in dem
> ich nach dem zurück kopieren (mithilfe eines Docker-Containers) ein
> 'chmod -R 777 ./' über das Volume ausgeführt habe.

Auch ein "chmod -R 777" ist keine besonders gute Strategrie, aber das 
haben die Kollegen in diesem Thread Dir ja bereits gesagt... So etwas 
wie
1
find <dir> -type d -print0 | xargs -0 -- chmod 755
2
find <dir> -type f -print0 | xargs -0 -- chmod 644

ist immer meistens noch keine gute Strategrie, aber immerhin besser, als 
alles (!) mit Lese-, Schreib- und Ausführrechten (!) zu versehen.

> Etwas kurios ist dagegen InfluxDB (1.8):
> Daten des Volumes zurück kopiert, 'chmod -R 777 ./' darüber ausgeführt.

Und kein chown(1)? Hm.

> Container läuft, Datenbanken sind da, Benutzer sind da, NodeRed kann
> Daten reinschreiben, Grafana kann Daten auslesen. Aber: alle bisherigen
> Daten sind irgendwie weg, bzw. Grafana zeigt diese nicht mehr an -
> obwohl die ja eigentlich da drinnen stecken sollten?

Leider kenne ich mich mit InfluxDB nicht aus, dafür aber mit einigen 
anderen Datenmanagementsystemen. Manche davon haben SEHR eigenwillige 
Vorstellungen davon, wem ihre Dateien und Verzeichnisse zu gehören und 
welche Permissions sie gefälligst zu haben haben. Das hier (vom klugen 
Ernst, natürlich) schon genannte PostgreSQL etwa verweigert den Start, 
wenn sein Datenverzeichnis nicht dem Benutzer "postgres" gehört, oder 
nicht die Permissions 0700 oder 0750 hat. Das ist auch gut so, denn in 
den Daten eines Datenmanagementsystems hat außer ihm selbst natürlich 
grundsätzlich nichts etwas zu suchen.

Und dann, hach ja, die Benutzerkennungen oder, genauer, die User-IDs. 
Weil so ein Linux-Setup ein, sagen wir mal... schwer vorhersagbares Ding 
ist, werden Benutzerkennungen häufig dynamisch vergeben, auch für 
Daemon- und Systemuser. Mit on-the-fly gestarteten Docker-Containern 
läßt sich das leicht überprüfen: installiere ich dort zuerst InfluxDB 
und dann PostgreSQL, dann sehen die UID so aus:
1
username | uid
2
---------+-----
3
influxdb | 100 
4
postgres | 102

Installiere ich hingegen zuerst PostgreSQL und dann InfluxDB, haben die 
User plötzlich ganz andere User-IDs:
1
username | uid
2
---------+-----
3
postgres | 101
4
influxdb | 102

(Vor PostgreSQL wird noch ein User "messagebus" angelegt, aber das 
spielt hier keine Rolle.)

Du siehst: die Benutzerkennungen, unter denen Deine Prozesse innerhalb 
Deiner Container laufen, sind nicht immer dieselben -- und, Achtung: 
auch nicht die auf Deinem Hostsystem. Das führt hier bei mir 
beispielsweise zu der lustigen Situation, daß die Datendateien meines 
OpenSearch-Containers im Container die User-ID 1000 des Benutzers 
"opensearch", aber auf dem Host  die User-Id meines normalen 
Shellbenutzers haben. In meinem Redis-Container hat der Redis-Server die 
Benutzerkennung "redis" mit der User-ID 999, die auf meinem Host dem 
User "systemd-coredump" vorbehalten ist.

Also -- und das ist der Punkt -- in Deinen Docker-Volume-Verzeichnissen 
auf Deinem Host, also: jenen Verzeichnissen, die Du mit Deiner 
"Backup-Strategrie" herum kopierst, legen die Prozesse Deiner Containern 
ihre Daten unter jener User-ID ab, mit der die Prozesse in Deinen 
Containern laufen. Die muß nicht einmal mit Deinem Host konsistent sein, 
und ist es höchstwahrscheinlich auch nicht zwischen verschiedenen 
Docker-Containern (oder -Generationen).

Okay, wie gehen wir mit dem "Problem" jetzt um? Da gibt es verschiedene 
Ideen und Strategien, die erste ist ein Feature namens userns-remaß, 
also Sub-UIDs und Sub-GIDs, die Manpages dazu gibt es in subuid(5) und 
subgid(5). Damit lassen sich Unter-IDs für Systembenutzer einrichten, 
aber Achtung: Docker läuft entweder mit oder ohne, und wer dieses 
Feature einschaltet, muß wissen, daß seine existierenden Container dann 
nicht mehr starten. Siehe auch [1].

Dann gibt es die Möglichkeit, feste User-IDs in den Containern bereits 
beim Erzeugen der Images festzulegen, sei es mit useradd(8) oder 
adduser(8), oder (diese Möglichkeit ist eher unbekannt) indem einfach 
die passenden Dateien passwd und group in /etc des Image angelegt 
werden, bevor die gewünschte Software installiert wird. Einfach ein
1
echo 'nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin' > /etc/passwd
2
echo 'nogroup:x:65534:' > /etc/group

im "RUN" eines Dockerfile und danach ein "USER nobody", schon läuft der 
ganze Prozess im Container als "nobody" mit der User-ID 65534. Ebenso 
kann man eine definierte User-ID beispielsweise für Benutzer wie 
"postgres" oder "influxdb" anlegen, bevor die betreffende Software im 
Image installiert wird -- oder wenn sie bereits installiert ist, mit 
usermod(8) die angelegten User modifizieren und ihnen fest vorgegebene 
User-IDs zuzuweisen (dann allerdings auch die bei der Installation 
angelegten Dateien und Verzeichnisse... genau). Die letztere Möglichkeit 
funktioniert sogar, ohne daß die Benutzerverwaltungswerkzeuge im Image 
installiert worden sind.

Wie dem auch sei: am Ende wirst Du für jede halbwegs zuverlässige 
Strategie reproduzierbare User- und Group-IDs brauchen.

[1] https://docs.docker.com/engine/security/userns-remap/

> Bessere Idee für BackUps? Interessant wäre ja:
> https://github.com/alaub81/backup_docker_scripts
> Da ich über das BackUp dann auch noch ein versioniertes BackUp laufen
> lasse (Duplicati), würde ich mir in dieses jede Menge große Volumes
> reinspeichern, was auch irgendwie doof ist...

Was nützt Dir die beste Backup-Strategrie, wenn Du das Restore nicht 
getestet hast? Richtig: nichts, oder, anders gesagt: hast Du kein 
Backup. Und ohne Dir zu Nahe treten zu wollen: einfach nur Daten 
irgendwohin sichern kostet zwar Speicherplatz, bietet Dir aber keine 
Garantie, sie im Falle eines Desasters wiederherstellen zu können. Und 
Dir irgendwas un- oder halb Verstandenes aus dem Internet zusammen zu 
kopieren, macht die Sache kaum besser.

In meinem ganz persönlichen Fall sind die allermeisten Images selbst 
erzeugt, und haben ein eigenes Programm als ENTRYPOINT. Je nachdem, wie 
es aufgerufen wird, arbeitet es als reiner Entrypoint und nutzt den 
Systembefehl exece(2), um den "eigentlichen" Entrypoint des Image zu 
starten. Gleichzeitig fungiert  es mit den passenden Argumenten aber 
auch als HEALTHCHECK und bei Containern, die Daten persistieren, werden 
diese in Tarballs auf STDOUT gedumpt oder aus ebensolchen von STDIN 
restauriert. Dadurch haben die Images eine einheitliche Bedienung, die 
sich obendrein über Labels prima automatisieren läßt. Das ist zwar ein 
bisschen Arbeit, aber sehr komfortabel. Und es verträgt sich prima mit 
meinen versionierten Backups (noch rsnapshot, künftig wohl Borg).

Wie dem auch sei: wenn Deine Datenmengen nicht exorbitant groß oder 
variant sind, dann ist es meist einfacher, Deine Daten mit "docker exec" 
erstmal in einen konsistenten Dump zu überführen und dann ins Backup zu 
schieben. Die meisten mir bekannten Backupwerkzeuge bieten die Option, 
vor dem Anfertigen eines neuen Backup ein oder mehrere Skripte 
auszuführen. Nutze sie.

von Vanye R. (vanye_rijan)


Lesenswert?

> "chmod 777" ist ein nicht zu Unterschätzendes Tool zur Fehlerbehebung
> für blauäugige Hobby-Linux-Heim-Admins ;-)

Ja, Linux im double-palmface-mode....

Vanye

von Matthias S. (da_user)


Lesenswert?

Sheeva P. schrieb:
> "Nicht die beste BackUp-Strategrie" ist eine feine Untertreibung. :-)

Ich werde hier in Zukunft den influxd backup Befehl verwenden. Macht 
halt relativ große Dateien, muss ich mir ggf. was wegen der 
Versionierung einfallen lassen...

Und... so schlecht war die gar nicht ;-)

Matthias S. schrieb:
> der InfluxDB-Container konnte per Binding ohne Probleme auf die Daten
> zugreifen. Davon ist jetzt erstmal ein BackUp gezogen.
> Jetzt muss ich nur noch gucken, wie ich beide Datenbanken zusammenführe.
> ChatGPT hat mir dazu immerhin schonmal drei Vorschläge gemacht.

Ich habe die relevanten Datenbanken mit
1
influx_inspect export -datadir /var/lib/influxdb/data -waldir /var/lib/influxdb/wal -out /backup/shc_old_lp/test.lp -database test
in eine Line Protokoll-Datei exportiert und dann mit
1
influx -import -path=/backup/shc_old_lp/test.lp
in die neue Datenbank importiert.
Habe da erstmal einen Schrecken bekommen, weil der Rechner dann erstmal 
eine Stunde lang quasi gar nicht reagiert hat. Auch SSH-Verbindungen 
aufbauen war nicht möglich, eigentlich nur noch eine Reaktion auf einen 
Ping. Hat dann für manche Datenbank nicht ganz ne Stunde gedauert und 
dann lief das wieder.

Tatsächlich sind die Daten wohl drinnen. Ich bekomme mit dem 
entsprechenden Influx-Befehl z.B. einen Datensatz vom 27.10.2023 - das 
ist einer der ersten Datensätze der da drinnen gelandet ist.
Blöd: Grafana zeigt trotzdem nur die "neuen" Daten an... hrmpf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.