Sonntag, 15. August 2010

netcat, dd und ganz viel Spaß

Die Problemstellung

Da ist ein Server, der einen kritischen Dienst bedient; leider ist dieser Server restlos veraltet (sowohl aus Hard- als auch aus Software-Sicht), und ein Update des kritischen Dienstes nicht so ohne weiteres möglich. Sie möchten den Datenbestand am liebsten 1:1 auf eine andere Maschine ziehen und auf dieser, ganz in Ruhe, einige Testläufe starten, Dinge probieren und einen Workflow zur Lösung dieses Problems entwickeln. Allerdings ist auf dem laufenden Server viel zu wenig Platz, als daß Sie ein Image des Systems machen und anschließend auf die neue Maschine übertragen könnten.

Ein möglicher Lösungsansatz


Ein guter Einsatzzweck für virtuelle Maschinen. Das zugrundeliegende System ist hier ein MacOS 10.6.3 mit Parallels 5; natürlich läßt sich das jedoch auf nahezu jedes beliebige Hostsystem und nahezu jede beliebige Virtualisierungssoftware übertragen. Der erste Schritt besteht darin, eine Standardinstallation eines Betriebssystems Ihrer Wahl durchzuführen – im folgenden Ubuntu genannt. Diese Prozedur ist in keiner Form außergewöhnlich und wird deshalb an dieser Stelle auch nicht weiter erläutert. Dieser virtuellen Maschine wird eine zweite virtuelle Festplatte untergeschoben — deren Größe orientiert sich an der Größe Quellsystems, in meinem Fall 10GB. Übers Netz wird aus dem virtuellen Ubuntu heraus ein vollständiger Dump des laufenden Quellsystems auf die zweite virtuelle Platte heraus vorgenommen. Schlußendlich wird über einen grub-Eintrag sichergestellt, daß das virtuelle System Dual-Boot-fähig ist und wahlweise nun entweder das ursprünglich installierte (Ziel-)Ubuntu oder aber der virtuelle (Quell-)Server gestartet werden kann. In diesem virtuellen Server können nun die benötigten Testläufe initiiert werden, und wenn man etwas schrottet, ist das gar nicht schlimm – die virtuelle Maschine läßt sich leicht wiederherstellen.

1. Die zweite virtuelle Platte einrichten

Nachdem dem Sytsem in der Parallels-Konfiguration eine zweite virtuelle Platte definiert wurde (vgl. Screenshot) und das virtualisierte Ubuntu gestartet ist, muß diese zweite Platte eingerichtet werden; wurde sie nachträglich definiert, wird sie naturgemäß beim Booten des Systems natürlich nicht erkannt. Also ersteinmal schauen, ob er sie überhaupt hat:

$ dmesg | grep sd
[ 0.936360] sd 0:0:0:0: Attached scsi generic sg0 type 0
[ 0.936780] sd 1:0:1:0: Attached scsi generic sg1 type 0
[ 0.936837] sd 0:0:0:0: [sda] 20972448 512-byte logical blocks: (10.7 GB/10.0 GiB)
...
[ 0.936946] sd 1:0:1:0: [sdb] 20972448 512-byte logical blocks: (10.7 GB/10.0 GiB)

...

Sieht schwer danach aus; sda ist ja unsere erste Festplatte, also die, auf der das Ubuntu liegt; sdb ist noch jungfräulich und leer, da wird nun das Serversystem draufgezogen…

2. Das System portieren

a) Auf dem Zielsystem

Auf dem Zielrechner, also in der Ubuntu-VM, wird ein Port geöffnet, über den die Daten hereinmarschieren und direkt auf die Platte /dev/sdb geschrieben werden:

root@ziel$ netcat -l 443 | dd of=/dev/sdb

In diesem Fall läuft der Transfer über Port 443, da die restriktiven Firewall-Regeln einen Extra-Eintrag für einen anderen Port erfordern würden. Nun kann der Transfer gestartet werden.

b) Auf dem Quellsystem

