Webserver mit Docker Container umziehen, Theorie und Praxis

This page is also available in English

Wer einen virtuellen Server oder Cloud-Server mietet, muss diesen f├╝r ein neues Betriebssystem von Zeit zu Zeit austauschen. Sp├Ątestens, wenn f├╝r das Betriebssystem keine Updates mehr zur Verf├╝gung gestellt werden, ist ein Serverwechsel unausweichlich. Vor einiger Zeit habe ich alle Websites auf Docker-Container umgestellt, was den Umzug beschleunigen soll. Zun├Ąchst etwas Theorie zu meinen ├ťberlegungen, dann wie mein Serverumzug zuletzt vonstattenging. Zus├Ątzlich habe ich zu meinem letzten Serverumzug ein Video erstellt, siehe YouTube-Video. Wer die Theorie und meine ├ťberlegungen ├╝berspringen will, kann direkt zum Bereich Praxis meines letzten Serverumzugs wechseln.

Warum Docker?

Urspr├╝nglich brachte ein neuer Server auch eine neue PHP und MySQL-Version mit sich und nicht selten musste ich bei einem Serverwechsel so manches an den Websites und den Servereinstellungen nachbessern, damit diese wieder ordentlich funktionierten. Mit Docker bleiben diese ├ťberraschungen aus, da sich die Container auf allen Hosts identisch verhalten. Die Container k├Ânnen unabh├Ąngig vom Betriebssystem gepatcht werden. Zudem kann mit Docker sehr einfach ein Reverse Proxy f├╝r das Hinzuf├╝gen von https SSL Zertifikaten verwendet werden, siehe: sichere https Verbindung: Traefik Reverse Proxy + Let┬┤s Encrypt.

F├╝r den Serverwechsel ergeben sich, auch mit Docker, zwei Herausforderungen:

  1. das ├ťbertragen der Daten von einem Server zum anderen
  2. das Ändern des Zugriffs auf den neuen Server

Docker Images oder die eigentlichen Container ├╝bertragen: muss in meinem Fall nicht sein.

Ich habe f├╝r jede Website ein docker-compose.yml -File erstellt. Die Files beinhalten alle Informationen f├╝r das Herunterladen der notwendigen Docker-Images und das Erstellen der Container. F├╝r das ├ťbersiedeln der Webservices muss ich die Images oder Container also nicht ├╝bertragen, da diese ├╝ber die docker-compose.yml-Files neu erstellt werden k├Ânnen. Anders bei den Container-Ordnern oder Volumes, diese beinhalten alle persistenten Daten meiner Container und spiegeln dessen Datenstand wider.

rsync und Bind-Mounts

Wer keine Volumes, sondern Bind-Mounts verwendet, kann die Ordner am Host-Dateisystem ablegen und mit dessen Tools einsehen und verwalten. F├╝r Linux-basierte Betriebssysteme k├Ânnen dessen Ordner mit rsync sehr einfach und schnell auf einen anderen Host ├╝bertragen werden. Mit den richten Parametern ├╝bertr├Ągt rsync beim ersten Aufruf alle Daten und bei weiteren Aufrufen nur noch die ge├Ąnderten Daten, was die Zeit erheblich minimiert. Bei meinem letzten Server konnte ich damit ca. 20GByte an Daten in unter einer Minute abgleichen.

Hier ein Beispiel um Ordner mittels rsync zu kopieren:

sudo rsync -rltD --delete -e ssh root@IPalterServer:/var/mydockerfolders/ /var/mydockerfolders

Entsprechende Berechtigungen vorausgesetzt, k├Ânnen Volumes aus dem Ordner "/var/lib/docker" wahrscheinlich auch problemlos mit rsync ├╝bertragen werden. Ich muss allerdings zugeben, dass ich dies noch nicht getestet habe. Da /var/lib/docker von Docker verwaltet wird, ist der direkte Zugriff darauf nicht der richtige Weg.

Alternative: Shared Storage

