Come eseguire l'SSH in Docker?


90

Vorrei creare il seguente flusso di infrastruttura:

Come è possibile ottenerlo utilizzando Docker?

Risposte:


70

In primo luogo è necessario installare un server SSH nelle immagini in cui si desidera eseguire l'SSH. Puoi usare un'immagine di base per tutto il tuo contenitore con il server ssh installato. Quindi devi solo eseguire ogni contenitore mappando la porta ssh (predefinita 22) su una delle porte dell'host (Server remoto nella tua immagine), usando -p <hostPort>:<containerPort>. cioè:

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

Quindi, se le porte 52022 e 53022 degli host sono accessibili dall'esterno, puoi direttamente ssh ai contenitori utilizzando l'ip dell'host (Remote Server) specificando la porta in ssh con -p <port>. Cioè:

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

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


E come esporre queste porte al mondo esterno? Voglio dire, se c'è la possibilità di configurarlo senza nginx?
Kamil Lelonek

2
@squixy: sono solo porte sul tuo host; esporli allo stesso modo delle altre applicazioni. Potrebbe funzionare o potrebbe essere necessario aprire le porte nel firewall.
Adrian Mouat

Capisco, mi chiedo solo qual è il modo migliore per mappare i nomi di dominio alle porte, ma credo che NginX sia la soluzione che posso facilmente implementare.
Kamil Lelonek

Cos'è container1? Quando eseguo "docker run <name>", <name> viene interpretato come nome dell'immagine, quindi docker cerca un'immagine nei repository. Il mio ID contenitore non funziona con docker run. Uso "docker start <containerID>" per avviare container, ma docker start non accetta il parametro -p.
mvmn

1
Se l'utente Docker è "root", sarà necessario fornire una password all'utente root tramite "passwd root". Inoltre ho trovato che funziona: docker run -p 52022: 22 container1 service ssh start -D FOREGROUND
CMP

42

Avviso : questa risposta promuove uno strumento che ho scritto.

La risposta selezionata qui suggerisce di installare un server SSH in ogni immagine. Concettualmente questo non è l'approccio giusto ( https://docs.docker.com/articles/dockerfile_best-practices/ ).

Ho creato un server SSH containerizzato che puoi "attaccare" a qualsiasi container in esecuzione. In questo modo puoi creare composizioni con ogni contenitore. L'unico requisito è che il contenitore abbia bash.

Il seguente esempio avvia un server SSH esposto sulla porta 2222 della macchina locale.

$ 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

Per ulteriori suggerimenti e documentazione, vedere: https://github.com/jeroenpeeters/docker-ssh

Non solo questo vanifica l'idea di un processo per contenitore, ma è anche un approccio complicato quando si utilizzano immagini dal Docker Hub poiché spesso non (e non dovrebbero) contenere un server SSH.


6
Questa dovrebbe essere la risposta corretta. L'installazione del server SSH in ogni immagine che desideri va contro il grano di finestra mobile. Dovresti avere un solo servizio per contenitore e dovresti comporre applicazioni da servizi / contenitori.
babbata

2
@JeroenPeeters Immagino che un altro prerequisito sia "Il socket Docker è mappato nel contenitore, questo consente al contenitore di accedere al Docker Engine".
Nam G VU

1
Che cos'è "jeroenpeeters" nel comando precedente? È un nome utente nel contenitore?
Pratik Patil

1
@PratikPatil fa parte del nome dell'immagine. hub.docker.com/r/jeroenpeeters/docker-ssh
Jeroen Peeters

13

Questi file apriranno correttamente sshd ed eseguiranno il servizio in modo da poter accedere a ssh localmente. (stai usando cyberduck, vero?)

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

per costruire / eseguire avvia il demone / salta nella shell.

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

inserisci qui la descrizione dell'immagine


2
Ehi, bella risposta. Il mio contenitore si apre e mi chiede di accedere, ma le credenziali sono "root" e "password"? Non sembra funzionare per me, ma mi piace la tua soluzione e voglio usarla.
Jabari Dash

Non sono sicuro - ho avuto problemi a colpire la porta 22 - assicurati di utilizzare la porta 2222 poiché spesso le cose potrebbero essere aperte sul dispositivo locale per entrare in conflitto con quella porta.
johndpope

questa riga ('PermitRootLogin senza password') in / etc / ssh / sshd_config è commentata per impostazione predefinita, quindi usa invece 's / # PermitRootLogin senza password / PermitRootLogin yes /'. Potrebbe anche essere necessario utilizzare "proibisci password" invece di "senza password" per Ubuntu 16.04+. Puoi sicuramente eseguire il controllo nel container per controllare in anticipo.
ItsJack

10

Immagino sia possibile. Devi solo installare un server SSH in ogni container ed esporre una porta sull'host. Il fastidio principale sarebbe mantenere / ricordare la mappatura del porto al container.

Tuttavia, devo chiedermi perché vorresti farlo. SSH'ng nei contenitori dovrebbe essere abbastanza raro da non essere un problema per ssh all'host, quindi usa docker exec per entrare nel contenitore.


Quindi voglio modellare il mio ambiente nel modo in cui creo container per progetto. Quindi ogni progetto ha il proprio ambiente, utente, database, versione python / ruby ​​e così via. Voglio isolare i progetti senza creare più server.
Kamil Lelonek

1
@squixy; ok. Normalmente i contenitori docker contengono solo un singolo processo - idiomaticamente dovresti avere contenitori separati per mysql, php e apache. Non sono sicuro di come questo funzionerà per te.
Adrian Mouat

Lo so, conosci una soluzione migliore per il mio caso?
Kamil Lelonek

1
@squixy dipende da molte cose. Consiglierei di suddividere ogni contenitore in più contenitori. Per cosa hai bisogno di ssh? Se è solo manutenzione, perché non puoi eseguire ssh nell'host e poi docker exec? Temo che sia una domanda troppo grande per rispondere in un commento.
Adrian Mouat

Come scrive Adrian, una volta che hai imparato a usare Docker, ti rendi conto che i contenitori! = Macchine virtuali. Non c'è virtualmente (gioco di parole) nessuna necessità di ottenere l'accesso interattivo ai contenitori in esecuzione.
mzedeler

8

Crea un'immagine docker con openssh-serverpreinstallato:

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"]

Costruisci l'immagine usando:

$ docker build -t eg_sshd .

Esegui un test_sshdcontenitore:

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

0.0.0.0:49154

Ssh nel tuo contenitore:

$ ssh root@192.168.1.2 -p 49154
# The password is ``screencast``.
root@f38c87f2a42d:/#

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


Vale la pena ricordare che per mac os x puoi provare a ssh root@localhost -p <ssh_host_port>seguire le istruzioni qui
Claudio Santos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.