Vom Quellsystem aus wollen wir den gesamten Inhalt der Platte (in diesem Falle heißt sie /dev/sda1) übertragen; dies initiieren wir mit folgendem Befehl:

root@quelle$ dd if=/dev/sda1 | netcat ziel 443

Nun werden die Daten übertragen.

c) Den Fortschritt beobachten

Während der Übertragung, die — je nach Netzaustattung und Datenmenge — durchaus eine ganze Weile dauern kann, lungern nun zwei offene Shells auf dem Desktop herum, doch eine Statusanzeige gibt keine von beiden. Es gibt jedoch eine Möglichkeit, nämlich dem dd-Prozeß auf dem Zielhost ein USR1 zu schicken:

root@ziel$ ps aux | grep dd
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
...
root 1563 0.0 0.0 3396 772 pts/0 S+ 15:38 0:00 dd of=/dev/sdb
...
root@ziel$ kill -USR1 1563

Das ergibt in der Shell des Zielsystems (in der der dd-Aufruf aktiv ist) eine Ausgabe in der Form:

2+1 records in
2+0 records out
1024 bytes (1.0kB) copied, 54.0942s, 24.2 kB/s

Entweder man entwirft sich einen Aufruf, der das automatisch alle paar Sekunden ausführt, oder man führt es manuell von Zeit zu Zeit aus — so sieht man jedenfalls, wieviele Daten bereits übertragen wurden. Die Übertragung ist beendet, wenn auch auf dem Quellrechner eine Ausgabe der Form »1196 bytes transferred in 0.000089 seconds (13431951 bytes/sec)« erscheint.

3. grub installieren

In meinem Fall war das mit einem simplen Aufruf erledigt:

root@zielrechner$ grub-install --force /dev/sdb

Hierdurch wurde meine grub-Konfig um folgende Zeilen erweitert:

## /boot/grub/grub.cfg
menuentry "Debian GNU/Linux, kernel 2.6.x (on /dev/sdb)" {
recordfail
insmod xfs
set root='(hd1,1)'
search --no-floppy --fs-uuid --set fb0a4e3a-0457-454d-8650-0bf853d17530
linux /boot/vmlinuz-2.6.x root=/dev/sdb
root=/dev/hdd ro

Damit funktioniert das Booten noch nicht wirklich: schauen Sie nochmal auf den Parallels-Screenshot. Die zweite Platte wurde als »Location IDE 1:1« definiert, sprich: als zweites Gerät am zweiten Controller, also hdd (die erste Platte ist auf »Location IDE 0:0« definiert und somit das erste Gerät am ersten Controller, also hda). Es muß also das oben stehende root=/dev/sdb durch root=/dev/hdd ersetzt werden.

Und das ist auch schon alles — nun kann das portierte System virtuell gestartet werden

4. Vorsicht!

Vor dem ersten Start des portierten Systems sollten sie sicherstellen, daß beim Booten nichts getötet werden kann; prüfen Sie beispielsweise sorgfältig, daß es nicht zu IP- oder DNS-Konflikten kommen kann, wenn Sie den ursprünglichen Server und Ihre virtualisierte Version parallel ins Netz hängen! Sorgen Sie weiterhin dafür, daß Dienste, die alle User im Netz betreffen können — DHCP beispielsweise — nicht das gesamte Netzwerk verwirren oder gar lahmlegen! Überlegen Sie sorgfältig, um welche Dienste es sich in Ihrem Falle konkret handeln könnte, und handeln Sie mit Bedacht.

Im laufenden Ubuntu-System können Sie die zweite Platte leicht mounten:

root@ziel$ mount /dev/sdb /mnt

Wenn nötig, führen Sie noch ein chroot /mnt aus; durchforsten Sie nun das System vor dem ersten Booten auf Dinge, die den laufenden Betrieb stören könnten. Starten Sie das System nur dann, wenn Sie sich sicher sind, daß es funktionieren wird. Starten Sie es sonst ausschließlich ohne Netzwerkinterface.

Keine Kommentare: