Поиск по сайту:

Как подключиться по SSH к контейнеру Docker


SSH — одна из наиболее часто используемых команд в наборе инструментов системного администратора, но ее редко можно увидеть рядом с Docker. Вот как вы можете подключиться по SSH к работающему контейнеру и почему вы должны дважды подумать, прежде чем делать это.

Стоит ли использовать SSH с контейнерами Docker?

Использование SSH в контейнере Docker, как правило, является плохой практикой, которой следует избегать. Почти всегда лучше использовать команду docker exec, чтобы получить оболочку внутри контейнера.

У новичков в Docker может возникнуть соблазн использовать SSH для обновления файлов внутри контейнера. Контейнеры предназначены для одноразового использования, поэтому после создания их следует рассматривать как неизменяемые, за исключением постоянных данных, хранящихся внутри томов. Создайте новый образ и перезапустите контейнер при редактировании исходного кода.

Помимо многоэтапного процесса настройки, установка SSH в образе Docker добавляет несколько пакетов зависимостей и открывает еще один потенциальный вектор атаки. В системе с несколькими активными контейнерами вы будете запускать несколько независимых процессов SSH и должны будете помнить правильный порт для каждого контейнера.

Вместо того чтобы добавлять SSH в отдельные контейнеры, установите его один раз на физическом хосте, на котором работает Docker. Используйте SSH для подключения к хосту, затем запустите docker exec -it my-container bash для доступа к отдельным контейнерам.

Хотя docker exec является предпочтительным подходом, все еще существуют сценарии, в которых SSH может быть полезен. Вы можете ввести его в качестве временной меры для интеграции с устаревшими системами развертывания. Он также может использоваться некоторыми IDE и инструментами сборки для обеспечения возможности перезагрузки в реальном времени во время разработки.

Установка SSH-сервера в Docker-контейнере

Большинство популярных базовых образов Docker намеренно оптимизированы. Вам нужно будет добавить сервер OpenSSH самостоятельно, даже в образы, полученные из популярных дистрибутивов операционных систем.

Вот пример Dockerfile для образа на основе Debian:

RUN apt-get update && apt-get install -y openssh-server
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

ENTRYPOINT service ssh start && bash

Конфигурация SSH изменена, поэтому вы можете войти в систему как root, пользователь по умолчанию в контейнере Docker. Для большей безопасности вместо этого настройте выделенную учетную запись пользователя:

RUN useradd -m -s /bin/bash sshuser

Это создает нового пользователя с именем sshuser с домашним каталогом (-m). Переключатель -s устанавливает оболочку входа пользователя по умолчанию в Bash.

Использование ENTRYPOINT гарантирует, что служба SSH всегда запускается вместе с контейнером. Затем выполнение передается Bash в качестве основного процесса контейнера. Вы можете заменить его бинарным файлом вашего приложения.

Настройка аутентификации

Далее вам нужно настроить систему аутентификации. Вы можете назначить пароль своей учетной записи sshuser и войти с ним:

RUN echo "sshuser:Changeme" | changepasswd

Более безопасный способ — настроить аутентификацию по ключу SSH. Вам нужно будет создать пару ключей на клиентском компьютере, а затем скопировать общедоступную часть в контейнер. Таким образом, демон SSH может проверить личность вашей машины при подключении.

Измените свой Dockerfile, чтобы настроить папку конфигурации .ssh для своего пользователя. Скопируйте открытый ключ из рабочего каталога с помощью команды docker cp или инструкции COPY в Dockerfile. В последнем случае ключ будет встроен в образ, видимый всем, у кого есть доступ.

COPY id_rsa.pub /home/sshuser/.ssh/authorized_keys
RUN chown -R sshuser:sshuser /home/sshuser/.ssh
RUN chmod 600 /home/sshuser/.ssh/authorized_keys

Эта последовательность команд создает файл authorized_keys SSH с открытым ключом id_rsa.pub в вашем рабочем каталоге. Разрешения файловой системы настраиваются в соответствии с требованиями SSH.

Подключение к контейнеру

Теперь вы готовы подключиться к вашему контейнеру. Запустите контейнер с портом 22, привязанным к хосту:

docker run -p 22:22 my-image:latest

