Wenn’s mal nicht ganz so rund läuft…

Dieser Blogpost zeigt uns, wie ein OpenShift Cluster von Backups wiederhergestellt wird, welche Verzeichnisse gesichert werden müssen und wie man in schwierigen Situationen den Überblick behalten kann.

/var contains variable data files. 
This includes spool directories and files, administrative and logging data, and transient and temporary files.

Dies meint zumindest der Filesystem Hierarchy Standard. Wenn man aber im Wartungsfenster merkt, dass der letzte Adhoc-Befehl, den man via Ansible auf den gesamten OpenShift Cluster losgelassen hat, nicht ganz richtig war, und man tatsächlich überall /var entfernt hat, dann wird einem schnell klar, dass auf modernen Linux Systemen in diesem Verzeichnis nicht nur flüchtige, temporäre und variable Daten hausen.

Es ist der letzte Donnerstag des Monats, kurz nach sechs Uhr abends. Bei Puzzle ITC steht, wie immer zu dieser Zeit, das monatliche Wartungsfenster an. Vier Puzzler arbeiten vor Ort, ein Fünfter unterstützt von zuhause aus. Der Ablauf ist durchgeplant und wurde nach dem Vieraugenprinzip geprüft. Die Arbeit wird aufgenommen und schon nach kurzer Zeit erreicht uns die Frage vom Homeoffice-Zwiseli, ob wir etwas am VPN machen oder ob bei uns die Master API des Clusters noch erreichbar sei? Kurzer Check: Master scheinen offline. Verbinden mit ssh geht nicht.

