Jak dostać się do powłoki kontenera Docker?

1160

Zaczynam pracę z Dockerem. Korzystam z obrazu podstawowego WordPress i komponuję okno dokowane.

Próbuję ssh do jednego z kontenerów, aby sprawdzić pliki / katalogi, które zostały utworzone podczas początkowej kompilacji. Próbowałem biec docker-compose run containername ls -la, ale to nic nie zrobiło. Nawet gdyby tak było, wolałbym mieć konsolę, w której mógłbym przeglądać strukturę katalogów, zamiast uruchamiać pojedyncze polecenie. Jak to zrobić w Docker?

Andrzej
źródło
Wygląda więc na to, że odpowiedzią jest dołączenie dokera. Ale jak mogę się do tego dostać z docker-compose?
Andrew
3
Użyj docker exec askubuntu.com/a/543057/35816 . Pobierz identyfikator kontenera za pomocądocker ps
Mauricio Scheffer
26
sudo docker run -it --entrypoint /bin/bash <container_name>przenosi Cię do kontenera interaktywnie. Następnie można sprawdzić system plików w kontenerze, używająccd <path>
Siergiej

Odpowiedzi:

1729

docker attachpozwoli ci połączyć się z kontenerem Docker, ale tak naprawdę to nie to samo, co ssh. Jeśli pojemnik ma serwera WWW, na przykład, docker attachbędzie prawdopodobnie połączyć Cię do stdout procesu serwera WWW. To niekoniecznie da ci powłokę.

docker execPolecenia jest chyba to, czego szukasz; pozwoli ci to uruchomić dowolne polecenia w istniejącym kontenerze. Na przykład:

docker exec -it <mycontainer> bash

Oczywiście każde uruchomione polecenie musi istnieć w systemie plików kontenera.

W powyższym poleceniu <mycontainer>jest nazwa lub identyfikator kontenera docelowego. Nie ma znaczenia, czy używasz docker compose; po prostu uruchom docker psi użyj albo ID (ciąg szesnastkowy wyświetlany w pierwszej kolumnie), albo nazwę (wyświetlany w ostatniej kolumnie). Na przykład biorąc pod uwagę:

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

Mogę biec:

$ 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

Mogłem osiągnąć to samo, uruchamiając:

$ docker exec -it d2d4a89aaee9 ip addr

Podobnie mógłbym uruchomić powłokę w pojemniku;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
Larsks
źródło
76
docker execDziała również tylko na uruchomionych kontenerach (w przeciwnym razie użyj docker run -it --entrypoint /bin/bashlub podobnych).
L0j1k
59
dla Twojej wygody -itjest to kombinacja -ii -tktóra jest odpowiednio --interactive(„Zachowaj STDIN otwarty, nawet jeśli nie jest dołączony”) odpowiednio --tty(„Przydziel pseudo-TTY”).
Adrian Föder
23
W kontenerach opartych na Alpine Linux możesz nie mieć basha, więc jeśli tak, użyj sh.
Robin Green,
9
@ L0j1k to jest docker run -it --entrypoint /bin/bash <imageid> --any --more --args, aby wyjaśnić ludziom
Alexander Mills
2
@AlexanderMills Tak, a dla dalszego wyjaśnienia, ci, których --any --more --argsmasz, będą karmieni czymkolwiek, co obraz zdefiniował jako swój, CMDa nie Docker (lub jeśli twój obraz definiuje tylko ENTRYPOINTi nie CMD, wtedy te opcje zostaną uwzględnione, /bin/bashjak określono tutaj ). Na przykład wszelkie inne docker runopcje (np. --net "host") Muszą przejść przed <imageid>.
L0j1k
302

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

docker exec -t -i container_name /bin/bash

lub

docker exec -ti container_name /bin/bash

lub

docker exec -ti container_name sh
Agustí Sánchez
źródło
Zakładając, że jest to kontener Linux?
Peter Mortensen,
5
/ bin / bash nie było wymagane, tylko bash zrobił to dla mnie
Anand Varkey Philips
6
Wolałbym docker exec -itzamiastdocker exec -t -i
VaTo
jaka jest różnica @VaTo
AATHITH RAJENDRAN
@AATHITHRAJENDRANI po prostu wolę krótszą formę polecenia zamiast dwóch flag, możesz zawrzeć te dwie opcje w tym samym argumencie -it.
VaTo
85

