Як SSH в Docker?


Відповіді:


69

По-перше, вам потрібно встановити сервер SSH на зображення, які ви хочете ввести в ssh. Ви можете використовувати базове зображення для всього вашого контейнера з встановленим сервером ssh. Тоді вам потрібно лише запустити кожен контейнер, що відображає порт ssh (за замовчуванням 22) до одного до портів хоста (віддалений сервер на вашому зображенні), використовуючи -p <hostPort>:<containerPort>. тобто:

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

Потім, якщо порти 52022 і 53022 хостів доступні зовні, ви можете безпосередньо ssh перейти до контейнерів, використовуючи ip хоста (віддалений сервер), вказавши порт в ssh за допомогою -p <port>. Тобто:

ssh -p 52022 myuser@RemoteServer -> SSH до контейнера1

ssh -p 53022 myuser@RemoteServer -> SSH до контейнера2


І як піддавати ці порти зовнішньому світу? Я маю на увазі, якщо є можливість налаштувати його без nginx?
Каміль Лелонек

2
@squixy: це лише порти на вашому хості; просто виставляйте їх так само, як і для інших додатків. Можливо, це просто спрацює, або вам може знадобитися відкрити порти у своєму брандмауері.
Адріан Муат,

Я розумію це, мені просто цікаво, який найкращий спосіб зіставити доменні імена з портами, але я вважаю, що NginX - це рішення, яке я можу легко реалізувати.
Каміль Лелонек

Що таке container1? Коли я роблю "запуск докера <ім'я>", <ім'я> інтерпретується як ім'я зображення, тому докер шукає зображення у репозиторіях. Мій ідентифікатор контейнера не працює під час запуску докера. Я використовую "docker start <containerID>" для запуску контейнера, але docker start не приймає параметр -p.
mvmn

1
Якщо користувач Docker є "кореневим", тоді вам потрібно буде надати користувацькому паролю пароль за допомогою "passwd root". Також я знайшов, що це працює: docker run -p 52022: 22 container1 service ssh start -D FOREGROUND
CMP

42

Зверніть увагу : ця відповідь просуває інструмент, який я написав.

Вибрана тут відповідь пропонує встановити SSH-сервер у кожне зображення. Концептуально це не правильний підхід ( https://docs.docker.com/articles/dockerfile_best-practices/ ).

Я створив контейнерний SSH-сервер, який ви можете «прикріпити» до будь-якого запущеного контейнера. Таким чином ви можете створювати композиції з кожним контейнером. Єдина вимога полягає в тому, щоб у контейнері був bash.

У наступному прикладі буде запущено SSH-сервер, відкритий для порту 2222 локальної машини.

$ 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

Додаткові вказівки та документацію див. На https://github.com/jeroenpeeters/docker-ssh

Це не тільки руйнує ідею одного процесу на контейнер, але також є громіздким підходом при використанні зображень з Docker Hub, оскільки вони часто не містять (і не повинні) містити SSH-сервер.


6
Це повинна бути правильна відповідь. Встановлення сервера SSH у кожне зображення, яке ви хочете, суперечить докерству. Ви повинні мати лише один сервіс на контейнер і складати програми з сервісів / контейнерів.
babbata

2
@JeroenPeeters Я думаю, ще однією передумовою є "Роз'єм Docker відображений у контейнері, це дозволяє контейнеру отримати доступ до механізму Docker".
Nam G VU

1
Що таке "jeroenpeeters" у наведеній вище команді? Це ім’я користувача на контейнері?
Пратік Патіл

1
@PratikPatil свою частину назви зображення. hub.docker.com/r/jeroenpeeters/docker-ssh
Jeroen Peeters

13

Ці файли успішно відкриють sshd і запустить службу, щоб ви могли ssh входити локально. (Ви використовуєте кібердак, чи не так?)

Докерфайл

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

для побудови / запуску демона запуску / переходу в оболонку.

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

введіть тут опис зображення


2
Гей, приємна відповідь. Виникає мій контейнер, і він пропонує мені увійти, але чи є облікові дані "кореневими" та "паролем"? Здається, це не працює для мене, але мені подобається ваше рішення, і я хочу його використовувати.
Jabari Dash

не впевнений - я зіткнувся з проблемою при попаданні на порт 22 - переконайтеся, що ви використовуєте порт 2222, оскільки часто на локальному пристрої може бути щось відкрито, щоб конфліктувати з цим портом.
johndpope

цей рядок ('PermitRootLogin без пароля') в / etc / ssh / sshd_config за замовчуванням є коментарем, тому використовуйте замість цього 's / # PermitRootLogin without-password / PermitRootLogin yes /'. Можливо, вам доведеться також використовувати "заборонити пароль" замість "без пароля" для Ubuntu 16.04+. Ви можете впевнено виконати роботу в контейнер, щоб перевірити заздалегідь.
ItsJack

10

Я думаю, це можливо. Вам просто потрібно встановити SSH-сервер у кожен контейнер і виставити порт на хості. Головною неприємністю було б збереження / запам'ятовування відображення порту в контейнер.

Однак я повинен запитати, чому ви хочете це зробити. SSH'ng в контейнери повинен бути досить рідкісним, щоб не було клопоту ssh до хоста, а потім використовувати docker exec, щоб потрапити в контейнер.


Тому я хочу змоделювати своє середовище так, як створюю контейнер для проекту. Отже, кожен проект має своє власне середовище, користувача, бази даних, версію python / ruby ​​тощо. Я хочу ізолювати проекти без створення декількох серверів.
Каміль Лелонек

1
@squixy; в порядку. Зазвичай контейнери докера містять лише один процес - ідіоматично ви повинні мати окремі контейнери для mysql, php та apache. Я не впевнений, наскільки це добре у вас вийде.
Адріан Муат,

Я знаю, чи знаєте ви краще рішення для моєї справи?
Каміль Лелонек

1
@squixy це залежить від багатьох речей. Я б рекомендував розбити кожен контейнер на кілька контейнерів. Для чого потрібен ssh? Якщо це просто технічне обслуговування, чому ви не можете ssh узяти хост, а потім виконайте docker? Я боюся, це занадто велике питання, щоб відповісти у коментарі.
Адріан Муат,

Як пише Адріан, як тільки ви звикнете використовувати Docker, ви зрозумієте, що контейнери! = Віртуальні машини. Практично (для каламбуру) немає необхідності отримувати інтерактивний доступ до запущених контейнерів.
mzedeler

8

Створіть образ докера з openssh-serverпопередньо встановленою:

Докерфайл

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

Створіть зображення за допомогою:

$ docker build -t eg_sshd .

Запустіть test_sshdконтейнер:

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

0.0.0.0:49154

Ssh до вашого контейнера:

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

Джерело: https://docs.docker.com/engine/examples/running_ssh_service/#build-an-eg_sshd-image


Варто згадати, що для mac os x ви можете спробувати ssh root@localhost -p <ssh_host_port>слідувати інструкціям тут
Клаудіо Сантос
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.