SSH ist einer der am häufigsten verwendeten Befehle in der Toolbox eines Systemadministrators, wird jedoch neben Docker nicht häufig verwendet. So können Sie SSH in einen laufenden Container einbinden und warum Sie es sich zweimal überlegen sollten, bevor Sie es tun.
Sollten Sie SSH mit Docker-Containern verwenden?
SSH-ing in einen Docker-Container ist im Allgemeinen eine schlechte Praxis, die Sie vermeiden sollten. Es ist fast immer besser, die docker exec
zu verwenden Befehl, um eine Shell in einen Container zu bekommen.
Docker-Neulinge könnten versucht sein, SSH zu verwenden, um Dateien in einem Container zu aktualisieren. Container sollen jedoch wegwerfbar sein, also sollten sie nach der Erstellung als unveränderlich behandelt werden, mit Ausnahme von persistenten Daten, die in Volumes gespeichert sind. Erstellen Sie ein neues Image und starten Sie Ihren Container neu, wenn Sie den Quellcode bearbeiten.
Abgesehen von dem mehrstufigen Konfigurationsprozess fügt die Installation von SSH in einem Docker-Image mehrere Abhängigkeitspakete hinzu und legt einen weiteren potenziellen Angriffsvektor offen. Auf einem System mit mehreren aktiven Containern führen Sie mehrere unabhängige SSH-Prozesse aus und müssen sich den richtigen Port für jeden Container merken.
Anstatt SSH einzelnen Containern hinzuzufügen, installieren Sie es einmal auf dem physischen Host, auf dem Docker ausgeführt wird. Verwenden Sie SSH, um eine Verbindung zu Ihrem Host herzustellen, und führen Sie dann docker exec -it my-container bash
aus um auf einzelne Container zuzugreifen.
Während docker exec
der bevorzugte Ansatz ist, gibt es dennoch Szenarien, in denen SSH nützlich sein könnte. Sie könnten es als Notlösung für die Integration mit Legacy-Bereitstellungssystemen einführen. Es kann auch von einigen IDEs und Build-Tools verwendet werden, um Live-Reload-Funktionen während der Entwicklung bereitzustellen.
Installieren des SSH-Servers in einem Docker-Container
Die beliebtesten Docker-Basisimages werden absichtlich rationalisiert. Sie müssen den OpenSSH-Server selbst hinzufügen, selbst bei Images, die von gängigen Betriebssystem-Distributionen stammen.
Hier ist ein Beispiel für Dockerfile
für ein Debian-basiertes Image:
RUN apt-get update && apt-get install -y openssh-server RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config ENTRYPOINT service ssh start && bash
Die SSH-Konfiguration wurde geändert, sodass Sie sich als root
anmelden können , der Standardbenutzer in einem Docker-Container. Richten Sie für mehr Sicherheit stattdessen ein dediziertes Benutzerkonto ein:
RUN useradd -m -s /bin/bash sshuser
Dadurch wird ein neuer Benutzer namens sshuser
erstellt mit einem Heimatverzeichnis (-m
). Das -s
switch setzt die Standard-Login-Shell des Benutzers auf Bash.
Die Verwendung von ENTRYPOINT
stellt sicher, dass der SSH-Dienst immer dann startet, wenn der Container dies tut. Die Ausführung wird dann an Bash als Vordergrundprozess des Containers übergeben. Sie könnten dies durch die Binärdatei Ihrer Anwendung ersetzen.
Authentifizierung konfigurieren
Als nächstes müssen Sie ein Authentifizierungssystem einrichten. Sie könnten Ihrem sshuser
ein Passwort zuweisen Konto und melden Sie sich damit an:
RUN echo "sshuser:Changeme" | changepasswd
Eine sicherere Methode ist die Einrichtung der SSH-Schlüsselauthentifizierung. Sie müssen ein Schlüsselpaar auf Ihrem Client-Computer erstellen und dann den öffentlichen Teil in den Container kopieren. Auf diese Weise kann der SSH-Daemon die Identität Ihres Computers überprüfen, wenn Sie eine Verbindung herstellen.
Ändern Sie Ihr Dockerfile
um die .ssh
einzurichten Konfigurationsordner für Ihren Benutzer. Kopieren Sie einen öffentlichen Schlüssel aus Ihrem Arbeitsverzeichnis, entweder mit einem docker cp
Befehl oder ein COPY
Anweisung in der Dockerfile
. Im letzteren Fall würde der Schlüssel in das Bild eingebrannt und für jeden mit Zugriff sichtbar.
COPY id_rsa.pub /home/sshuser/.ssh/authorized_keys RUN chown -R sshuser:sshuser /home/sshuser/.ssh RUN chmod 600 /home/sshuser/.ssh/authorized_keys
Diese Befehlsfolge erstellt die authorized_keys
von SSH Datei mit dem id_rsa.pub
öffentlichen Schlüssel in Ihrem Arbeitsverzeichnis. Die Dateisystemberechtigungen werden an die Anforderungen von SSH angepasst.
Verbindung zum Container herstellen
Jetzt können Sie sich mit Ihrem Container verbinden. Führen Sie den Container mit Port 22 aus, der an den Host gebunden ist:
docker run -p 22:22 my-image:latest
Ausführen von ssh [email protected]
gibt Ihnen eine Hülle in Ihrem Container.
Sie können das Binden des Ports überspringen, wenn Sie eine Verbindung von der Maschine herstellen, die den Docker-Container hostet. Verwenden Sie docker inspect
um die IP-Adresse Ihres Containers zu erhalten, übergeben Sie sie dann an den SSH-Verbindungsbefehl.
docker inspect <id-or-name> | grep 'IPAddress' | head -n 1
Verwenden Sie den SSH-Client auf Ihrem Computer, um eine Verbindung zum Container herzustellen:
ssh [email protected] # OR ssh [email protected]
Sie müssen einen alternativen Port verwenden, wenn Sie einen separaten SSH-Server auf dem Host betreiben oder mehrere Container haben, die Port 22 benötigen. So initiieren Sie eine Verbindung, wenn SSH an Port 2220 gebunden ist:
docker run -p 22:2220 my-image:latest ssh [email protected] -p 2220
Container-Verknüpfungen mit SSH Config einrichten
Sie können Ihre SSH-Konfigurationsdatei bearbeiten, um Verbindungen zu einzelnen Containern zu vereinfachen. Bearbeiten Sie ~/.ssh/config
um Kurzform-Hosts mit vorkonfigurierten Ports zu definieren:
Host my-container HostName 172.17.0.1 Port 2220 User sshuser
Jetzt können Sie ssh my-container
ausführen direkt in Ihren Container fallen lassen. Dadurch ist es einfacher, mehrere Verbindungen zu jonglieren, ohne sich Container-IPs und -Ports merken zu müssen.
Verwenden Sie stattdessen Dockssh, um die Containerverwaltung zu vereinfachen
Das Dockssh-Projekt geht noch einen Schritt weiter, indem es einen weiteren Daemon bereitstellt, mit dem Sie ssh [email protected]
ausführen können , ohne manuelle SSH-Konfiguration. Sie müssen keinen SSH-Server in Ihren Containern installieren; Dockssh leitet SSH-Verbindungen automatisch weiter und führt die richtige docker exec
aus Befehl statt.
Sie müssen zuerst Redis installieren, um die Konfigurationsdaten von Dockssh zu speichern:
sudo apt install redis
Definieren Sie als Nächstes die Container, die Sie verfügbar machen möchten, indem Sie einen Redis-Eintrag mit dem Namen des Containers und einem Passwort für SSH-Verbindungen hinzufügen:
redis-cli set dockssh:my-container:pass "container-password-here"
Laden Sie dann Dockssh herunter:
sudo curl https://github.com/alash3al/dockssh/releases/download/v1.1.0/dockssh_linux_amd64 -O /usr/local/bin/dockssh sudo chmod +x /usr/local/bin/dockssh sudo ufw allow 22022 # Start DockSSH server dockssh
Jetzt können Sie sich mit Ihrem Container verbinden:
ssh [email protected] -p 22022
Dockssh lauscht standardmäßig auf Port 22022. Die Firewall wird geöffnet, um eingehende Verbindungen über den Port zuzulassen.
Sie werden beim Herstellen der Verbindung zur Eingabe des Container-Passworts aufgefordert. Dies wurde als container-password-here
festgelegt in unserem Redis-Eintrag oben.
Die Verwendung von Dockssh macht es einfach, SSH in eine große Anzahl von Docker-Containern einzubinden. Dieser Ansatz ist ideal, wenn Sie sich regelmäßig von einem Remote-Host aus mit Ihren Containern verbinden, da er den zweistufigen „SSH, dann docker exec
“ rationalisiert ”-Sequenz in einen einzigen, denkwürdigen Befehl.
Registrieren Sie Dockssh als Systemdienst für die langfristige Nutzung:
sudo nano /etc/systemd/system/dockssh.service
[Unit] Description=Dockssh service After=network.target [Service] type=simple Restart=always RestartSec=1 User=root ExecStart=/usr/local/bin/dockssh [Install] WantedBy=multi-user.target
Aktivieren Sie den Dienst mit systemctl
:
sudo systemctl enable dockssh.service sudo systemctl start dockssh
Dockssh wird jetzt automatisch gestartet, wenn Ihr System hochfährt.
Zusammenfassung
Die Kombination von SSH mit Docker-Containern wird allgemein als Anti-Pattern angesehen, hat aber dennoch seine Verwendung in Entwicklungs-, Test- und Legacy-Umgebungen. Wenn es keine Alternative gibt, können Sie den SSH-Server zu Ihrem Container hinzufügen, einen öffentlichen Schlüssel kopieren und sich über die IP des Containers oder eine Host-Port-Bindung verbinden.
Systemadministratoren, die eine große Anzahl von Docker-Containern aus der Ferne verwalten möchten, können Dockssh ausprobieren. Damit können Sie vertrautes ssh
ausführen Befehle über eine nahtlose Zuordnung hinter den Kulissen zu docker exec
, wodurch Sie das Beste aus beiden Welten erhalten, indem Sie unveränderte Bilder verwenden.