Powiedzmy, że z własnych powodów naprawdę chcesz korzystać z SSH. To zajmuje kilka kroków, ale można to zrobić. Oto polecenia, które można uruchomić w kontenerze, aby go skonfigurować ...

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)

Teraz możesz nawet uruchamiać aplikacje graficzne (jeśli są zainstalowane w kontenerze), używając X11 do klienta SSH:

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

Oto niektóre powiązane zasoby:

nobar
źródło
33

Jeśli szukasz tutaj odpowiedzi specyficznej dla Docker Compose, takiej jak ja, zapewnia to łatwą drogę bez konieczności wyszukiwania wygenerowanego identyfikatora kontenera.

docker-compose execprzyjmuje nazwę usługi zgodnie z docker-compose.ymlplikiem.

Aby uzyskać powłokę Bash dla usługi „sieciowej”, możesz:

$ docker-compose exec web bash
bcmcfc
źródło
docker-compose rundziała również, jeśli twój kontener jeszcze nie istnieje.
Paul
23

Uwaga : ta odpowiedź promuje narzędzie, które napisałem.

Stworzyłem kontenerowy serwer SSH, który można „przykleić” do dowolnego działającego kontenera. W ten sposób możesz tworzyć kompozycje z każdego pojemnika. Jedynym wymaganiem jest to, że kontener ma Bash.

Poniższy przykład uruchomiłby serwer SSH podłączony do kontenera o nazwie „mój-kontener”.

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

Gdy połączysz się z tą usługą SSH (z wybranym klientem SSH), sesja Bash zostanie uruchomiona w kontenerze o nazwie „mój-kontener”.

Więcej wskazówek i dokumentacji można znaleźć na stronie : https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
źródło
1
To całkiem słodkie. Dużą zaletą robienia tego w ten sposób jest uzyskanie w pełni funkcjonalnego terminala. Kiedy korzystałem z metody „docker exec”, wtedy nie mogłem wyczyścić zawartości terminala, lesswyświetlałem ostrzeżenie za każdym razem, gdy go uruchamiam itp. Korzystanie z kontenera Jeroen daje mi o wiele lepsze wrażenia. Po prostu sprawdź dokumentację . Przykładowe polecenie w odpowiedzi nie wydaje się już prawidłowe.
Rafał G.
1
to świetne narzędzie. Czy wiesz, jak mogę go używać jako agenta dokującego rurociągów Jenkins? i chcę, aby Jenkins przesłał niektóre pliki przez SCP do zdalnego hosta i wykonał je za pomocą SSH
Gilson
21

Jeśli używasz Dockera w systemie Windows i chcesz uzyskać dostęp powłoki do kontenera, użyj tego:

winpty docker exec -it <container_id> sh

Najprawdopodobniej masz już zainstalowany Git Bash . Jeśli nie, zainstaluj go.

Cosmin Ababei
źródło
1
Zakłada kontener Linux Docker?
Peter Mortensen,
1
docker exec -ti <
id_kontenera
17

Jeśli kontener już wyszedł (być może z powodu błędu), możesz to zrobić

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

lub

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

lub

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

aby utworzyć nowy pojemnik i uzyskać do niego powłokę. Ponieważ podałeś --rm, kontener zostanie usunięty po wyjściu z powłoki.

użytkownik674669
źródło
16

W niektórych przypadkach twój obraz może być oparty na alpejskim. W takim przypadku wyrzuci:

Wykonanie środowiska wykonawczego OCI nie powiodło się: exec nie powiodło się: kontener_linux.go: 348: uruchomienie procesu kontenera spowodowało „exec: \" bash \ ": nie znaleziono pliku wykonywalnego w $ PATH": nieznany

Ponieważ /bin/bashnie istnieje. Zamiast tego powinieneś użyć:

