Jak wprowadzić bash lub ssh do działającego kontenera w trybie tła?

933

Chcę ssh lub uderzyć w działający kontener dokerów. Zobacz przykład:

$ 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 

teraz chcę dostać coś takiego (przejdź do działającego kontenera):

$ 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:/#

Użyłem Vagrant i chciałbym uzyskać podobne zachowanie jak vagrant ssh.

Timur Fajzrakhmanov
źródło
alternatywnie, sudo docker exec -i -t 665b4a1e17b6 /bin/shaby móc zainstalować apt programy i pakiety
fonjeekay
1
Zauważ, że używanie SSH do bashowania do uruchomionego kontenera jest słabą praktyką - patrz uzasadnienie tutaj . sudo docker exec -i -t container-name /bin/bashjest droga do zrobienia.
patryk.beza

Odpowiedzi:

1306

Odpowiedzią jest attachpolecenie Dockera . W powyższym przykładzie rozwiązaniem będzie:

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

W przypadku Dockera w wersji 1.3 lub nowszej: dzięki użytkownikowi WiR3D, który zaproponował inny sposób uzyskania powłoki kontenera. Jeśli użyjemy attach, możemy użyć tylko jednego wystąpienia powłoki. Jeśli więc chcemy otworzyć nowy terminal z nową instancją powłoki kontenera, wystarczy uruchomić następujące polecenie:

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

lub

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fajzrakhmanov
źródło
5
Alternatywnie, wykonajsudo docker attach loving_heisenberg
Thiago Perrotta
51
polecenie attach nie działa dla mnie, powoduje, że doker zamarza. Masz jakieś pomysły, dlaczego tak się dzieje?
Mo J. Mughrabi
10
Przypomnienie dla użytkowników boot2docker: usuń sudo :)
Henno
17
-i -trówna się-it
pasha.zhukov
47
To niebezpieczna odpowiedź, którą należy wybrać i tak wysoko zagłosowana. docker attachna przykład wejście do instancji MongoDB spowoduje jej usunięcie. Jak wyjaśniono bardziej szczegółowo w tym pytaniu attach i execsą to różne zwierzęta.
fwc
675

Począwszy od Dockera 1.3:

docker exec -it <containerIdOrName> bash

Zasadniczo, jeśli kontener Docker został uruchomiony przy użyciu /bin/bashpolecenia, można uzyskać do niego dostęp za pomocą attach. Jeśli nie, musisz wykonać polecenie, aby utworzyć instancję Bash wewnątrz kontenera za pomocą exec.

Również, aby wyjść z Bash bez pozostawiania Bash w nieuczciwym procesie:

exit

Tak, to takie proste.

WiR3D
źródło
wciąż nie wymyśliłem, jak zmusić nano do pracy. Pomyśl, że może to dotyczyć docker-ssh z phusion
WiR3D
Czy jest jakiś sposób, aby domyślnie ustawić bash w oknie dokowanym?
ipeacocks
@ipeacocks tak, jeśli RUNpolecenie w pliku dokera to /bin/bash. Ale zależy, co masz na myśli. Jeśli chcesz uruchomić kontener i mieć dostęp do basha natychmiast w tym samym terminalu, uruchom to z -itpowinno to zrobić
WiR3D
10
Używanie grupy dokerów to zła praktyka. Każdy użytkownik należący do grupy dokerów jest zasadniczo używany z uprawnieniami administratora, bez potrzeby korzystania z sudo. projectatomic.io/blog/2015/08/…
Maiku Mori,
1
Myślę, że nie ma to większego znaczenia, z punktu widzenia bezpieczeństwa hosta, czy używasz sudovs dockergrupa. Tak czy inaczej, w oknie dokowanym znajduje się luka w zabezpieczeniach, która może zapewnić pełne uprawnienia w systemie plików hosta od gościa - niezależnie od tego, czy używasz grupy dokerów, czy sudouruchamiasz kontener.
nobar
123

Chociaż autor pytania wyraźnie stwierdził, że są zainteresowani działającym kontenerem, warto również zauważyć, że jeśli kontener nie jest uruchomiony, ale chcesz go uruchomić, aby poke wokół, możesz uruchomić:

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

Adam Kalnas
źródło
10
To daje inny pojemnik, tak jak odpowiedź @ kraxor.
Blaisorblade,
27

Spróbuj tego:

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

Źródło: https://docs.docker.com/articles/basics/#running-an-interactive-shell

