Jak połączyć się przez SSH z Dockerem?

89

Chciałbym utworzyć następujący przepływ infrastruktury:

Jak można to osiągnąć za pomocą Dockera?

Kamil Lelonek
źródło

Odpowiedzi:

69

Najpierw musisz zainstalować serwer SSH na obrazach, do których chcesz ssh-do. Możesz użyć obrazu podstawowego dla całego kontenera z zainstalowanym serwerem ssh. Następnie wystarczy uruchomić każdy kontener mapujący port ssh (domyślnie 22) do jednego z portów hosta (serwer zdalny na obrazie), używając -p <hostPort>:<containerPort>. to znaczy:

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

Następnie, jeśli porty 52022 i 53022 hostów są dostępne z zewnątrz, możesz bezpośrednio ssh do kontenerów za pomocą adresu IP hosta (serwera zdalnego), określając port w ssh za pomocą -p <port>. To znaczy:

ssh -p 52022 myuser@RemoteServer -> SSH do kontenera1

ssh -p 53022 myuser@RemoteServer -> SSH do kontenera 2

Javier Cortejoso
źródło
A jak wystawić te porty na świat zewnętrzny? Chodzi mi o to, czy istnieje możliwość skonfigurowania go bez nginx?
Kamil Lelonek
2
@squixy: to tylko porty na twoim hoście; po prostu eksponuj je w taki sam sposób, jak w przypadku innych aplikacji. Może po prostu zadziałać lub może być konieczne otwarcie portów w zaporze.
Adrian Mouat
Rozumiem, po prostu zastanawiam się, jaki jest najlepszy sposób mapowania nazw domen na porty, ale uważam, że NginX jest rozwiązaniem, które mogę łatwo wdrożyć.
Kamil Lelonek
Co to jest pojemnik1? Kiedy robię „docker run <name>”, <nazwa> jest interpretowana jako nazwa obrazu, więc docker szuka obrazu w repozytoriach. Mój identyfikator kontenera nie działa z uruchomieniem platformy Docker. Używam „docker start <containerID>” do uruchomienia kontenera, ale docker start nie akceptuje parametru -p.
mvmn
1
Jeśli użytkownik Dockera to „root”, będziesz musiał podać użytkownikowi root hasło poprzez „passwd root”. Również znalazłem to działa: docker run -p 52022: 22 container1 service ssh start -D FOREGROUND
CMP
42

Uwaga : ta odpowiedź promuje napisane przeze mnie narzędzie.