docker exec -it 9f7d99aa6625 ash

lub

docker exec -it 9f7d99aa6625 sh
Deoksyseia
źródło
15

SSH do kontenera Docker za pomocą tego polecenia:

sudo docker exec -i -t (container ID) bash
Tjs
źródło
12

Aby połączyć się z cmd w kontenerze Windows, użyj

docker exec -it d8c25fde2769 cmd

Gdzie d8c25fde2769 jest identyfikatorem kontenera.

Aqeel Qureshi
źródło
11

To jest proste !

Wymień wszystkie obrazy Dockera:

sudo docker images

W moim systemie pokazało następujące dane wyjściowe:

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

Mam dwa obrazy Docker na moim komputerze. Powiedzmy, że chcę uruchomić pierwszy.

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

To da ci terminalową kontrolę nad kontenerem. Teraz możesz wykonywać wszelkiego rodzaju operacje powłoki w kontenerze. Podobnie jak robienie ls, wypisane zostaną wszystkie foldery w katalogu głównym systemu plików.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
Patel Sunil
źródło
11

Aby sprawdzić pliki, uruchom, docker run -it <image> /bin/shaby uzyskać interaktywny terminal. Listę zdjęć można uzyskać za pomocą docker images. W przeciwieństwie do docker exectego rozwiązania działa również w przypadku, gdy obraz nie uruchamia się (lub kończy pracę natychmiast po uruchomieniu).

idę
źródło
Zakładając obraz Linux Docker?
Peter Mortensen,
10

ROZWIĄZANIE 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

stara odpowiedź

Umieściliśmy ten fragment kodu w ~/.profile:

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

Nie tylko sprawia to, że każdy może dostać się do działającego kontenera dzięki:

goinside containername

Rozwiązuje również długotrwały problem związany ze stałymi rozmiarami terminali kontenerowych Docker . Co jest bardzo denerwujące, jeśli się z tym zmierzysz.

Również po kliknięciu tego łącza będziesz mieć możliwość wykonania poleceń dotyczących nazw kontenerów dokerów.

Soorena
źródło
1
Dzięki. Działa jak urok, przynajmniej dla tych obrazów, które już zawierają bash. Może nie działać w przypadku obrazów alpejskich, ale można to naprawić za pomocą innej funkcji napisanej specjalnie dla sh / ash itp.
Gaurav Bhaskar
8
$ docker exec -it <Container-Id> /bin/bash

Lub może być w zależności od powłoki

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

Możesz uzyskać identyfikator kontenera za pomocą docker pspolecenia

-i = interaktywny

-t = przydzielić psuedo-TTY

Ashutosh Chamoli
źródło
8

Stworzyłem funkcję terminala dla łatwiejszego dostępu do terminala kontenera. Może wam też się przyda:

Rezultatem jest, zamiast pisać:

docker exec -it [container_id] /bin/bash

napiszesz:

dbash [container_id]

Umieść następujące informacje w swoim ~ / .bash_profile (lub cokolwiek innego, co Ci odpowiada), a następnie otwórz nowe okno terminala i skorzystaj ze skrótu:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}
Chłopak
źródło
7

możesz wchodzić w interakcje z terminalem w kontenerze dokowanym, przekazując opcję -ti

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

-t oznacza terminal -i oznacza interaktywny

Alwin
źródło
6

docker execna pewno będzie rozwiązaniem. Łatwym sposobem pracy z zadanym pytaniem jest zamontowanie katalogu wewnątrz Dockera do katalogu systemu lokalnego .

Abyś mógł natychmiast zobaczyć zmiany w lokalnej ścieżce.

docker run -v /Users/<path>:/<container path> 
Pratik
źródło
1
twoje polecenie faktycznie instaluje katalog hosta w kontenerze.
Demonbane
Tak! Zrób kopię zapasową do innego katalogu, a następnie podłącz wolumin, a następnie przenieś kopię zapasową do zamontowanego folderu.
Pratik
6

Posługiwać się:

docker attach <container name/id here>

