Как получить bash или ssh в работающий контейнер в фоновом режиме?

Я хочу подключиться по ssh или bash к запущенному контейнеру docker. Пожалуйста, смотрите пример:

$ sudo docker run -d webserverwebserver is clean image from ubuntu:14.04$ sudo docker psCONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

Теперь я хочу получить что-то вроде этого (перейти в запущенный контейнер):

$ sudo docker run -t -i webserver (или, может быть 665b4a1e17b6 вместо этого)
$ root@665b4a1e17b6:/#

Однако, когда я запускаю строку выше, я получаю новый ИДЕНТИФИКАТОР КОНТЕЙНЕРА:

$ root@42f1e37bd0e5:/#

Я использовал Vagrant, и я хотел бы получить такое же поведение, как vagrant ssh.

Ответ - это Докер attach команда. Итак, для моего примера выше решение будет следующим:

$ sudo docker attach 665b4a1e17b6 #by IDor$ sudo docker attach loving_heisenberg #by Name$ root@665b4a1e17b6:/#

Для Docker версии 1.3 или более поздней: Спасибо пользователю WiR3D который предложил другой способ получить оболочку контейнера. Если мы используем attach мы можем использовать только один экземпляр оболочки. Итак, если мы хотим открыть новый терминал с новым экземпляром оболочки контейнера, нам просто нужно выполнить следующее:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

или

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name$ root@665b4a1e17b6:/#

Начиная с Docker 1.3 и далее:

docker exec -it <containerIdOrName> bash

В принципе, если контейнер Docker был запущен с использованием /bin/bash команда вы можете получить к ней доступ с помощью attach. Если нет, то вам нужно выполнить команду для создания экземпляра Bash внутри контейнера с помощью exec.

Также для выхода из Bash, не оставляя Bash запущенным в процессе-изгое:

exit

Да, это так просто.

Хотя автор вопроса специально сказал, что их интересует работающий контейнер, также стоит отметить, что если контейнер не запущен, но вы хотели бы запустить его, чтобы поковыряться, вы можете запустить:

docker run -i -t --entrypoint /bin/bash <imageID>

Попробуй это:

sudo docker run -i -t webserver /bin/bash

Источник: https://docs.docker.com/engine/reference/commandline/run/

Основываясь на ответе @Timur, я создал следующее удобный скрипт

Установка

Поставь docker-ssh файл в вашем $PATH со следующим содержанием

#!/bin/bash -xe# docker container id or name might be given as a parameterCONTAINER=$1if [[ "$CONTAINER" == "" ]]; then  # if no id given simply just connect to the first running container  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")fi# start an interactive bash inside the container# note some containers don't have bash, then try: ash (alpine), or simply sh# the -l at the end stands for login shell that reads profile files (read man)docker exec -i -t $CONTAINER bash -l

Примечание: Некоторые контейнеры не содержат bash, но ash, sh и т.д. В этих случаях bash должен быть заменен в приведенном выше сценарии.

Использование

Если у вас есть только один запущенный экземпляр, просто запустите

$> docker-ssh 

В противном случае предоставьте ему параметр docker id, который вы получаете из docker ps (первая колонка)

$> docker-ssh 50m3r4nd0m1d

Если в вашем контейнере не установлен bash, вы можете попробовать sh:

docker exec -it CONTAINER /bin/sh

Или сначала поищите оболочки в /bin:

docker export CONTAINER|tar -t|egrep ^bin/

Я создал контейнерный SSH-сервер, который предоставляет возможности SSH любому запущенному контейнеру. Вам не нужно менять свой контейнер. Единственное требование - чтобы в контейнере был bash.

Если у вас есть контейнер с именем 'web-server1'. Следующая команда docker run запустит второй контейнер, который предоставит SSH для первого контейнера.

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \jeroenpeeters/docker-ssh

Для получения дополнительных указаний оформите заказ https://github.com/jeroenpeeters/docker-ssh

У @jpetazzo есть потрясающий пост на эту тему. Короткий ответ состоял бы в том, чтобы использовать nsenter:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)nsenter --target $PID --mount --uts --ipc --net --pid

P.S.: Не забудьте проверить обсуждение в комментариях к посту...

Овации

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

Это будет более "традиционным" (ssh), вместо использования специфичной для приложения команды, такой как docker attach, и в конечном итоге сделает его более "переносимым" для разных систем и версий.

Иногда бывает удобно иметь возможность подключаться по ssh к контейнеру Docker, особенно во время разработки. Следующий образ Docker позволяет подключаться к контейнеру по ssh с помощью закрытого ключа:

UbuntuWithSSH-Докер

Суть Dockerfile заключается в следующем https://gist.github.com/devbkhadka/98792f7bca57f9778793b2db758b3d07.

Обратите внимание, что использование SSH для загрузки в запущенный контейнер является плохой практикой – см. [обоснование здесь] (If you run SSHD in your Docker containers, you're doing it wrong! /). `sudo docker exec -i -t container-name /bin/bash" - это правильный путь.

в качестве альтернативы sudo docker exec -i -t 665b4a1e17b6 /bin/sh, чтобы иметь возможность устанавливать подходящие программы и пакеты