Docker'da SSH nasıl yapılır?


90

Aşağıdaki altyapı akışını oluşturmak istiyorum:

Docker kullanılarak bu nasıl başarılabilir?

Yanıtlar:


70

Öncelikle, ssh-içine sokmak istediğiniz görüntülere bir SSH sunucusu kurmanız gerekir. Ssh sunucusu kurulu olan tüm kapsayıcınız için bir temel görüntü kullanabilirsiniz. Ardından, ssh bağlantı noktasını (varsayılan 22) ana bilgisayarın bağlantı noktalarından birine (görüntünüzdeki Uzak Sunucu) eşleyen her kapsayıcıyı -p <hostPort>:<containerPort>. yani:

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

Ardından, ana bilgisayarın 52022 ve 53022 bağlantı noktalarına dışarıdan erişilebiliyorsa, ana bilgisayarın ipini (Uzak Sunucu) kullanarak ssh içinde bağlantı noktasını belirterek doğrudan kapsayıcılara ssh yapabilirsiniz -p <port>. Yani:

ssh -p 52022 myuser@RemoteServer -> SSH'den container1'e

ssh -p 53022 myuser@RemoteServer -> SSH'den container2'ye


Ve bu limanlar dış dünyaya nasıl maruz bırakılır? Demek istediğim, onu nginx olmadan yapılandırma imkanı varsa?
Kamil Lelonek

2
@squixy: bunlar yalnızca ana makinenizdeki bağlantı noktalarıdır; bunları diğer uygulamalarda olduğu gibi gösterin. Sadece işe yarayabilir veya güvenlik duvarınızda bağlantı noktalarını açmanız gerekebilir.
Adrian Mouat

Anladım, alan adlarını bağlantı noktalarına eşlemenin en iyi yolunun ne olduğunu merak ediyorum, ancak NginX'in kolayca uygulayabileceğim bir çözüm olduğuna inanıyorum.
Kamil Lelonek

Container1 nedir? "Docker run <name>" yaptığımda, <name> imaj adı olarak yorumlanıyor, bu yüzden docker depolarda bir imaj arıyor. Kapsayıcı kimliğim docker run ile çalışmıyor. Kapsayıcıyı başlatmak için "docker start <containerID>" kullanıyorum, ancak docker start -p parametresini kabul etmiyor.
mvmn

1
Docker kullanıcısı "root" ise, kullanıcı köküne "passwd root" yoluyla bir şifre vermeniz gerekecektir. Ayrıca bu işleri buldum: docker run -p 52022: 22 container1 service ssh start -D FOREGROUND
CMP

42

Dikkat : Bu cevap yazdığım bir aracı tanıtıyor.

