Можно ли запустить сеанс оболочки в запущенном контейнере (без ssh)

Я наивно ожидал, что эта команда запустит оболочку bash в запущенном контейнере:

docker run "id of running container" /bin/bash

похоже, что это невозможно, я получаю сообщение об ошибке:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

Итак, если я хочу запустить оболочку bash в запущенном контейнере (например, для целей диагностики)

Нужно ли мне запускать в нем SSH-сервер и loggin через ssh?

Ответ 1

EDIT: теперь вы можете использовать docker exec -it "id of running container" bash (doc)

Ранее ответ на этот вопрос был:

Если вам действительно нужно, и вы находитесь в среде отладки, вы можете сделать это: sudo lxc-attach -n <ID> Обратите внимание, что идентификатор должен быть полным (docker ps -notrunc).

Однако я настоятельно рекомендую против этого.

уведомление: -notrunc устарело, оно скоро будет заменено на --no-trunc.

Ответ 2

С docker 1.3 появилась новая команда docker exec. Это позволяет ввести запущенный докер:

docker exec -it "id of running container" bash

Ответ 3

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

Дополнительную информацию об этом репозитории github можно найти здесь. Но в целом вы можете использовать nsenter следующим образом:

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

или вы можете использовать обертку docker-enter:

docker-enter <container_name_or_ID>

Хорошее объяснение по этой теме можно найти в блоге Jérôme Petazzoni: Почему вам не нужно запускать sshd в контейнерах докеров?

Ответ 4

Просто сделай

docker attach container_name

Как уже упоминалось в комментариях, для отсоединения от контейнера, не останавливая его, введите Ctrl p, затем Ctrl q.

Ответ 5

Первое, что вы не можете запустить

docker run "existing container" command

Поскольку эта команда ожидает изображение, а не контейнер, и в любом случае это приведет к созданию нового контейнера (а не того, на который вы хотели бы посмотреть)

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

Я запускаю свои команды через диспетчер в режиме DEAMON.

Затем я выполняю то, что я называю docker_loop.sh В основном это содержание:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

Что он делает, так это то, что он позволяет "присоединить" к контейнеру и быть представлен с интерфейсом supervisorctl для остановки/запуска/перезапуска и проверки журналов. Если этого недостаточно, вы можете Ctrl+D, и вы попадете в оболочку, которая позволит вам заглянуть, как если бы это была обычная система.

ПОЖАЛУЙСТА, ТАКЖЕ СДЕЛАТЬ СЧЕТ, что эта система не так безопасна, как наличие контейнера без оболочки, поэтому сделайте все необходимые шаги для обеспечения безопасности вашего контейнера.

Ответ 6

Следите за этим запросом на растяжение: https://github.com/docker/docker/pull/7409

Что реализует будущая утилита docker exec <container_id> <command>. Когда это доступно, должно быть возможно, например, запустите и остановите службу ssh внутри запущенного контейнера.

Для этого также существует nsinit: "nsinit предоставляет удобный способ доступа к оболочке внутри пространства имен запущенного контейнера", но сложно работать. https://gist.github.com/ubergarm/ed42ebbea293350c30a6

Ответ 7

На самом деле есть способ иметь оболочку в контейнере.

Предположим, что ваш /root/run.sh запускает процесс, диспетчер процессов (супервизор) или что-то еще.

Создайте /root/runme.sh с помощью некоторых трюков gnu:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Теперь у вас есть демоны на вкладке 0 и интерактивная оболочка на вкладке 1. docker attach в любое время, чтобы увидеть, что происходит внутри контейнера.

Другим советом является создание образа "пакета разработки" поверх производственного образа со всеми необходимыми инструментами, включая этот трюк экрана.

Ответ 8

вот мое решение

часть файла DOcker:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

часть "initd.sh"

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

После создания изображения у вас есть два варианта с помощью exec и attach:

  • с exec (который я использую), запустите:

docker run --name $CONTAINER_NAME -dt $IMAGE_NAME

затем

docker exec -it $CONTAINER_NAME/bin/bash

и используйте

CTRL + D для отсоединения

  1. с приложением, запустить:

docker run --name $CONTAINER_NAME -dit $IMAGE_NAME

то

docker присоединить $CONTAINER_NAME

и используйте

CTRL + P и CTRL + Q для отсоединения

разница между параметрами находится в параметре -i

Ответ 9

Есть два способа.

С приложением

$ sudo docker attach 665b4a1e17b6 #by ID

С exec

$ sudo docker exec - -t 665b4a1e17b6 #by ID

Ответ 11

Это полезно назначать имя при запуске контейнера. Вам не нужна ссылка container_id.

docker run --name container_name yourimage docker exec -it container_name bash

Ответ 12

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

Контейнеры похожи на любой другой процесс. В самом деле, вы можете захотеть "прикрепить" их для целей отладки (подумайте о /proc//env или strace -p), но это очень частный случай.

Обычно вы просто запускаете процесс, поэтому, если вы хотите изменить конфигурацию или прочитать журналы, просто создайте новый контейнер и убедитесь, что вы записываете журналы за его пределами, разделяя каталоги, записывая на stdout (так что докер журналы) или что-то в этом роде.

Для целей отладки вы можете запустить оболочку, затем код, а затем нажмите CTRL-p + CTRL-q, чтобы оставить оболочку неповрежденной. Таким образом, вы можете повторно подключиться, используя:

docker attach <container_id>

Если вы хотите отлаживать контейнер, потому что он делает что-то, чего вы не ожидаете, попробуйте отладить его: https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization

Ответ 13

Нет. Это невозможно. Используйте что-то вроде supervisord, чтобы получить ssh-сервер, если это необходимо. Хотя, я определенно сомневаюсь в необходимости.