Wie SSH in Docker?

87

Ich möchte den folgenden Infrastrukturfluss erstellen:

Wie kann das mit Docker erreicht werden?

Kamil Lelonek
quelle

Antworten:

66

Zunächst müssen Sie einen SSH-Server in den Images installieren, in die Sie ssh-in möchten. Sie können ein Basis-Image für Ihren gesamten Container verwenden, auf dem der SSH-Server installiert ist. Dann müssen Sie nur noch jeden Container ausführen, der den ssh-Port (Standard 22) einem der Ports des Hosts (Remote Server in Ihrem Image) zuordnet -p <hostPort>:<containerPort>. dh:

docker run -p 52022:22 container1 
docker run -p 53022:22 container2

Wenn dann von außen auf die Ports 52022 und 53022 des Hosts zugegriffen werden kann, können Sie mithilfe der IP-Adresse des Hosts (Remote Server), auf der der Port in ssh mit angegeben ist, direkt zu den Containern ssh -p <port>. Dh:

ssh -p 52022 myuser@RemoteServer -> SSH zu container1

ssh -p 53022 myuser@RemoteServer -> SSH zu container2

Javier Cortejoso
quelle
Und wie können diese Häfen der Außenwelt ausgesetzt werden? Ich meine, ob es eine Möglichkeit gibt, es ohne Nginx zu konfigurieren?
Kamil Lelonek
2
@squixy: Sie sind nur Ports auf Ihrem Host. Belichten Sie sie einfach auf die gleiche Weise wie für andere Anwendungen. Möglicherweise funktioniert es nur, oder Sie müssen möglicherweise Ports in Ihrer Firewall öffnen.
Adrian Mouat
Ich verstehe nur, wie Domain-Namen am besten Ports zugeordnet werden können, aber ich glaube, dass NginX die Lösung ist, die ich einfach implementieren kann.
Kamil Lelonek
Was ist container1? Wenn ich "Docker <Name> ausführen", wird der <Name> als Bildname interpretiert, sodass Docker in Repos nach einem Bild sucht. Meine Container-ID funktioniert nicht mit Docker-Lauf. Ich benutze "Docker Start <ContainerID>", um den Container zu starten, aber Docker Start akzeptiert den Parameter -p nicht.
MVMN
1
Wenn der Docker-Benutzer "root" ist, müssen Sie dem Benutzer root über "passwd root" ein Kennwort geben. Auch ich fand das funktioniert: Docker run -p 52022: 22 container1 service ssh start -D FOREGROUND
CMP
41

Hinweis : Diese Antwort bewirbt ein Tool, das ich geschrieben habe.

