Die Ransomware-Angriffe der vergangenen Monate haben vielen Administratoren die Bedeutung von funktionierenden Backupkonzepten schmerzlich vor Augen geführt. ... (mehr)

Heikles Pausieren

Der Ubuntu enthaltene Paketmanager funktioniert theoretisch auch innerhalb eines Containers. In der Praxis kommt es dabei allerdings zu allerlei ungewöhnlichem Verhalten. Zum Test der Funktion müssen wir den Namen des Containers ermitteln, das gelingt beispielsweise mit »docker ps« .

Zum Anhalten des Containers dient dann folgender Befehl:

$ docker container pause condescending_bohr
condescending_bohr

Ein angehaltener Container lebt nach wie vor in der Container-Runtime seines Hosts. Die Fortsetzung des Jobs erfolgt also analog:

$ docker container unpause condescending_bohr
condescending_bohr

Wenn Sie diese Befehle in einem neuen Kommandozeilenfenster eingeben, sehen Sie, dass im Container laufende Prozesse bei Eingabe von "Pause" einschlafen. Die Eingabe von "Unpause" setzt die Verarbeitung fort. Liegengebliebene Eingabe- und Verbindungsereignisse arbeitet der Container ab. Zum "Extrahieren" der Speicherinhalte eines Docker-Containers brauchen wir die Pausefunktion übrigens nicht unbedingt. In der Praxis empfiehlt sich ihre Verwendung aber schon deshalb, weil ein Container permanent läuft. Das Risiko, ein ungültiges Image zu ziehen, steigt bei der Image-Generierung im laufenden Betrieb immens.

Erfreulicherweise weiß das Docker-Entwicklerteam über diese Situation Bescheid, weshalb der zum Sichern laufender Images vorgesehene commit-Befehl ein dediziertes Flag mitbringt:

$ docker commit -p condescending_bohr tamshalt
sha256:16d31365a70e8d370227f792306851d0473dede6e6c554d956e1820d7b20ad2b

Ein Aspekt des Parameters ist, dass er das Anhalten des Containers zeitlich streng limitiert. Nach dem Ziehen des Images gibt »commit« den Container sofort wieder frei. Neben dem Pausebefehl und dem Namen des zu kopierenden Containers übergeben Sie normalerweise noch ein weiteres Namensfeld, das den neu anzulegenden Container beschreibt. Nach erfolgreicher Abarbeitung des Kommandos bekommen Sie es mit einem weiteren Image zu tun. Dieses lässt sich wie dargelegt nach Belieben abspeichern und wiederherstellen.

Angemerkt sei, dass das Einfrieren und Anlassen der Prozesse unter Linux unter Verwendung von cgroups erfolgt. Das bedeutet, dass die jeweiligen Threads beziehungsweise Programme keine Informationen darüber bekommen, dass sie eingefroren werden – das SIGSTOP-Signal trifft nicht ein. Unter Windows ist die Situation insofern besonders, als nur jene Container pausiert werden können, die unter Hyper-V leben.

Bild 3: Volumes leben "innerhalb" eines Host-Dateisystems; ein zwischengeschalteter Treiber erleichtert die Verwaltung.

Sicherung von Volumes

Das soeben besprochene commit-System – die Namensähnlichkeit zu Versionskontrollsystemen ist beabsichtigt – kümmert sich nur um die Inhalte des Containers. Wer Volumes sichern möchte, muss zusätzliche Aktionen durchführen. Sofern der Volume-Treiber nicht selbst eine Möglichkeit zum Durchführen von Backups mitbringt, gestaltet sich das Binden von Volumes an Ihre Hosts etwas schwierig. Der Königsweg besteht mit Sicherheit darin, das Volume aus der Cloud zu beschaffen. In diesem Fall muss sich der Nutzer nur wenig Gedanken über die Sicherung machen und kann beispielsweise die von AWS oder Azure angebotenen Versionierungsdienste verwenden.

Führt dies nicht zum Ziel, müssen Sie einen komplizierteren Weg gehen. Dieser ist übrigens auch in der Docker-Dokumentation empfohlen. Im ersten Schritt müssen alle Container, die das Volume benutzen, heruntergefahren oder anderweitig stillgelegt werden. Anschließend starten Sie einen neuen Container, der Verbindung zum Volume und zu einem beliebigen lokalen Verzeichnis auf der Workstation aufnimmt. Danach führt der Container einen copy-Befehl aus, der die im Volume befindlichen Informationen zusammenpackt und aus der Docker-Ausführungsumgebung herausschreibt. An dieser Stelle bekommen Sie – abermals – ein TAR-File, das Sie nach Belieben kopieren können:

docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

Die Wiederherstellung der Informationen erfolgt durch Umkehrung des Prozesses. Im ersten Schritt entsteht ein neuer Container, der die Inhalte des TAR-Archivs wieder in das Volume entpackt:

$ docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

Unter Ubuntu arbeitende Administratoren haben es an dieser Stelle insofern einfach, da auf einer lokalen Box laufende Container Volumeinformationen im Pfad "/var/lib/docker/volumes/" ablegen. Dieser ist naturgemäß auch für beliebige Kopierbefehle von der Shell des Hosts aus ansprechbar – ein anderer Weg, um Informationen zu exfiltrieren. Beachten Sie dabei allerdings das Risiko von Schreibkonflikten. Liest der Backupprozess eine Datei, während der Server einen Teil davon verändert, sind Konsistenzprobleme eher Regel als Ausnahme.

Ähnliche Artikel

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023