Eine Alternative zum ├ťbertragen der Daten w├Ąre der zentrale Zugriff auf eine Storage oder NAS. Wer beispielsweise einen zentralen Netzwerkspeicher, wie NFS, einsetzt und die Daten der Container darauf ablegt, ben├Âtigt f├╝r den neuen Server einzig einen Zugriff auf das Filesystem. Die Container k├Ânnten somit am alten Server gestoppt und einfach am neuen Server erstellt und gestartet werden.┬á

GlusterFS

Bei meiner Recherche nach einer alternativen Variante zu einer Shared Storage bin ich auch kurz bei GlusterFS h├Ąngen geblieben. GlusterFS kann bestimmte Ordner permanent und synchron zwischen Hosts ├╝ber das Netzwerk replizieren und bildet damit sowas wie eine verteilte Shared Storage.

Vorsicht bei Datenbanken: nicht im laufenden Betrieb kopieren

mysqldump

Datenbankfiles sollten nicht einfach im laufenden Betrieb kopiert werden, da die Kopie unter Umst├Ąnden nicht konsistent ist, siehe: Docker Backup

Docker Container stoppen, dann erst kopieren

Eine sehr universelle Variante um alle Daten konsistent zu ├╝bertragen, ist das Stoppen der Container am Quellserver und das Kopieren in ausgeschaltetem Zustand. Nat├╝rlich entsteht mit dieser Variante eine kurze Downtime. F├╝r das ├ťbersiedeln von Websites k├Ânnte diese Downtime eventuell in Kauf genommen werden, da die Services am alten Server f├╝r den Switch auf den neuen Server eventuell ohnehin kurz gestoppt werden m├╝ssen. F├╝r ein Backup ist diese Variante weniger geeignet, da dieses regelm├Ą├čig stattfinden soll: Es muss ja nicht jeder mitbekommen, dass die Website gerade gesichert wird.

Ändern des Zugriffs auf den Server

F├╝r das ├ändern des Zugriffs vom alten auf den neuen Server gibt es mehrere M├Âglichkeiten:

DNS-Änderung

Die wohl einfachste ├Ąlteste Variante ist das ├ändern der DNS-Eintr├Ąge auf die IP-Adresse des neuen Servers:

Siehe auch: Datenverkehr auf einen anderen Server weiterleiten. Die n├Ąchsten beiden Varianten habe ich selbst nicht im Einsatz, der Vollst├Ąndigkeit halber sollten sie dennoch nicht fehlen:

IP-Adresse auf den neuen Server anwenden

Bestimmte Provider bieten eine M├Âglichkeit die IP-Adresse von einem Server auf den anderen zu ├Ąndern: Floating IP.┬á

 

Alternativ kann eine IP je nach Provider eventuell auf einen neuen Server ├╝bertragen werden:

Load Balancer vorschalten

Wird ein Load Balancer eines Providers eingesetzt, verteilt dieser die Zugriffe auf verschiedene Server. Da der Zugriff auf den Load Balancer stattfindet, bleibt dessen IP-Adresse beim Austausch der Server bestehen.

Docker Swarm

Bevor ich dieses Mal meinen Webserver ├╝bersiedelt habe, habe ich Docker Swarm getestet. Mit Docker Swarm werden die Container ├╝ber eine gemeinsaem Netzwerkverbindung auf verschiedene Hosts verteilt. Zum Beispiel k├Ânnte ein Webcontainer auf einem Host laufen, dessen Datenbank-Container auf einem anderen. Docker Swarm l├Âst das Problem mit dem Zugriff, da alle Container ├╝ber alle Hosts eines gemeinsamen Swarms erreichbar sind. Docker Swarm k├╝mmert sich dabei nur um das Netzwerk, nicht aber um die verwendeten Volumes. Aus diesem Grund kann Swarm f├╝r Container eingesetzt werden die entweder keine persistenten Daten speichern m├╝ssen, oder in Kombination mit einem zentralen Netzwerkspeicher: Shared Storage, NAS oder verteilter zentraler Speicher, wie GlusterFS. Da ich bisher mit einem virtuellen Server auskomme, w├╝rde Docker-Swarm in meinem Fall mehr Overhead produzieren als Nutzen, auch wenn das gemeinsame Netzwerk beim ├ťbersiedeln des Servers durchaus hilfreich sein k├Ânnte. Auf der Suche nach einer alternativen M├Âglichkeit um Zugriffe von einem Server auf den anderen zu leiten bin mit Traefik f├╝ndig geworden, siehe: Traefik: Datenverkehr auf einen anderen Server weiterleiten. F├╝r das ├ťbertragen der Daten habe ich einfach den rsync-Befehl eingesetzt.

