Nun endlich komme ich auch zu meinem ersten Blogeintrag, der sich um mein drittes Hobby, die Frickelei am Computer dreht. Auf der Arbeit habe ich ein kleines Projekt gemacht, dass mir ein CentOS mit Docker und Docker-Compose in einer VBox automatisiert installiert. Über dieses Projekt werde ich später einmal berichten (oder auch nicht ;-). Heute soll es darum gehen, wie ich einen Docker-Host auf einer lokalen VirtualBox Maschine (oder auch gerne jedem anderen Docker-Host) administriere. Das ganze aber nicht über die üblichen Docker Ports, sondern über SSH, was seitens Docker seit Version 18.09 unterstützt wird.
VBox und NAT
Der Vollständigkeit halber (und weil es natürlich interessant ist), will ich erst einmal zeigen, wie der Port einer bestehenden virtuellen Maschine in VirtualBox freigegeben wird.
Öffnet hierfür die Settings eurer virtuellen Maschine und wechselt in die Einstellungen für das Netzwerk. Dort muss als Verbindungstyp zwingend NAT eingetragen sein. Nutzt Ihr andere Verbindungstypen, entfällt dieser Schritt. Ist NAT angewählt, steht der Button “Port Weiterleitung” zur Verfügung.
In dem nun erscheinenden Dialog tragt Ihr die folgenden Verbindungsdetails ein:
- Name: SSH
- Protocol: TCP
- Host IP: 127.0.0.1
- Host Port: Frei wählbar. In meiner Umgebung hat jede VBox Maschine Ihren eigenen 10000er Bereich und ich hänge die Original Portnummer hinten an. In meiner dritten VBox für SSH also 30022.
- Guest IP: Bleibt leer
- Guest Port: 22
Nun könnt Ihr mit Putty oder einem anderen SSH Client eurer Wahl eine Verbindung zur virtuellen Maschine mit den Parametern 127.0.0.1:30022 aufbauen.
SSH – Zertifikats-basierte Authentifizierung
Nun geht es mit dem eigentlich Thema erst los. Wie stelle ich mit dem Docker Client eine Verbindung zu der Maschine her? Aus Gewohnheit (und weil ich zu faul bin es mit anderen Konsolen zu testen) nutze ich hier die folgend die GIT Bash. Ein Kollege (der mich auch zu diesem Artikel inspiriert hat) hat das ganze aber auch schon erfolgreich mit cygwin im Einsatz, die Nutzung mit anderen Systemen wie Putty oder Rebex sollte aber ebenfalls kein Problem darstellen. Mit OpenSSH for Windows habe ich selber vor einiger Zeit unter 1709 getestet und bin an diversen Problemen gescheitert, ggf. werde ich den Versuch mit der aktuellen Windows Version bei Zeiten nochmal nachholen.
Natürlich möchte ich mich nicht für jedes “docker ps” an der remote-machine authentifizieren. Daher kümmern wir uns erstmal um die Authentifizierung am SSH daemon mittels Zertifikat. Zu diesem Zweck wird ein private und ein public key benötigt. Der private key verbleibt an einem sicheren Ort auf eurer Maschine, der public key wird auf der VBox eingespielt. Solltet Ihr noch nicht über Keys verfügen, ruft Ihr einfach das command “ssh-keygen” in der GIT Bash auf und beantwortet alle nun folgenden Fragen.
Im nächsten Schritt muss der public-key auf die VBox kopiert werden. Die einfachste Möglichkeit ist die Verwendung des Commands ssh-copy-id und in allen Implementierungen verfügbar. Der Aufruf lautet:
ssh-copy-id admin@localhost –p 2022
Eine weitere Möglichkeit ist die manuelle Übertrag des public-keys. Die Vorgehensweise beschreibe ich nun folgend:
- Anmelden an der VBox via SSH oder in der VBox Konsole (ich empfehle SSH um auch Copy&Paste nutzen zu können).
- Es wird das SSH Verzeichnis wie folgt angelegt (Das setzen der Berechtigungen ist an dieser Stelle wichtig, andernfalls wird der SSH Daemon seinen Dienst verweigern):
- mkdir ~/.ssh
- chmod 700 ~/.ssh
- touch ~/.ssh/authorized_keys
- chmod 600 ~/.ssh/authorized_keys
- Nun könnt Ihr mit einem Editor eurer Wahl die Datei “authorized_keys” editieren und euren Key mit folgendem Format dort einfügen:
ssh-rsa AAAAXS............qv+OvaQ== <comment>
Ist der public-key auf der remote Maschine gespeichert, muss lokal dafür gesorgt werden, dass das Kennwort des private keys nicht bei jedem Verbindungsaufbau eingegeben werden muss. Das speichern des private-keys übernimmt der SSH-Agent der zu diesem Zweck gestartet werden muss. Nach dem Start wird der private key mit dem Command “ssh-add” hinzugefügt. Um den SSH-Agent permanent zu starten, könnt Ihr diesen Artikel zu Rate ziehen.
Connect
Nun öffne dein Terminal und versuche eine Verbindung via SSH mit
“ssh admin@127.0.0.1 -p 30022“. Funktioniert dies nun ohne jede Authentifizierung, können wir nun Docker installieren. Da die Installation von Docker auf Windows per default nur in vollem Umfang mit Aktivierung der entsprechenden Windows Rolle funktioniert gehe ich hier gerne einen anderen Weg. Ich nutze zur Installation das chocolatey repository. Zur Installation des Docker clients mit chocolatey geht Ihr wie folgt vor:
- Download und Installation von chocolatey von https://chocolatey.org/install.
- Start einer Powershell session mit administrativen privilegien.
- Ausführen von “choco install docker” und “choco install docker-compose“.
- Wollt Ihr später die Installation aktualisieren, ruft cup all (choco upgrade all) in einer administrativen Powershell session auf.
Ruft nun folgendes Kommando auf, um euch eine Liste aller laufenden Container auf der remote Maschine anzuzeigen.
Woll Ihr euch die Eingabe des Host mit dem “-H” parameter sparen, könnt Ihr auch die variable DOCKER_HOST mit “ssh://127.0.0.1:30022” befüllen. Nu reicht die Eingabe von “docker ps” aus.
Um die DOCKER_HOST variable dauerhaft nutzen zu können tragt das Kommando “export DOCKER_HOST=ssh://127.0.0.1:30022” in eure “.bashrc” Datei ein, die Ihr in der Regel auf der root Ebene eures Userverzeichnisses findet.
MinTTY
Habt Ihr den Git client mit der Option “Use MinTTY” installiert, kann es passieren, dass Ihr die Fehlermeldung “the input device is not a TTY. If you are using mintty, try prefixing the command with ‘winpty’” erhaltet, wenn Ihr versucht Kommandos aufzurufen, die eine Interaktion innerhalb der Konsole erfordern (Beispiel: docker exec -it <id> /bin/sh). Im Falle von Git wäre es eine Möglichkeit, die Installation von Git zu wiederholen und die Option entsprechend umzustellen.
Die andere Möglichkeit ist, wie in der Fehlermeldung beschrieben, den Prefix winpty zu nutzen. Was die Fehlermeldung allerdings nicht verrät: In diesem Fall müsst Ihr auch die slashes verdoppeln. Also gilt für obiges Kommando:
winpty docker exec -it a7ef25a484ba //bin//sh
Danach könnt Ihr wie gewohnt weiter arbeiten (Müssst also die slashes nicht wiederholen).
Nutzt Ihr cygwin muss winpty zuvor heruntergeladen werden und der winpty Installationspfad in die PATH variable aufgenommen werden.
Fazit
Mit dieser Lösung habt Ihr die Möglichkeit, einen remote docker-daemon so zu verwalten als würde dieser lokal laufen. Zudem ist dieses Verfahren gut mit evt. vorhandenen Firewalls machbar, da SSH im besten Fall freigeschaltet ist. Die 5-10 Minuten Aufwand die in diese Lösung gesteckt werden muss, habt ihr (meiner Meinung nach) in sehr kurzer Zeit wieder drinnen.
1 Gedanke zu „Docker Connection über SSH“