Как мне попасть в оболочку контейнера Docker?


1164

Я начинаю работать с Докером. Я использую базовый образ WordPress и docker-compose.

Я пытаюсь ssh в один из контейнеров для проверки файлов / каталогов, которые были созданы во время первоначальной сборки. Я пытался бежать docker-compose run containername ls -la, но это ничего не делало. Даже если бы это было так, я бы предпочел консоль, где я мог бы просматривать структуру каталогов, а не запускать одну команду. Как правильно сделать это с Docker?


Так что звучит так, как будто ответом является прикрепление докера. Но как я могу получить это от docker-compose?
Андрей

3
Используйте docker exec askubuntu.com/a/543057/35816 . Получить идентификатор контейнера с помощьюdocker ps
Маурисио Шеффер

26
sudo docker run -it --entrypoint /bin/bash <container_name>доставит вас в контейнер в интерактивном режиме. Затем можно проверить файловую систему в контейнере с помощьюcd <path>
Sergei

Ответы:


1738

docker attachпозволит вам подключиться к вашему контейнеру Docker, но это не совсем то же самое, что и ssh. Например, если в вашем контейнере запущен веб-сервер, он, docker attachвероятно, подключит вас к стандартному выводу процесса веб-сервера. Это не обязательно даст вам оболочку.

Команда, docker execвероятно, то, что вы ищете; это позволит вам запускать произвольные команды внутри существующего контейнера. Например:

docker exec -it <mycontainer> bash

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

В приведенной выше команде <mycontainer>указывается имя или идентификатор целевого контейнера. Неважно, используете ли вы или нет docker compose; просто запустите docker psи используйте либо идентификатор (шестнадцатеричная строка, отображаемая в первом столбце), либо имя (отображаемое в последнем столбце). Например, учитывая:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Я могу бегать:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Я мог бы сделать то же самое, запустив:

$ docker exec -it d2d4a89aaee9 ip addr

Точно так же я мог запустить оболочку в контейнере;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$

76
Кроме того, docker execработает только на работающие контейнеры (в противном случае использовать docker run -it --entrypoint /bin/bashили аналогичные).
L0j1k

59
для вашего удобства -itэто комбинация -iи -tкоторая --interactive(«Держите STDIN открытым, даже если он не подключен») соответственно --tty(«Выделить псевдо-TTY»).
Адриан Фёдер

23
В контейнерах на основе Alpine Linux у вас может не быть bash, поэтому, если это так, используйте sh.
Робин Грин

9
@ L0j1k это так docker run -it --entrypoint /bin/bash <imageid> --any --more --args, просто чтобы прояснить для людей
Александр Миллс

2
@AlexanderMills Да, и, чтобы уточнить, те, которые у --any --more --argsвас есть, будут добавлены в то, что изображение определено как его, CMDа не как Docker (или если ваше изображение определяет только « ENTRYPOINTнет» и «нет») CMD, то эти параметры будут введены так, /bin/bashкак вы указали здесь. ). Так, например, любые другие docker runварианты (например --net "host") должны идти перед <imageid>.
L0j1k

302

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

docker exec -t -i container_name /bin/bash

или

docker exec -ti container_name /bin/bash

или

docker exec -ti container_name sh

Предполагая, что это контейнер Linux?
Питер Мортенсен

5
/ bin / bash не требуется, просто bash сделал это для меня
Anand Varkey Philips

6
Я бы предпочел docker exec -itвместоdocker exec -t -i
VaTo

какая разница @VaTo
АЭФИТ РАДЖЕНДРАН

@AATHITHRAJENDRANI просто предпочитают более короткую форму команды вместо двух флагов, вы можете включить эти две опции в один аргумент -it.
ВаТо

85

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

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Теперь вы даже можете запускать графические приложения (если они установлены в контейнере), используя пересылку X11 клиенту SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Вот некоторые связанные ресурсы:


34

Если вы ищете ответ, специфичный для Docker Compose, как я, он предоставляет простой способ без необходимости искать сгенерированный идентификатор контейнера.

docker-compose execпринимает имя службы в соответствии с вашим docker-compose.ymlфайлом.

Итак, чтобы получить оболочку Bash для вашего «веб-сервиса», вы можете сделать:

$ docker-compose exec web bash

docker-compose runработает также, если ваш контейнер еще не существует.
Пол

23

Обратите внимание : этот ответ поддерживает инструмент, который я написал.

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