Siehe: Docker Compose vs. Docker Swarm: verwenden und verstehen

Weiterleitung des Datenverkehrs

Eine weite M├Âglichkeit den Zugriff auf einen anderen Server zu ├Ąndern, ist das Weiterleiten s├Ąmtlicher Anfragen auf den neuen Server, siehe: Traefik: Verkehr an einen anderen Server weiterleiten. Um die Zeit f├╝r den Serverwechsel m├Âglichst gering zu halten, habe ich bei meinem letzten Serverumzug den Datenverkehr weitergeleitet, bis die DNS-├änderung ├╝berall bekannt war.

In der Praxis: mein letzter Serverumzug

Mein einfaches Setup: Ordner (Bind-Mounts) und keine Volumes

Bei meinem Setup habe ich den Ordner /var/web am Server angelegt und darunter die einzelnen Webservices in eigenen Unterordnern.
Als Beispiel:

  • /var/web/libe.net und
  • /var/web/script-example.com

Im Root-Ordner der Webservices befindet sich das jeweilige docker-compose-File der jeweiligen Site und darunter die Ordner mit den persistenten Daten:

  • /var/web/libe.net/docker-compose.yml
  • /var/web/libe.net/www ... Ordner mit den Daten der Website
  • /var/web/libe.net/db .. Ordner mit den Datenbank-Files

Mit dieser Ordnerstruktur befinden sich alle relevanten Daten zentral unterhalb des Ordners /var/web. Da /var/web der einzige sch├╝tzenswerte Ordner auf dem Server ist, reicht es diesen zu backupen. Aber auch beim ├ťbersiedeln des Servers reicht es alle Container zu stoppen und einzig den Ordner /var/web auf den neuen Server zu ├╝bertragen und dort mit docker-compose wieder alle Services zu starten. Den Zugriff vom Internet auf die einzelnen Websites steuert der Traefik Reverse Proxy.

Die Downtime m├Âglichst gering halten

Bereits meine urspr├╝ngliche Idee f├╝r den Datentransfer war, den Inhalt aller Container-Ordner einfach mit dem Befehl rsync vom alten Server auf den neuen zu kopieren und die Container im Anschluss am neuen Server zu starten. Mit dieser Variante k├Ânnte ich ohne Downtime alle Websites am neuen Server parallel starten und im Anschluss den DNS auf den neuen Server ├Ąndern. Die Vorgehensweise hat aber Nachteile: Erstens ist das einfache Kopieren von Datenbanken im laufenden Betrieb etwas problematisch, siehe: mysql. Zweitens gibt es, solange der DNS nicht ├╝berall aktiv ist, eine gewisse ├ťbergangszeit, in der die Anfragen auf beiden Servern landen w├╝rden.┬á

Auf Kosten der Downtime, habe ich diesmal alle Container gestoppt, dann die Services ├╝bertragen und im Anschluss alle Zugriffe des alten Webservers auf den neuen weitergeleitet.

 

Ich habe mir folgende Vorgehensweise für den Umzug überlegt: 

Bestehender Server neuer Server
1) alle Docker-Container stoppen 3) alle Container stoppen
2) TCP-Umleitung starten 4) alle ge├Ąnderten Daten kopieren
  5) alle Container starten

 Um am Quellserver alle Container zu stoppen, kann folgender Befehl verwendet werden:

docker kill $(docker ps -q)

Das Weiterleiten aller Anfragen kann mit folgendem Setup erfolgen: Traefik: Datenverkehr auf einen anderen Server weiterleiten.