Wybrana tutaj odpowiedź sugeruje zainstalowanie serwera SSH w każdym obrazie. Koncepcyjnie nie jest to właściwe podejście ( https://docs.docker.com/articles/dockerfile_best-practices/ ).

Utworzyłem kontenerowy serwer SSH, który możesz „przykleić” do dowolnego działającego kontenera. W ten sposób możesz tworzyć kompozycje z każdym pojemnikiem. Jedynym wymaganiem jest to, aby kontener miał bash.

Poniższy przykład spowoduje uruchomienie serwera SSH udostępnionego na porcie 2222 komputera lokalnego.

$ 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

Aby uzyskać więcej wskazówek i dokumentacji, zobacz: https://github.com/jeroenpeeters/docker-ssh

To nie tylko podważa ideę jednego procesu na kontener, ale jest także uciążliwym podejściem podczas korzystania z obrazów z Docker Hub, ponieważ często nie zawierają one (i nie powinny) zawierać serwera SSH.

Jeroen Peeters
źródło
6
To powinna być prawidłowa odpowiedź. Instalowanie serwera SSH na każdym obrazie, który chcesz, jest sprzeczne z doku. Powinieneś mieć tylko jedną usługę na kontener i powinieneś tworzyć aplikacje z usług / kontenerów.
babbata
2
@JeroenPeeters Wydaje mi się, że kolejnym warunkiem wstępnym jest „Gniazdo Dockera jest mapowane na kontener, co umożliwia kontenerowi dostęp do silnika Docker”.
Nam G VU
1
Co to jest „jeroenpeeters” w powyższym poleceniu? Czy to nazwa użytkownika na kontenerze?
Pratik Patil
1
@PratikPatil jego część nazwy obrazu. hub.docker.com/r/jeroenpeeters/docker-ssh
Jeroen Peeters
13

Te pliki pomyślnie otworzą sshd i uruchomią usługę, dzięki czemu możesz ssh lokalnie. (używasz cyberkaczki, prawda?)

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

zbudować / uruchomić uruchomić demona / wskoczyć do powłoki.

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

wprowadź opis obrazu tutaj

johndpope
źródło
2
Hej, miła odpowiedź. Mój kontener pojawia się i prosi o zalogowanie się, ale czy poświadczenia są „root” i „hasło”? Wydaje mi się, że to nie działa, ale podoba mi się Twoje rozwiązanie i chcę z niego skorzystać.
Jabari Dash
nie jestem pewien - napotkałem problemy z wejściem na port 22 - upewnij się, że używasz portu 2222, ponieważ często rzeczy mogą być otwarte na urządzeniu lokalnym i powodować konflikt z tym portem.
johndpope
ta linia ('PermitRootLogin without-password') w / etc / ssh / sshd_config jest domyślnie zakomentowana, więc zamiast tego użyj 's / # PermitRootLogin without-password / PermitRootLogin yes /'. Być może będziesz musiał użyć „zakazu hasła” zamiast „bez hasła” dla Ubuntu 16.04+. Możesz na pewno wykonać do kontenera, aby sprawdzić z wyprzedzeniem.
ItsJack
10

Myślę, że to możliwe. Wystarczy zainstalować serwer SSH w każdym kontenerze i udostępnić port na hoście. Główną przeszkodą byłoby utrzymanie / zapamiętanie mapowania portu do kontenera.

Muszę jednak zapytać, dlaczego chcesz to zrobić. SSH'ng do kontenerów powinno być na tyle rzadkie, że nie jest problemem ssh do hosta, a następnie użyj docker exec, aby dostać się do kontenera.

Adrian Mouat
źródło
Dlatego chcę modelować swoje środowisko w taki sposób, jak tworzę kontener na projekt. Więc każdy projekt ma swoje własne środowisko, użytkownika, bazy danych, wersję Python / Ruby i tak dalej. Chcę izolować projekty bez tworzenia wielu serwerów.
Kamil Lelonek
1
@squixy; ok. Zwykle kontenery Dockera przechowują tylko jeden proces - idiomatycznie powinieneś mieć osobne kontenery dla mysql, php i apache. Nie jestem pewien, jak dobrze ci się to ułoży.
Adrian Mouat
Wiem, czy znasz lepsze rozwiązanie dla mojej sprawy?
Kamil Lelonek
1
@squixy to zależy od wielu rzeczy. Poleciłbym rozbić każdy pojemnik na kilka pojemników. Do czego potrzebujesz ssh? Jeśli to tylko konserwacja, dlaczego nie możesz ssh do hosta, a następnie docker exec? Obawiam się, że to zbyt duże pytanie, aby odpowiedzieć w komentarzu.
Adrian Mouat
Jak pisze Adrian, kiedy już opanujesz używanie Dockera, zdasz sobie sprawę, że kontenery! = Maszyny wirtualne. Praktycznie (gra słów zamierzona) nie ma potrzeby uzyskiwania interaktywnego dostępu do uruchomionych kontenerów.
mzedeler
8

Utwórz obraz Dockera z openssh-serverpreinstalowanym:

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

Zbuduj obraz używając:

$ docker build -t eg_sshd .

Uruchom test_sshdkontener:

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

0.0.0.0:49154

Ssh do twojego kontenera:

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

Źródło: https://docs.docker.com/engine/examples/running_ssh_service/#build-an-eg_sshd-image

Nazwa Użytkownika
źródło
Warto wspomnieć, że w przypadku Mac OS X możesz spróbować ssh root@localhost -p <ssh_host_port>postępować zgodnie z instrukcjami tutaj
Claudio Santos