В следующем примере запускается SSH-сервер, подключенный к контейнеру с именем «my-container».

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 localhost -p 2222

Когда вы подключаетесь к этой службе SSH (с вашим выбранным SSH-клиентом), сеанс Bash будет запущен в контейнере с именем «my-container».

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


1
Это довольно мило. Большим преимуществом этого является то, что вы получаете полнофункциональный терминал. Когда я использовал подход «docker exec», я не мог очистить содержимое терминала, lessпоказывал предупреждение каждый раз, когда я запускаю его и т. Д. Использование контейнера Jeroen дает мне гораздо лучший опыт. Просто обязательно ознакомьтесь с документацией . Пример команды в ответе больше не действителен.
Рафал Г.

1
это отличный инструмент. Знаете ли вы, как я могу использовать его в качестве агента докера Jenkins Pipeline? Я хочу, чтобы Дженкинс передал некоторые файлы по SCP на удаленный хост и
Гилсон,

21

Если вы используете Docker в Windows и хотите получить доступ оболочки к контейнеру, используйте это:

winpty docker exec -it <container_id> sh

Скорее всего, у вас уже установлен Git Bash . Если вы этого не сделаете, обязательно установите его.


1
Предполагается, что Linux Docker контейнер?
Питер Мортенсен

1
docker exec -ti <container_id> cmd работает хорошо
PBo

17

Если контейнер уже вышел (возможно, из-за какой-то ошибки), вы можете сделать

$ docker run --rm -it --entrypoint /bin/ash image_name

или

$ docker run --rm -it --entrypoint /bin/sh image_name

или

$ docker run --rm -it --entrypoint /bin/bash image_name

создать новый контейнер и вставить в него оболочку. Поскольку вы указали --rm, контейнер будет удален при выходе из оболочки.


16

В некоторых случаях ваше изображение может быть альпийским. В этом случае он бросит:

Ошибка выполнения OCI exec: ошибка exec: container_linux.go: 348: запуск процесса контейнера вызвал "exec: \" bash \ ": исполняемый файл не найден в $ PATH": неизвестно

Потому /bin/bashчто не существует. Вместо этого вы должны использовать:

docker exec -it 9f7d99aa6625 ash

или

docker exec -it 9f7d99aa6625 sh

15

SSH в Docker-контейнер с помощью этой команды:

sudo docker exec -i -t (container ID) bash

12

Чтобы подключиться к cmd в контейнере Windows, используйте

docker exec -it d8c25fde2769 cmd

Где d8c25fde2769 - это идентификатор контейнера.


11

Это просто !

Перечислите все ваши изображения Docker:

sudo docker images

На моей системе это показало следующий вывод:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

У меня есть два образа Docker на моем ПК. Допустим, я хочу запустить первый.

sudo docker run -i -t ubuntu:latest /bin/bash

Это даст вам терминальный контроль над контейнером. Теперь вы можете выполнять все типы операций оболочки внутри контейнера. Подобно тому, как вы lsбудете делать , выведите все папки в корне файловой системы.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

11

Чтобы проверить файлы, запустите, docker run -it <image> /bin/shчтобы получить интерактивный терминал. Список изображений можно получить с помощью docker images. В противовес docker execэтому решению работает также в случае, когда изображение не запускается (или выходит сразу после запуска).


Предполагаете образ Linux Docker?
Питер Мортенсен

10

GOINSIDE РЕШЕНИЕ

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

sudo npm install -g goinside

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

goinside docker_container_name

старый ответ

Мы поместили этот фрагмент в ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

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

goinside containername

Это также решает долгосрочную проблему с фиксированными размерами контейнерных терминалов Docker . Что очень раздражает, если вы сталкиваетесь с этим.

Также, если вы перейдете по ссылке, у вас будет команда завершения для имен ваших контейнеров докеров.


1
Спасибо. Это работает как шарм, по крайней мере, для тех изображений, которые уже включены в bash. Может не работать на альпийских изображениях, однако, может быть исправлено с помощью другой функции, специально написанной для sh / ash и т. Д.
Гаурав Бхаскар

8
$ docker exec -it <Container-Id> /bin/bash

Или в зависимости от оболочки, это может быть

$ docker exec -it <Container-Id> /bin/sh

Вы можете получить идентификатор контейнера с помощью docker psкоманды

-i = интерактивный