Zuletzt habe ich am Zielserver sicherheitshalber alle Container gestoppt, die letzten ├änderungen der Ordner mit rsync ├╝bertragen und dann alle Container gestartet. Damit die Downtime m├Âglichst gering gehalten werden kann, hab ich die Befehle in eine Bash-Datei geschrieben:┬á

File: target-actions.sh

#!/bin/bash
docker kill $(docker ps -q)
rsync -rltD --delete -e ssh root@IPalterServer:/var/web/ /var/web
cd /var/web/traefik
docker-compose up -d
cd /var/web/website1
docker-compose -d
cd /var/web/website2
docker-compose -d

Start der Bash-Datei:

chmod +x target-actions.sh
. /target-actions.sh

Nach dem Ausf├╝hren der Bash-Datei laufen die Container am neuen Server.┬áDamit der Zugriff direkt auf den neuen Server stattfindet, kann jetzt der DNS-Eintrag auf die IP-Adresse des neuen Servers ge├Ąndert werden. Wenn alle Container auf dem neuen Server laufen und ├╝ber den alten Container keine relevanten Zugriffe mehr umgeleitet werden, kann der alte Server ausgeschaltet und gel├Âscht werden.

Video

neuer Server: meine zus├Ątzlichen Pakete

Zus├Ątzlich zu Docker verwende ich am Webserver eine ├ťberwachung mit Glances und EARLYOOM.

├ťberwachung

Systeme ├╝berwachen: Monitoring in HomeAssistant mit Glances

Einsatz eines Webserver mit relativ wenig Arbeitsspeicher: RAM

Sollte ein Linux-Server an die Grenze des Arbeitsspeichers kommen, kann eventuell EARLYOOM diesen dennoch am Leben halten. EARLYOOM kann bestimmte Dienste stoppen, wenn der Speicher zur Neige geht: Wenn Ubuntu nicht mehr reagiert: Linux Memory Leak.

Fazit

Mit mehreren Servern und einem entsprechenden Cluster-Setup k├Ânnten die Container sicherlich noch einfacher verschoben werden, daf├╝r sind aber auch mehr Ressourcen und ein aufwendigeres und kostenintensiveres Setup notwendig. Wer nur einen Server f├╝r seine Websites verwendet, kann bestehende Docker-Container mit einem einfachen rsync-Befehl auf einen anderen Server ├╝bertragen und muss im Anschluss nur den Zugriff darauf ├Ąndern. Rsync kann zudem als einfaches Backup verwendet werden, siehe auch: Docker Backup

positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE f├╝r deine Bewertung!

Ver├Âffentlichung: 06.11.2022 von Bernhard ­čöö


Top-Artikel in diesem Bereich


ioBroker installieren - Docker
Mit ioBroker k├Ânnen verschiedene Automatisierungsl├Âsungen oder Ger├Ąte in einem System zusammengefasst werden. Um bestimmte Gateways oder Ger├Ąte ansprechen zu k├Ânnen, werden in ioBroker verschiedene Adapter verwendet.

Home-Assistant Docker Conbee 2 und Zigbee2MQTT / deCONZ
Dank zahlreicher Integrationsm├Âglichkeiten ist Home-Assistant eine einfache Plattform f├╝r das Steuern verschiedenster Smart-Home Ger├Ąte. Im Vergleich zu ioBroker ist mir der Start mit Home Assistant wesentlich einfacher gefallen. W├Ąhrend ich f├╝r ioBroker noch am Suchen war, welches Frontend ich f├╝r meine Dashboards verwenden k├Ânnte, hatte ich mit Home-Assistant out of the box ein fertig eingerichtetes System. Die Lovelance Dashboards von Home Assistant k├Ânnen einfach in der GUI zusammengeklickt...

Conbee 2: Phoscon deCONZ - Docker Inbetriebnahme | Review
Mit dem kleinen USB-Stick Conbee2 habe ich meinen NAS um ein Zigbee-Gateway erweitert. Conbee2 kann auf Raspbian, Ubuntu, Docker oder Windows installiert werden.

Fragen / Kommentare


Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu Mehr Details