Как вы используете SSH для входа в контейнер Docker? Традиционный подход состоит из двух шагов:
Шаг 1 : подключитесь по SSH к удаленному серверу Linux (если вы запускаете контейнер в удаленной системе).
ssh user_name@server_ip_address
Шаг 2 : Затем вы входите в оболочку вашего запущенного контейнера Docker в интерактивном режиме следующим образом:
docker exec -it container_ID_or_name /bin/bash
При этом вы можете запустить команду Linux или выполнить некоторое обслуживание службы, работающей внутри контейнера.
В описанном выше методе нет ничего плохого. Это традиционный и рекомендуемый способ без труда загружать контейнеры.
Однако, приложив некоторые усилия, вы можете напрямую подключиться к работающему контейнеру по SSH, без предварительного входа в хост-систему.
Это немного странно, не правда ли? Вход в контейнер через SSH. Хотя это звучит нетрадиционно, в зависимости от ваших сценариев использования оно может быть вам полезно.
Вот несколько вещей, которых вы можете достичь с помощью SSH в контейнере:
Прежде чем мы покажем вам, как делать все вышеперечисленное, расскажем, как это на самом деле работает.
Если вас не интересует, как это работает, вы можете игнорировать этот раздел. Мы собираемся показать вам контейнер-пустышку. Вы можете следовать инструкциям на практике.
Во-первых, вам нужно запустить контейнер Docker. В alpine:latest пока будем использовать очень маленькое изображение. Запустите контейнер с помощью этой команды:
docker run --rm --name ssh-test -it -p 22:7655 alpine:latest ash
Некоторые заметные моменты, касающиеся параметров командной строки, следующие:
Теперь вам нужно установить ssh-сервер внутри контейнера. В Alpine Linux вы можете использовать следующие команды:
apk update; apk add openssh-server
Затем вам нужно быстро изменить параметр конфигурации, чтобы разрешить вход в систему с правами root. Вы можете сделать это вручную, отредактировав файл /etc/ssh/sshd_config или используя эту команду:
sed -E 's/^#(PermitRootLogin )no/\1yes/' /etc/ssh/sshd_config -i
Сгенерируйте ключи хоста с помощью:
ssh-keygen -A
Наконец, запустите ssh-сервер, запустите /usr/sbin/sshd &. Проверьте, не пробегает ли он ps aux.
По умолчанию у корневой учетной записи вашего контейнера нет пароля. Если вы открываете к нему SSH-доступ, вы должны установить пароль для учетной записи root.
Вы можете использовать команду passwd без каких-либо параметров и следовать инструкциям на экране:
passwd
С другого хоста попробуйте войти в контейнер сейчас.
ssh root@IP_address_of_host_server -p port_number
Вам не нужна опция -p, если вы ранее были привязаны к порту 22. В качестве IP используйте IP-адрес хост-сервера (а не контейнера).
Когда вы запустите команду, вы должны увидеть результат, подобный этому:
debdut@shinchan:/mnt/data/documents/AndreyEx/container-ssh$ ssh root@domain.com root@domain.com's password: Welcome to Alpine! The Alpine Wiki contains a large amount of how-to guides and general information about administrating Alpine systems. See <http://wiki.alpinelinux.org/>. You can setup the system with the command: setup-alpine You may change this message by editing /etc/motd. c4585d951883:~#
Это можно лучше понять визуально. Взгляните на следующую диаграмму:
Думайте о контейнерах как о виртуальной машине, порт 22 которой склеен с портом хоста 7655 (или тем, который вы выбрали). Это позволяет вам иметь два разных процесса ssh, запущенных на одном компьютере, привязанных к разным портам.
Допустим, вы используете какой-то другой порт для SSH в хост-системе и склеиваете порт 22 с портом контейнера. Теперь, если кто-то попытается подключиться к хост-серверу, используя SSH-порт по умолчанию 22, окажется в корневой файловой системе контейнера.
Было бы несправедливо, если бы мы оставили вас на этом месте, не предоставив какой-нибудь надежный вариант для контейнера SSH-сервера.
Если вы хотите воспользоваться преимуществом наличия другого изолированного ssh-сервера с отдельной корневой файловой системой, работающей в вашей удаленной системе, это можно было бы сделать, но не следуя предыдущему пошаговому руководству, т.е. установив и настроив sshd на работающей базе контейнера.
Просто потому, что его нелегко воспроизвести, все изменения, которые вы делаете в работающем контейнере, не являются постоянными, перезапуск контейнера и все исчезает.
Итак, здесь мы предлагаем вам гораздо более простой, легко воспроизводимый, настраиваемый способ развертывания контейнера SSH-сервера на вашем удаленном хосте.
Очевидно, вам необходимо установить docker compose. Здесь необходимы базовые знания о компоновке докеров.
Поскольку вы будете получать доступ к серверу через ключи SSH, вам необходимо добавить открытый ключ SSH вашей локальной системы в каталог вашего хост-сервера Linux, где находится файл docker-compose, и на всякий случай сохранить имя «id_rsa.pub».
Предлагаем использовать изображение linuxserver/openssh-server. Это очень легкий образ с достаточно хорошими параметрами конфигурации с помощью переменных среды.
Здесь будет вставлен весь файл композиции. Скопируйте это в какое-нибудь место на вашем сервере и назовите файл docker-compose.yaml.
version: "3.7" services: ssh: image: "linuxserver/openssh-server" ports: - "22:2222" volumes: - "./id_rsa.pub:/pubkey:ro" environment: PUID: ${ID} PGID: ${ID} TZ: ${TZ} PUBLIC_KEY_FILE: "/pubkey" SUDO_ACCESS: "false" PASSWORD_ACCESS: "false" USER_NAME: ${USER_NAME} restart: "always"
Довольно маленький файл для создания текста, не так ли? Позвольте нам объяснить различные части этого файла набора.
Том: у вас есть только одна привязка, которая монтирует открытый ключ в контейнере как pubkey. Он также доступен только для чтения.
Порты: процесс sshd внутри контейнера работает на порту 2222. Вот почему мы привязали этот порт к порту 22 нашего хоста. Измените 22 в соответствии с вашими потребностями, но помните, что он понадобится вам для входа в контейнер через SSH позже.
Переменные среды:
Политика перезапуска: мы установили политику перезапуска «always», которая будет перезапускать контейнер, даже если демон будет перезагружен.
Чтобы упростить вам задачу, мы создали сценарий Bash, который задаст вам несколько вопросов и на основе ответа развернет службу.
#! /usr/bin/env bash vars=("ID" "USER_NAME") defaults=("991" "dummy") questions=("Каков был бы ваш предпочтительный UID & GID для имени пользователя по вашему выбору? [default] " "Ваше желаемое имя пользователя для контейнера? [dummy] ") put() { echo "$1" >> .env } for i in {1..0}; do read -p "${questions[$i]}" ans case $ans in ""|"default") put "${vars[$i]}=${defaults[$i]}" ;; *) put "${vars[$i]}=$ans" ;; esac done put "TZ=$(cat /etc/timezone)" docker-compose up -d
Мы сохранили сценарий bash как deploy.sh в том же каталоге, где находился файл docker-compose.
Теперь, если вы запустите этот скрипт, он задаст вам несколько вопросов, а затем запустит контейнер docker:
bash deploy.sh
Как только это будет сделано, попробуйте войти на сервер:
ssh user@ip -p port
В качестве IP используйте IP-адрес хост-сервера (а не контейнера). что это значит где это посмотреть у меня запущен контейнер и я хочу с c# подключиться и не понгимаю что указать. Помогите
Посмотрите здесь: https://stackoverflow.com/questions/28358008/how-to-properly-specify-an-ip-for-a-docker-container