kraxor
źródło
14
Nie nadaje się, ponieważ dostaję inny ID KONTENERA ( root@42f1e37bd0e5:/#i nie root@665b4a1e17b6:/#)
Timur Fayzrakhmanov
link nie działa, powinieneś zaktualizować
Ahmet Karakaya
19

Na podstawie odpowiedzi @ Timur stworzyłem następujący przydatny skrypt

Ustawiać

Umieść docker-sshplik w swoim pliku $PATHo następującej treści

#!/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

Uwaga : Niektóre pojemnik nie zawierają bash, ale ash, shitd. W takich przypadkach bashpowinny zostać zastąpione w powyższym scenariuszu.

Stosowanie

Jeśli masz tylko jedną działającą instancję, po prostu uruchom

$> docker-ssh 

W przeciwnym razie podaj parametr id dokera, który otrzymujesz docker ps(pierwsza kolumna)

$> docker-ssh 50m3r4nd0m1d
Matyas
źródło
Czy mogę wiedzieć, dlaczego potrzebujemy -l na końcu?
Nam G VU
uruchomić bash jako powłokę logowania, odczytując parametry środowiska (opisane w wierszu nad poleceniem)
Matyas
12

Jeśli twój kontener nie ma zainstalowanej bash, możesz spróbować sh:

docker exec -it CONTAINER /bin/sh

Lub poszukaj najpierw powłok w / bin:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
źródło
Co to jest „konsul” ? Czy masz do tego referencję? Masz na myśli „konsolę” ?
Peter Mortensen,
9

Stworzyłem kontenerowy serwer SSH, który zapewnia możliwości SSH do dowolnego działającego kontenera. Nie musisz zmieniać kontenera. Jedynym wymaganiem jest, aby kontener miał bash.

Jeśli masz kontener o nazwie „web-server1”. Następująca komenda uruchamiania dokera uruchomi drugi kontener, który zapewni SSH dla pierwszego kontenera.

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

Aby uzyskać więcej wskazówek, sprawdź https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
źródło
To powinna być zaakceptowana odpowiedź ^
Nam G VU
Nawiasem mówiąc, w jaki sposób możemy załadować .bashrc automatycznie podczas uruchamiania sesji ssh przy użyciu twojego rozwiązania? Opublikowano również problem na github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

@jpetazzo ma niesamowity post na ten temat . Krótka odpowiedź brzmiałaby nsenter:

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

PS: Nie zapomnij sprawdzić dyskusji w komentarzach do wpisu ...

Twoje zdrowie

Richard
źródło
1
To dość stary post, który nie jest już tak naprawdę potrzebny . @ Rozwiązanie WiR3D docker execjest raczej wygodniejsze.
drevicko,
4

Możesz również nadać kontenerowi Docker adres IP możliwy do trasowania za pomocą Pipework, a następnie SSH do urządzenia z tym nowym adresem IP.

Będzie to bardziej „tradycyjne” (ssh), zamiast używania polecenia specyficznego dla aplikacji docker attach, i ostatecznie sprawi, że będzie ono bardziej „przenośne” między systemami i wersjami.

radriaanse
źródło
Dodaj prosty sposób, jak to zrobić. Szczerze mówiąc, naprawdę tego potrzebuję, ale nie mam czasu na znalezienie najprostszego rozwiązania. Czy możesz opublikować swoją odpowiedź tutaj? Byłoby wspaniale ..
Timur Fayzrakhmanov
2
Można to zrobić na dwa sposoby, ale nie jest to proste i stałoby się dużym postem. Możesz sam sprawdzić ten link , aby użyć pipework lub tego linku , który zasadniczo osiąga to samo co Pipework i jest nieco prostszy, ale musisz to zrobić ręcznie. To zależy od tego, ile serwerów rozmawia. Jeśli nie możesz znaleźć czegoś bardziej konkretnego, daj mi znać. Ale nie mam też czasu na napisanie pełnego samouczka.
radriaanse
Masz rację - nie ma oczywistego i prostego sposobu na zrobienie tego (dzięki za linki, myślę, że wrócę później.
Timur Fayzrakhmanov
2
docker run -it openjdk:8

To działa :-)

Kishan B.
źródło
1

GOINSIDE

zainstaluj goinsidenarzędzie wiersza poleceń za pomocą:

sudo npm install -g goinside

i wejdź do kontenera dokującego o odpowiedniej wielkości terminala z:

goinside docker_container_name

po więcej szczegółów sprawdź to .

Soorena
źródło
0

Aby uderzyć w działający kontener, wpisz:

docker exec -t -i container_name /bin/bash
Agustí Sánchez
źródło
1
jest to ta sama odpowiedź, co @AdamKalnas
Bruni
0

Tylko dla informacji. Jeśli chcesz się zalogować w prostym kontenerze, który nie jest demonem, musisz użyć następujących poleceń:

docker start {id}
docker attach {id}
Nek
źródło
-1

jeśli kontener zostanie zatrzymany, jak na przykład kontener tylko danych, dobrym rozwiązaniem jest uruchomienie kontenera wysuwanego za każdym razem, gdy chcesz dołączyć do kontenera danych. W takim przypadku sam kontener danych może być całkowicie pusty, ponieważ tymczasowy kontener miałby narzędzia systemu operacyjnego.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
David Dehghan
źródło