Innym sposobem, aczkolwiek istnieje niebezpieczeństwo, jest użycie attach, ale jeśli Ctrl+ wyjdziesz Cz sesji, zatrzymasz również kontener. Jeśli chcesz tylko zobaczyć, co się dzieje, użyj 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)
rbrooker
źródło
6

Użyj tego polecenia:

docker exec -it containerid /bin/bash
Hack administratora
źródło
4

Jeśli masz zainstalowany Docker Kitematic , możesz użyć GUI. Otwórz Kitematicikonę Docker Kitematic, a następnie w oknie wybierz kontener, a następnie kliknij execikonę.

Możesz zobaczyć dziennik kontenera i wiele informacji o kontenerze (w zakładce ustawień) również w tym GUI.

Wybierz Kitematic z menu

Kliknij na exec

Alireza Fattahi
źródło
2

W moim przypadku z jakiegoś powodu muszę sprawdzić wszystkie informacje dotyczące sieci w każdym kontenerze. Dlatego poniższe polecenia muszą być prawidłowe w kontenerze ...

ip
route
netstat
ps
...

Przejrzałem wszystkie te odpowiedzi, żadne nie były dla mnie pomocne. Przeszukałem informacje na innych stronach internetowych. Nie dodam tutaj super linku, ponieważ nie jest napisany po angielsku. Właśnie opublikowałem ten post z rozwiązaniem podsumowującym dla osób, które mają takie same wymagania jak ja.

Załóżmy, że masz jeden działający kontener o nazwie test świetlny. Wykonaj poniższe kroki.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. To polecenie otrzyma odpowiedź jak /var/run/docker/netns/xxxx.
  • Potem ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Katalog może nie istnieć, zrób to mkdir /var/run/netnsnajpierw.
  • Teraz możesz wykonać ip netns exec xxxx ip addr showeksplorację świata sieci w kontenerze.

PS. xxxxjest zawsze tą samą wartością otrzymaną od pierwszego polecenia. I oczywiście wszelkie inne polecenia są prawidłowe, tj ip netns exec xxxx netstat -antp|grep 8080.

Light.G
źródło
1

Inną opcją jest użycie nsenter .

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
xuhdev
źródło
2
Istnieje wiele problemów z nsenter. Po pierwsze, wymaga fizycznego dostępu do hosta dokera, co nie jest dane (być może pracujesz ze zdalnym interfejsem API dokera). Ponadto działanie pod nsenterzwolnia cię z szeregu ograniczeń bezpieczeństwa i zasobów, które Docker nakłada (które mogą być wady lub zalety, w zależności od środowiska).
larsks
1
Nawet autor nsenter mówi, aby korzystać z docker exectych dni.
L0j1k
1
@larsks Tak, oba mają swoje zalety. Na przykład, ta jest zaletą Nsentera docker exec. docker execwygląda mi bardziej elegancko.
xuhdev
2
@ L0j1k Żeby być mniej mylącym: wysłany przez ciebie post nie jest autorem autora nsenter, ale autora obrazu Docker, który uruchamia nsenter.
xuhdev
1

Jeśli używasz Docker Compose, przeniesie Cię to do kontenera Docker.

docker-compose run container_name /bin/bash

Wewnątrz kontenera zabierze Cię do WORKDIR zdefiniowanego w Dockerfile. Możesz zmienić katalog roboczy za pomocą

WORKDIR directory_path # E.g  /usr/src -> container's path
Sivakumar
źródło
0

Aby wykonać w działającym kontenerze o nazwie test , poniżej znajdują się następujące polecenia

Jeśli pojemnik ma bashpowłokę

docker exec -it test /bin/bash

Jeśli pojemnik ma bournepowłokę i większość skrzynek jest obecna

docker run -it test /bin/sh
nischay goyal
źródło
-3

Do tworzenia dokerów-skomponuj (Docker4Drupal)

docker-compose exec php bash

Korzystam z Dockera dla Drupala na laptopie z systemem Linux. Po uruchomieniu kontenera używam ' docker-compose exec php bash', aby połączyć się z kontenerem, aby móc uruchomić komandosy drush. Działa dla mnie dobrze.

illutek
źródło