Kurzer Schock, was ist passiert?
Beim Überprüfen der eingegebenen Befehle wird schnell klar: Anstatt /var/log/*, welches auf eine neue Partition migriert wurde, wurde /var/* gelöscht. Und dies auf allen Servern unserer produktiven OpenShift Plattform – auf einen Schlag.

Der erste Schock ist überwunden, nun muss eine Lösung her. Wie bringen wir den Cluster wieder zum Laufen und dies möglichst ohne Datenverlust? Flipcharts werden herangeführt, Schlachtpläne geschmiedet und auch wieder verworfen. Bald ist uns klar, wir haben zwei Möglichkeiten: Entweder wir schaffen es, auf den bestehenden VMs das /var Verzeichnis wiederherzustellen, oder wir bauen den OpenShift Cluster neu und restoren dann die einzelnen Komponenten. Die persistenten Daten der Applikationen im Cluster liegen auf Gluster Storage, welcher ebenfalls im Cluster eingebunden ist (RHOCS). Die Bricks sind jedoch auf einer separaten Platte und diese ist unversehrt. Ob die Daten zwischen den vier Gluster Nodes noch in sync sind, ist jedoch unklar. Die Konfigurationen des Clusters und der darauf laufenden Apps sind in etcd gespeichert, dem Key-Value-Store von OpenShift, und davon existiert ein relativ zeitnahes Backup. Soweit so gut. Wir teilen uns auf, zwei Zwiselis versuchen die gelöschten /vars wieder herzustellen, die anderen beiden bauen parallel dazu einen neuen Cluster auf. Wichtig ist hier zu erwähnen, dass wir seit Anfang dieses Jahres dabei sind, unsere komplette Infrastruktur vom eigenen Rechenzentrum in die Cloud zu verschieben (https://www.puzzle.ch/de/blog/articles/2019/04/24/puzzle-modernisiert-mit-cloudscale-ch-seine-it-infrastruktur). Da dieser Prozess noch voll im Gang ist und wir bis dato keinen Ausfall hatten, haben wir auch erst wenig bis keine Erfahrung in Recoveries auf der neuen Plattform.

Die zwei Zwiselis, welche versuchen das /var zu restoren, haben in Nullkommanichts eine LiveDisk erstellt und können erfolgreich eine der defekten VMs starten sowie die Daten aus dem Backup restoren. Nach dem Reboot der vermeintlich reparierten Disk will das System jedoch nicht booten (hierzu laufen die Analysen noch). Zeitgleich haben die anderen beiden, dank Ansible und Gitlab CI/CD-Pipeline (nach vorhergehendem Umbenennen der bestehenden VMs), alle 18 VMs neu deployed und beginnen mit dem Installieren des OpenShift Clusters. Die Strategie ist simpel: Den neuen Cluster installieren, sodass alle notwendigen Pakete und Configdateien vorhanden sind und anschliessend unsere Config aus dem Backup zurückspielen. Das prerequisites Playbook läuft und wir entscheiden uns den Cluster neu zu bauen, da der konventionelle Restore nicht auf Anhieb funktioniert hat. Allgemein haben wir ein gutes Gefühl und schicken das erste Zwiseli in den Feierabend.

Doch dann: das Playbook failed!

Der Dockerstorage kann nicht erstellt werden. Merkwürdig, denn hier sollte es eigentlich keine Probleme geben. Dieser Schritt wurde schon mehrmals erprobt. Das System wird analysiert. Da scheint was auf der Disk zu sein.

Unser VM-Deploment hat zwar neue VMs erstellt, jedoch die Datendisks an die neuen VMs umgehängt. Zum Glück sind die Playbooks nicht destruktiv. Um auf Nummer sicher zu gehen, hängen wir die Gluster-Disks wieder an die alten VMs und erstellen neue Disks für glusterfs-server, ohne unsere persistenten Daten in Gefahr zu bringen. Parallel hierzu erstellen wir mit dd eine Kopie von allen Disks. An dieser Stelle ein riesengrosses Dankeschön an cloudscale.ch, dass wir einfach mal kurz 12 TB SSDs zusätzlich allozieren und am Ende der Nacht wieder freigeben konnten!

Nachdem wir auf allen Nodes den Dockerpool gelöscht und die neuen Disks angehängt haben, läuft sowohl das prerequisites wie auch das deploy-cluster Playbook durch. Wir haben wieder einen funktionierenden OpenShift Cluster!

Bevor wir mit dem Restore beginnen, nutzen wir die Chance und erledigen die geplanten Tasks. /var/log wird in einem neuen Anlauf migriert (ohne dass /var ins /dev/null verbannt wird), Zertifikate ausgetauscht, Docker Konfiguration ergänzt, Infrastruktur Limits und Requests gesetzt und die OS-Patches eingespielt. Um uns abzusichern, deaktivieren wir auf den Infranodes (welche auch als Glusternodes genutzt werden) den docker und atomic-openshift-node Dienst und schalten die VMs ab. Anschliessend restoren wir als Erstes den etcd Example Backup etcd job on a OpenShift 3 Cluster:

Restore von einem etcd Cluster auf OpenShift ist zwar bei RedHat beschrieben, aber nicht aktuell:

Am besten folgt man dieser Anleitung:

Folgende Schritte sind nötig:

 
# Do this on all Masters
# First Restore /etc/etcd from Backup
$ systemctl stop atomic-openshift-node
$ systemctl stop docker
$ mv /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak
$ yum install etcd-3.2.22-1.el7.x86_64
$ rm -rf /var/lib/etcd
$ mv /etc/etcd/etcd.conf.bak /etc/etcd/etcd.conf
$ source /etc/etcd/etcd.conf
$ export ETCDCTL_API=3
$ etcdctl snapshot restore /tmp/snapshot.db \
  --name $ETCD_NAME \
  --initial-cluster $ETCD_INITIAL_CLUSTER \
  --initial-cluster-token $ETCD_INITIAL_CLUSTER_TOKEN \
  --initial-advertise-peer-urls $ETCD_INITIAL_ADVERTISE_PEER_URLS \
  --data-dir /var/lib/etcd
$ restorecon -Rv /var/lib/etcd
# After restoring all etcd data, start `atomic-openshift-node` and `docker` on all masters
$ systemctl start atomic-openshift-node
$ systemctl start docker
$ ETCD_ALL_ENDPOINTS=` etcdctl3 --write-out=fields
  member list | awk '/ClientURL/{printf "%s%s",sep,$3;
  sep=","}'`
$ etcdctl3 --endpoints=$ETCD_ALL_ENDPOINTS endpoint status --write-out=table
 

Anschliessend stellen wir auf allen Nodes /etc/origin wieder aus dem Backup her, starten die Infranodes und müssen dort folgende Verzeichnisse wiederherstellen: /etc/origin, /var/lib/glusterd, /var/lib/heketi.

Backup/Restore Labs vom APPUiO OpenShift OPStechlab

Hier findet ihr zwei Labs, die aufzeigen, wie man einzelne Projektdaten oder den gesamten etcd restored:

Bechreibung auf der Red Hat Seite:

OpenShift-Cluster von Grund auf wiederherstellen

  • VMs neu bereitstellen
  • Ausführen der prerequisites.yml und deploy_cluster.yml openshift-ansible Playbooks, damit ein neuer Cluster gebaut wird
  • Stoppen/Deaktivieren von Docker/Node-Diensten auf Infranodes und Herunterfahren der VMs
  • Wiederherstellung etcd Snapshot und /etc/etcd auf Masters
  • Wiederherstellung von /etc/origin auf allen Nodes des Clusters
  • Neustart von Infra-Nodes und Wiederherstellung folgender Pfade
    • /var/lib/glusterd
    • /var/lib/heketi
  • Infra-Nodes aktivieren
  • Hoffen

Was wir gelernt haben

  • DR sollte möglichst früh im Projekt getestet und dokumentiert sein
  • Keine Wartungsfenster bei 35+ Grad
  • Keine Änderungen in letzter Minute an den getesteten Changes
  • Alle Changes vorgängig auf der Testplattform testen
  • Auch bei 35+ Grad Änderungen im Detail hinterfragen
  • Wir brauchen einen Live-System-Wiederherstellungsplan auf Wolkenebene, hier haben wir bereits gute Inputs von cloudscale.ch erhalten.
  • Es sollte eine Möglichkeit geben, VM-Snapshots zu erstellen. Dazu haben wir einen Feature Request bei cloudscale.ch eingegeben.
  • Zerstörerische Schritte nicht parallelisieren, wenn nicht getestet.

Letzter Abschnitt wurde mit DeepL übersetzt.

Kommentare sind geschlossen.