Як отримати bash або ssh у запущений контейнер у фоновому режимі?


933

Я хочу ssh або bah у запущений контейнер 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 для удару в запущений контейнер є поганою практикою - див. Обґрунтування тут . 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:/#

Для Докер версії 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 :)
Хенно

17
-i -tдорівнює-it
паша.жуков

47
Це небезпечна відповідь, яку слід обрати і так високо проголосувати. docker attachНаприклад, екземпляр MongoDB, наприклад, вбиває екземпляр. Як детальніше пояснено в цьому питанні, attach і execце різні тварини.
fwc

675

Від Docker 1.3 і далі:

docker exec -it <containerIdOrName> bash

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

Крім того, щоб вийти з Bash, не залишаючи Bash працювати в шахрайському процесі:

exit

Так, це все просто.


ще не придумав, як змусити нано працювати. Подумайте, що може стосуватися докер-шш від phusion
WiR3D

Чи є спосіб встановити bash за замовчуванням у докерах?
ipeacocks

@ipeacocks так, якщо RUNкоманда в dockerfile є /bin/bash. Але залежить, що ти маєш на увазі. Якщо ви хочете запустити контейнер і негайно мати доступ до того ж терміналу, тоді з ним -itслід це зробити
WiR3D

10
Використання докерної групи - це погана практика. Будь-який користувач, який перебуває в групі докер, по суті використовується з правами root без необхідності використовувати sudo. projectatomic.io/blog/2015/08 / ...
Maiku Mori

1
Я думаю, що з точки зору безпеки хоста, чи використовуєте ви sudoпроти dockerгрупи, це не має великої різниці . У будь-якому випадку в докер є вбудований отвір для захисту, який може забезпечити повну привілею у файловій системі хоста від гостя - незалежно від того, використовуєте ви групу докерів чи sudoзапускаєте контейнер.
nobar

123

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

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


10
Це дає інший контейнер, як і відповідь @ kraxor.
Blaisorblade


19

На основі відповіді @ Тимура я створив наступний зручний сценарій

Налаштування

Помістіть 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 ps(перший стовпчик)

$> docker-ssh 50m3r4nd0m1d

Чи можу я знати, для чого нам потрібен -кінець?
Нам Г ВУ

почати bash як оболонку для входу, читаючи параметри середовища (описані в рядку над командою)
Матяш

13

Якщо у вашому контейнері не встановлено bash, ви можете спробувати sh:

docker exec -it CONTAINER /bin/sh

Або спочатку шукайте снаряди у / бункері:

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

Що таке "консул" ? У вас є посилання на це? Ви маєте на увазі "консоль" ?
Пітер Мортенсен

9

Я створив контейнерний SSH-сервер, який забезпечує можливості SSH для будь-якого запущеного контейнера. Вам не потрібно міняти контейнер. Єдина вимога полягає в тому, щоб контейнер мав баш.

Якщо у вас є контейнер з назвою 'web-server1'. Наступна команда запуску докера запустить другий контейнер, який би забезпечував 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


Це має бути прийнята відповідь ^
Нам 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, і з часом зробить її більш "портативною" для всіх систем та версій.


Будь ласка, додайте способи, як це зробити. Якщо чесно, мені це дуже потрібно, але я не маю часу шукати найпростішого рішення для цього. Чи можете ви опублікувати свою відповідь тут? Було б чудово ..
Тимур Файзрахманов

2
Є два способи досягти цього, але це не просто, і це стане великою посадою. Ви можете перевірити це посилання власноруч, використовуючи трубопровід або це посилання , відьма по суті виконує те саме, що і Трубопровід, і це трохи простіше, але робити це потрібно вручну. Тож залежить від того, скільки серверів, де розмовляють. Якщо ви не можете зрозуміти щось більш конкретне, дайте мені знати. Але я також не маю часу написати повний підручник.
radriaanse

Ви маєте рацію - очевидного і простого способу це зробити не існує (Дякую за посилання, я думаю, я перегляну його пізніше.
Тимур Файзрахманов

3

Іноді буде корисно мати можливість потрапити в контейнер Docker, особливо під час розробки. Наведене нижче зображення Докера дозволяє перенести скриньку в контейнер за допомогою приватного ключа:

UbuntuWithSSH-Docker

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



1

ГОЛОВНЕ

встановити goinsideінструмент командного рядка за допомогою:

sudo npm install -g goinside

і зайти всередину докерного контейнера належного розміру терміналу з:

goinside docker_container_name

для отримання детальної інформації перевірте це .


0

Щоб ударити в запущений контейнер, введіть це:

docker exec -t -i container_name /bin/bash

1
це та сама відповідь, що і @AdamKalnas
Bruni

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.