Burada seçilen yanıt, her görüntüye bir SSH sunucusu kurmanızı önerir. Kavramsal olarak bu doğru yaklaşım değildir ( https://docs.docker.com/articles/dockerfile_best-practices/ ).

Çalışan herhangi bir kapsayıcıya 'yapıştırabileceğiniz' kapsayıcıya alınmış bir SSH sunucusu oluşturdum. Bu şekilde her kapla kompozisyonlar oluşturabilirsiniz. Tek gereksinim, kapsayıcıda bash olmasıdır.

Aşağıdaki örnek, yerel makinenin 2222 numaralı bağlantı noktasında açığa çıkan bir SSH sunucusunu başlatacaktır.

$ 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

Daha fazla işaretçi ve belge için bkz: https://github.com/jeroenpeeters/docker-ssh

Bu, konteyner başına bir işlem fikrini ortadan kaldırmakla kalmaz, aynı zamanda Docker Hub'daki görüntüleri kullanırken, bunlar genellikle bir SSH sunucusu içermediğinden (ve olmamalıdır) zahmetli bir yaklaşımdır.


6
Bu doğru cevap olmalı. SSH sunucusunu istediğiniz her imaja kurmak, docker yapısına aykırıdır. Kapsayıcı başına yalnızca bir hizmetiniz olmalı ve hizmetleri hizmetlerden / kapsayıcılardan oluşturmalısınız.
babbata

2
@JeroenPeeters Sanırım "Docker soketi konteynere eşlenir, bu konteynerin Docker Engine'e erişmesine izin verir."
Nam G VU

1
Yukarıdaki komuttaki 'jeroenpeeters' nedir? Konteynerde bir kullanıcı adı mı?
Pratik Patil

1
@PratikPatil, görüntü adının bir parçası. hub.docker.com/r/jeroenpeeters/docker-ssh
Jeroen Peeters

13

Bu dosyalar başarıyla sshd'yi açar ve hizmeti çalıştırır, böylece yerel olarak ssh yapabilirsiniz. (Cyberduck kullanıyorsun değil mi?)

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

inşa etmek / çalıştırmak için arka plan programı başlatmak / kabuğa atlamak.

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

görüntü açıklamasını buraya girin


2
Hey, güzel cevap. Konteynırım geliyor ve oturum açmamı istiyor, ancak kimlik bilgileri "kök" ve "şifre" mi? Bu benim için işe yaramıyor gibi görünüyor, ancak çözümünüzü beğendim ve kullanmak istiyorum.
Jabari Dash

emin değilim - 2222 numaralı bağlantı noktasını vururken sorunla karşılaştım - bu bağlantı noktasıyla çakışacak yerel cihazda her şeyin açık olabileceği için 2222 numaralı bağlantı noktasını kullandığınızdan emin olun.
johndpope

/ etc / ssh / sshd_config içindeki bu satır ('Parolasız PermitRootLogin'), varsayılan olarak yorum dışıdır, bu nedenle bunun yerine 's / # PermitRootLogin parolasız / PermitRootLogin yes /' kullanın. Ubuntu 16.04+ için 'şifresiz' yerine 'şifreyi yasakla' kullanmanız gerekebilir. Önceden kontrol etmek için konteynere girdiğinizden emin olabilirsiniz.
ItsJack

10

Sanırım mümkün. Her konteynere bir SSH sunucusu kurmanız ve ana bilgisayarda bir bağlantı noktası göstermeniz yeterlidir. Başlıca sıkıntı, limanın konteynere eşleştirilmesini sürdürmek / hatırlamak olacaktır.

Ancak, bunu neden yapmak isteyeceğinizi sorgulamalıyım. Kapsayıcılara SSH'ng, ana makineyi ssh yapmak ve daha sonra kapsayıcıya girmek için docker exec kullanmak için bir güçlük oluşturmayacak kadar nadir olmalıdır.


Bu yüzden ortamımı proje başına kapsayıcı oluşturduğum şekilde modellemek istiyorum. Yani her projenin kendi ortamı, kullanıcısı, veritabanları, python / ruby ​​versiyonu vb. Vardır. Birden fazla sunucu oluşturmadan projeleri izole etmek istiyorum.
Kamil Lelonek

1
@squixy; tamam. Normalde docker konteynerleri sadece tek bir işlemi tutar - deyimsel olarak mysql, php ve apache için ayrı konteynerlere sahip olmalısınız. Bunun senin için ne kadar işe yarayacağından emin değilim.
Adrian Mouat

Biliyorum, davam için daha iyi bir çözüm biliyor musunuz?
Kamil Lelonek

1
@squixy bir çok şeye bağlıdır. Her kabı birden çok kaba bölmenizi tavsiye ederim. Ssh için ne gerekiyor? Sadece bakım ise, neden ana makineye ssh sonra docker exec yapamıyorsunuz? Korkarım bir yorumda cevaplanamayacak kadar büyük bir soru.
Adrian Mouat

Adrian'ın yazdığı gibi, Docker'ı kullanmaya alıştığınızda, konteynerlerin! = Sanal makineler olduğunu fark edersiniz. Neredeyse (amaçlanan) çalışan kapsayıcılara etkileşimli erişim elde etmeye gerek yoktur.
mzedeler

8

openssh-serverÖnceden yüklenmiş olarak docker görüntüsü oluşturun :

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

Görüntüyü aşağıdakileri kullanarak oluşturun:

$ docker build -t eg_sshd .

Bir test_sshdkapsayıcı çalıştırın :

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

0.0.0.0:49154

Ssh, konteynerinize:

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

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


Mac os x ssh root@localhost -p <ssh_host_port>için buradaki
Claudio Santos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.