Запуск ssh sshuser@example.com даст вам оболочку внутри вашего контейнера.

Вы можете пропустить привязку порта, если будете подключаться с машины, на которой размещен контейнер Docker. Используйте docker inspect, чтобы получить IP-адрес вашего контейнера, а затем передайте его команде подключения SSH.

docker inspect <id-or-name> | grep 'IPAddress' | head -n 1

Используйте клиент SSH на своем компьютере для подключения к контейнеру:

ssh root@172.17.0.1

# OR

ssh sshuser@172.17.0.1

Вам нужно будет использовать альтернативный порт, если вы используете отдельный SSH-сервер на хосте или у вас есть несколько контейнеров, которым нужен порт 22. Вот как инициировать соединение, когда SSH привязан к порту 2220:

docker run -p 22:2220 my-image:latest

ssh root@172.17.0.1 -p 2220

Настройка ярлыков контейнера с помощью SSH Config

Вы можете манипулировать файлом конфигурации SSH, чтобы упростить подключение к отдельным контейнерам. Отредактируйте ~/.ssh/config, чтобы определить сокращенные хосты с предварительно настроенными портами:

Host my-container
    HostName 172.17.0.1
    Port 2220
    User sshuser

Теперь вы можете запустить ssh my-container, чтобы перейти прямо в ваш контейнер. Это упрощает работу с несколькими подключениями, не запоминая IP-адреса и порты контейнеров.

Вместо этого используйте Dockssh для упрощения управления контейнерами

Проект Dockssh делает еще один шаг вперед, предоставляя еще один демон, который позволяет запускать ssh my-container@example.com без какой-либо ручной настройки SSH. Вам не нужно устанавливать SSH-сервер в свои контейнеры; Dockssh автоматически проксирует SSH-соединения и вместо этого запускает правильную команду docker exec.

Сначала вы должны установить Redis для хранения данных конфигурации Dockssh:

sudo apt install redis

Затем определите контейнеры, которые вы хотите открыть, добавив запись Redis с именем контейнера и паролем для SSH-соединений:

redis-cli set dockssh:my-container:pass "container-password-here"

Затем скачайте Dockssh:

sudo curl https://github.com/alash3al/dockssh/releases/download/v1.1.0/dockssh_linux_amd64 -O /usr/local/bin/dockssh
sudo chmod +x /usr/local/bin/dockssh
sudo ufw allow 22022

# Start DockSSH server
dockssh

Теперь вы можете подключиться к вашему контейнеру:

ssh my-container@example.com -p 22022

Dockssh по умолчанию прослушивает порт 22022. Брандмауэр открыт, чтобы разрешить входящие соединения с использованием порта.

При подключении вам будет предложено ввести пароль контейнера. Это было установлено как container-password-here в нашей записи Redis выше.

Использование Dockssh упрощает подключение по SSH к большому количеству контейнеров Docker. Этот подход идеален, когда вы регулярно подключаетесь к своим контейнерам с удаленного хоста, поскольку он упрощает двухэтапную последовательность «SSH, затем docker exec» в одну запоминающуюся команду.

Зарегистрируйте Dockssh как системную службу для длительного использования:

sudo nano /etc/systemd/system/dockssh.service
[Unit]
Description=Dockssh service
After=network.target

[Service]
type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/local/bin/dockssh

[Install]
WantedBy=multi-user.target

Включите службу с помощью systemctl:

sudo systemctl enable dockssh.service
sudo systemctl start dockssh

Dockssh теперь будет запускаться автоматически при загрузке вашей системы.

Краткое содержание

Сочетание SSH с контейнерами Docker широко считается анти-шаблоном, но оно по-прежнему используется в разработке, тестировании и устаревших средах. Когда нет альтернативы, вы можете добавить SSH-сервер в свой контейнер, скопировать открытый ключ и подключиться через IP-адрес контейнера или привязку порта хоста.

Системные администраторы, которые хотят удаленно управлять большим количеством контейнеров Docker, могут попробовать Dockssh. Он позволяет запускать знакомые команды ssh с помощью плавного скрытого сопоставления с docker exec, предоставляя вам лучшее из обоих миров, используя неизмененные изображения.