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

934

Я хочу ssh или bash в работающий контейнер Docker. Пожалуйста, посмотрите пример:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

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

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/# 
However when I run the line above I get new CONTAINER ID
$ root@42f1e37bd0e5:/#

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

Тимур Файзрахманов
источник
в качестве альтернативы, sudo docker exec -i -t 665b4a1e17b6 /bin/shчтобы иметь возможность устанавливать подходящие программы и пакеты
fonjeekay
1
Обратите внимание, что использование SSH для bash в работающий контейнер является плохой практикой - см. Обоснование здесь . sudo docker exec -i -t container-name /bin/bashэто путь
patryk.beza

Ответы:

1306

Ответ - attachкоманда Докера . Так что для моего примера выше, решение будет:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ 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:/#
Тимур Файзрахманов
источник
5
Кроме того, выполнитьsudo docker attach loving_heisenberg
Тьяго Перротта
51
команда присоединения не работает для меня, это заставляет докер зависать .. какие-либо идеи, почему это происходит?
Мо Дж. Муграби
10
Напоминание для пользователей boot2docker: удалите sudo :)
Henno
17
-i -tравняется-it
паша.жуков
47
Это опасный ответ, который нужно выбирать и так высоко голосовать. docker attachНапример, обращение к экземпляру MongoDB приведет к его уничтожению. Как объяснено более подробно в этом вопросе attach и execразные животные.
FWC
677

Начиная с версии Docker 1.3:

docker exec -it <containerIdOrName> bash

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

Также, чтобы выйти из Bash, не оставляя Bash в мошенническом процессе:

exit

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

WiR3D
источник
до сих пор не понял, как заставить работать нано. Подумайте, что может быть связано с Docker-SSH из Phusion
WiR3D
Есть ли способ установить bash по умолчанию в докерах?
ipeacocks
@ipeacocks yes, если RUNкоманда в файле настройки есть /bin/bash. Но зависит, что вы имеете в виду. Если вы хотите запустить контейнер и сразу же получить доступ к bash в том же терминале, то запуск с помощью -itдолжен сделать это
WiR3D
10
Использование Docker Group - плохая практика. Любой пользователь, который находится в группе Docker, по существу используется с правами root без необходимости использовать sudo. projectatomic.io/blog/2015/08/…
Maiku Mori
1
Я думаю, что с точки зрения безопасности хоста не имеет большого значения, используете ли вы sudovs dockergroup. В любом случае, в Docker встроена дыра в безопасности, которая может предоставить полные привилегии в файловой системе хоста от гостя - независимо от того, используете ли вы группу Docker или sudoдля запуска контейнера.
nobar
123

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

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

Адам Калнас
источник
10
Это дает другой контейнер, как ответ @ kraxor.
Blaisorblade
27

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

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

Источник: https://docs.docker.com/articles/basics/#running-an-interactive-shell

kraxor
источник
14
Это не подходит, потому что я получаю другой КОНТЕЙНЕР ID ( root@42f1e37bd0e5:/#и нет root@665b4a1e17b6:/#)
Тимур Файзрахманов
ссылка не работает, вы должны обновить
Ахмет Каракая
19

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

Настроить

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

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$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, который вы получаете docker ps(первый столбец)

$> docker-ssh 50m3r4nd0m1d
Матиас
источник
Могу ли я знать, зачем нам нужен -l в конце?
Нам G VU
чтобы начать Баш как оболочку входа, считывание параметров окружающей среды ( как описано в предыдущей строке команды)
Matyáš
13

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

docker exec -it CONTAINER /bin/sh

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

docker export CONTAINER|tar -t|egrep ^bin/
laktak
источник
Что такое "консул" ? У вас есть ссылка на это? Вы имеете в виду "консоль" ?
Питер Мортенсен
9

Я создал контейнерный сервер 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

Йерун Питерс
источник
Это должен быть принятый ответ ^
Nam G VU
Кстати, как мы можем автоматически загружать .bashrc при запуске ssh-сессии, используя ваше решение? Также выложено сообщение на github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

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

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

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

ура

Ричард
источник
1
Это довольно старый пост, который больше не нужен . Решение @ WiR3D docker execболее удобно.
drevicko
4

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

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

radriaanse
источник
Пожалуйста, добавьте простой способ, как это сделать. Если честно, мне это действительно нужно, но у меня нет времени искать самое простое решение для этого. Не могли бы вы опубликовать свой ответ здесь? Было бы здорово ..
Тимур Файзрахманов
2
Есть 2 способа сделать это, но это не просто, и станет большим постом. Вы можете проверить эту ссылку самостоятельно, для использования pipework или этой ссылки , которая по сути выполняет то же самое, что Pipework, и немного проще, но вам нужно сделать это вручную. Так что это зависит от того, сколько серверов где разговаривают. Если вы не можете найти что-то более конкретное, дайте мне знать. Но у меня также нет времени, чтобы написать полное руководство.
Radriaanse
Вы правы - не существует очевидного и простого способа сделать это (спасибо за ссылки, я думаю, что я вернусь к нему позже.
Тимур Файзрахманов
3

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

UbuntuWithSSH-Docker

Суть Dockerfile - это https://gist.github.com/devbkhadka/98792f7bca57f9778793b2db758b3d07 .

Дев Хадка
источник
2
docker run -it openjdk:8

Это работает :-)

Кишан Б
источник
1

ВОЙТИ В ПОМЕЩЕНИЕ

установить goinsideинструмент командной строки с помощью:

sudo npm install -g goinside

и войдите в докер-контейнер с правильным размером терминала:

goinside docker_container_name

для более подробной информации проверьте это .

Soorena
источник
0

Чтобы добавить bash в работающий контейнер, введите:

docker exec -t -i container_name /bin/bash
Агусти Санчес
источник
1
это тот же ответ, что и @AdamKalnas
Бруни
0

Просто для информации. Если вам нужно войти в простой контейнер, который не является демоном, вам нужно использовать следующие команды:

docker start {id}
docker attach {id}
горный перевал
источник
-1

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

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
Дэвид Дехган
источник