Die hier ausgewählte Antwort schlägt vor, in jedem Image einen SSH-Server zu installieren. Konzeptionell ist dies nicht der richtige Ansatz ( https://docs.docker.com/articles/dockerfile_best-practices/ ).

Ich habe einen containerisierten SSH-Server erstellt, an den Sie sich an jeden laufenden Container halten können. Auf diese Weise können Sie mit jedem Container Kompositionen erstellen. Die einzige Voraussetzung ist, dass der Container Bash hat.

Im folgenden Beispiel wird ein SSH-Server gestartet, der an Port 2222 des lokalen Computers verfügbar gemacht wird.

$ docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

$ ssh -p 2222 localhost

Weitere Hinweise und Dokumentationen finden Sie unter: https://github.com/jeroenpeeters/docker-ssh

Dies macht nicht nur die Idee eines Prozesses pro Container zunichte, sondern ist auch ein umständlicher Ansatz bei der Verwendung von Images aus dem Docker Hub, da diese häufig keinen SSH-Server enthalten (und sollten).

Jeroen Peeters
quelle
5
Dies sollte die richtige Antwort sein. Die Installation des SSH-Servers in jedem gewünschten Image widerspricht dem Docker. Sie sollten nur einen Dienst pro Container haben und Anwendungen aus Diensten / Containern erstellen.
Babbata
2
@JeroenPeeters Ich denke, eine weitere Voraussetzung ist "Der Docker-Socket ist dem Container zugeordnet, damit der Container auf die Docker Engine zugreifen kann."
Nam G VU
1
Was ist "Jeroenpeeter" im obigen Befehl? Ist es ein Benutzername auf dem Container?
Pratik Patil
1
@PratikPatil sein Teil des Bildnamens. hub.docker.com/r/jeroenpeeters/docker-ssh
Jeroen Peeters
13

Diese Dateien öffnen sshd erfolgreich und führen den Dienst aus, sodass Sie ssh lokal einbinden können. (Sie benutzen Cyberduck, nicht wahr?)

Dockerfile

FROM swiftdocker/swift
MAINTAINER Nobody

RUN apt-get update && apt-get -y install openssh-server supervisor
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 22
CMD ["/usr/bin/supervisord"]

Supervisord.conf

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

Startdämon erstellen / ausführen / in Shell springen.

docker build -t swift3-ssh .  
docker run -p 2222:22 -i -t swift3-ssh
docker ps # find container id
docker exec -i -t <containerid> /bin/bash

Geben Sie hier die Bildbeschreibung ein

Johndpope
quelle
2
Hey, schöne Antwort. Mein Container wird gestartet und fordert mich auf, mich anzumelden. Sind die Anmeldeinformationen jedoch "root" und "password"? Das scheint bei mir nicht zu funktionieren, aber ich mag Ihre Lösung und möchte sie nutzen.
Jabari Dash
Ich bin mir nicht sicher - ich habe Probleme beim Erreichen von Port 22 - stellen Sie sicher, dass Sie Port 2222 verwenden, da auf dem lokalen Gerät häufig Probleme auftreten können, die mit diesem Port in Konflikt stehen.
Johndpope
Diese Zeile ('PermitRootLogin ohne Passwort') in / etc / ssh / sshd_config ist standardmäßig auskommentiert. Verwenden Sie stattdessen 's / # PermitRootLogin ohne Passwort / PermitRootLogin yes /'. Möglicherweise müssen Sie für Ubuntu 16.04+ auch "Passwort verbieten" anstelle von "ohne Passwort" verwenden. Sie können sicher in Container ausführen, um im Voraus zu überprüfen.
ItsJack
10

Ich denke es ist möglich. Sie müssen lediglich einen SSH-Server in jedem Container installieren und einen Port auf dem Host verfügbar machen. Das größte Ärgernis wäre, die Zuordnung von Port zu Container beizubehalten / sich daran zu erinnern.

Ich muss mich jedoch fragen, warum Sie dies tun möchten. SSH'ng in Container sollte selten genug sein, dass es kein Problem ist, ssh zum Host zu senden und dann Docker Exec zu verwenden, um in den Container zu gelangen.

Adrian Mouat
quelle
Daher möchte ich meine Umgebung so modellieren, wie ich Container pro Projekt erstelle. Jedes Projekt hat also seine eigene Umgebung, Benutzer, Datenbanken, Python / Ruby-Version und so weiter. Ich möchte Projekte isolieren, ohne mehrere Server zu erstellen.
Kamil Lelonek
1
@squixy; OK. Normalerweise enthalten Docker-Container nur einen einzigen Prozess - idiomatisch sollten Sie separate Container für MySQL, PHP und Apache haben. Ich bin mir nicht sicher, wie gut das für Sie funktionieren wird.
Adrian Mouat
Ich weiß, kennen Sie eine bessere Lösung für meinen Fall?
Kamil Lelonek
1
@squixy es hängt von vielen Dingen ab. Ich würde empfehlen, jeden Container in mehrere Container aufzuteilen. Wofür brauchst du ssh? Wenn es nur Wartung ist, warum können Sie nicht in den Host ssh dann Docker Exec? Ich fürchte, es ist eine zu große Frage, um sie in einem Kommentar zu beantworten.
Adrian Mouat
Wie Adrian schreibt, stellen Sie fest, dass Container! = Virtuelle Maschinen sind, sobald Sie den Dreh raus haben, Docker zu verwenden. Es ist praktisch (Wortspiel beabsichtigt) nicht erforderlich, interaktiven Zugriff auf laufende Container zu erhalten.
mzedeler
8

Erstellen Sie ein Docker-Image mit openssh-servervorinstalliertem:

Dockerfile

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

Erstellen Sie das Bild mit:

$ docker build -t eg_sshd .

Führen Sie einen test_sshdContainer aus:

$ docker run -d -P --name test_sshd eg_sshd
$ docker port test_sshd 22

0.0.0.0:49154

Ssh zu Ihrem Container:

$ ssh [email protected] -p 49154
# The password is ``screencast``.
root@f38c87f2a42d:/#

Quelle: https://docs.docker.com/engine/examples/running_ssh_service/#build-an-eg_sshd-image

Nutzername
quelle
Es ist erwähnenswert, dass Sie für Mac OS X versuchen können, ssh root@localhost -p <ssh_host_port>die Anweisungen hier zu
Claudio Santos