-t = выделить псевдо-TTY


8

Я создал функцию терминала для более легкого доступа к терминалу контейнера. Может быть, это будет полезно и вам, ребята:

В результате вместо ввода:

docker exec -it [container_id] /bin/bash

ты напишешь:

dbash [container_id]

Поместите следующее в ваш ~ / .bash_profile (или что-нибудь еще, что вам подходит), затем откройте новое окно терминала и наслаждайтесь сочетанием клавиш:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}

7

вы можете взаимодействовать с терминалом в контейнере Docker, передав опцию -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t обозначает терминал -i обозначает интерактив


6

docker execопределенно будет решением. Самый простой способ справиться с заданным вопросом - подключить каталог внутри Docker к каталогу локальной системы .

Так что вы можете просматривать изменения локального пути мгновенно.

docker run -v /Users/<path>:/<container path> 

1
ваша команда фактически монтирует каталог хоста в контейнер.
Demonbane

Да! Сделайте резервную копию в другой каталог и затем смонтируйте том, затем переместите резервную копию в смонтированную папку.
Pratik

6

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

docker attach <container name/id here>

Другой способ, хотя есть опасность для него, это использовать attach, но если выCtrl + Cвыходите из сеанса, вы также остановите контейнер. Если вы просто хотите увидеть, что происходит, используйте docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)


4

Если у вас установлен Docker Kitematic, вы можете использовать графический интерфейс. Откройте Kitematicзначок Docker и в Kitematicокне выберите свой контейнер, а затем нажмите execзначок.

В этом графическом интерфейсе вы также можете видеть журнал контейнера и много информации о контейнере (на вкладке настроек).

Выберите Kitematic из меню

Нажмите на Exec


2

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

ip
route
netstat
ps
...

Я проверил все эти ответы, ни один из них не помог мне. Я искал информацию на других сайтах. Я не буду добавлять здесь супер ссылку, так как она не написана на английском языке. Поэтому я просто выложил этот пост с кратким описанием для людей, которые предъявляют те же требования, что и я.

Скажем, у вас есть один работающий контейнер с именем light-test. Следуйте инструкциям ниже.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}, Эта команда получит ответ как /var/run/docker/netns/xxxx.
  • Потом ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Каталог может не существовать, сделатьmkdir /var/run/netns сначала.
  • Теперь вы можете выполнить, ip netns exec xxxx ip addr showчтобы исследовать сетевой мир в контейнере.

PS. xxxxвсегда одно и то же значение, полученное из первой команды. И, конечно же , любые другие команды являются действительными, то есть ip netns exec xxxx netstat -antp|grep 8080.


1

Другой вариант - использовать nsenter .

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

2
Есть ряд проблем с nsenter. Во-первых, это требует, чтобы у вас был физический доступ к хосту докера, который не является заданным (вы можете работать с API удаленного докера). Кроме того, запуск в соответствии с nsenterосвобождает вас от нескольких ограничений безопасности и ресурсов, которые устанавливает Docker (которые могут быть за или против, в зависимости от вашей среды).
Жаворонки

1
Даже автор nsenter говорит, что использовать в docker execэти дни.
L0j1k

1
@larsks Да, оба имеют свои преимущества. Например, это преимущество от nsenter docker exec. docker execвыглядит более элегантно для меня.
xuhdev

2
@ L0j1k Просто чтобы быть менее запутанным: пост, на который вы ссылались, принадлежит не автору nsenter, а автору образа Docker, на котором работает nsenter.
xuhdev

1

Если вы используете Docker Compose, то вы попадете в контейнер Docker.

docker-compose run container_name /bin/bash

Внутри контейнера вы попадете в WORKDIR, определенный в Dockerfile. Вы можете изменить свой рабочий каталог:

WORKDIR directory_path # E.g  /usr/src -> container's path

0

Выполнить в работающий контейнер с именем test , ниже приведены следующие команды

Если контейнер имеет bashоболочку

docker exec -it test /bin/bash

Если контейнер имеет bourneоболочку и в большинстве случаев он присутствует

docker run -it test /bin/sh

-3

Для docker-compose (Docker4Drupal)

docker-compose exec php bash

Я использую Docker для Drupal на ноутбуке с Linux. После запуска контейнера я использую ' docker-compose exec php bash', чтобы соединиться с контейнером, чтобы я мог запустить drush commandos. Он отлично работает для меня.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.