Wie komme ich in die Shell eines Docker-Containers?

1162

Ich fange an, mit Docker zu arbeiten. Ich benutze das WordPress-Basis-Image und Docker-Compose.

Ich versuche, in einen der Container zu ssh, um die Dateien / Verzeichnisse zu überprüfen, die während des ersten Builds erstellt wurden. Ich habe versucht zu rennen docker-compose run containername ls -la, aber das hat nichts gebracht. Selbst wenn dies der Fall wäre, hätte ich lieber eine Konsole, in der ich die Verzeichnisstruktur durchlaufen kann, anstatt einen einzelnen Befehl auszuführen. Was ist der richtige Weg, um dies mit Docker zu tun?

Andrew
quelle
Es klingt also so, als ob die Antwort Docker Attach lautet. Aber wie komme ich von Docker-Compose dazu?
Andrew
3
Verwenden Sie docker exec askubuntu.com/a/543057/35816 . Holen Sie sich die Container-ID mitdocker ps
Mauricio Scheffer
26
sudo docker run -it --entrypoint /bin/bash <container_name>bringt Sie interaktiv in den Container. Dann kann man das Dateisystem im Container mitcd <path>
Sergei

Antworten:

1732

docker attachSie können eine Verbindung zu Ihrem Docker-Container herstellen, dies ist jedoch nicht das Gleiche wie ssh. Wenn in Ihrem Container beispielsweise ein Webserver ausgeführt wird, docker attachwerden Sie wahrscheinlich mit dem Standard des Webserverprozesses verbunden. Es wird Ihnen nicht unbedingt eine Muschel geben.

Der docker execBefehl ist wahrscheinlich das, wonach Sie suchen. Auf diese Weise können Sie beliebige Befehle in einem vorhandenen Container ausführen. Zum Beispiel:

docker exec -it <mycontainer> bash

Natürlich muss jeder Befehl, den Sie ausführen, im Container-Dateisystem vorhanden sein.

Im obigen Befehl <mycontainer>steht der Name oder die ID des Zielcontainers. Es spielt keine Rolle, ob Sie verwenden oder nicht docker compose; Führen Sie einfach aus docker psund verwenden Sie entweder die ID (eine hexadezimale Zeichenfolge, die in der ersten Spalte angezeigt wird) oder den Namen (angezeigt in der letzten Spalte). ZB gegeben:

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

Ich kann rennen:

$ 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

Ich könnte das Gleiche erreichen, indem ich renne:

$ docker exec -it d2d4a89aaee9 ip addr

Ebenso könnte ich eine Shell im Container starten;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$
Larsks
quelle
76
Funktioniert auch docker execnur beim Ausführen von Containern (anderweitig verwenden docker run -it --entrypoint /bin/bashoder ähnlich).
L0j1k
59
für Ihre Bequemlichkeit -itist eine Kombination aus -iund -tdas ist --interactive( „Keep öffnen STDIN auch wenn sie nicht angebracht“) bzw. --tty( „ein Pseudo-TTY Weisen“).
Adrian Föder
23
Auf Alpine Linux-basierten Containern haben Sie möglicherweise keine Bash. Wenn ja, verwenden Sie stattdessen sh.
Robin Green
9
@ L0j1k ist es docker run -it --entrypoint /bin/bash <imageid> --any --more --args, nur um für die Menschen zu klären
Alexander Mills
2
@AlexanderMills Ja, und um dies weiter zu verdeutlichen, werden diejenigen, die --any --more --argsSie haben, in das eingespeist, was das Bild als sein CMDund nicht als Docker definiert hat (oder wenn Ihr Bild nur ein ENTRYPOINTund nein definiert CMD, werden diese Optionen /bin/bashwie hier angegeben eingespeist ). So müssen zum Beispiel alle anderen docker runOptionen (z. B. --net "host") vor dem stehen <imageid>.
L0j1k
302

Geben Sie Folgendes ein, um in einen laufenden Container zu schlagen:

docker exec -t -i container_name /bin/bash

oder

docker exec -ti container_name /bin/bash

oder

docker exec -ti container_name sh
Agustí Sánchez
quelle
Angenommen, es ist ein Linux-Container?
Peter Mortensen
5
/ bin / bash war nicht erforderlich, nur bash hat es für mich getan
Anand Varkey Philips
6
Ich würde es vorziehen, docker exec -itanstattdocker exec -t -i
VaTo
Was ist der Unterschied @VaTo
AATHITH RAJENDRAN
@AATHITHRAJENDRANI bevorzugen nur eine kürzere Form des Befehls anstelle von zwei Flags. Sie können diese beiden Optionen in dasselbe Argument -it aufnehmen.
VaTo
85

Nehmen wir an, Sie möchten aus eigenen Gründen wirklich SSH verwenden. Es dauert ein paar Schritte, aber es kann getan werden. Hier sind die Befehle, die Sie im Container ausführen würden, um ihn einzurichten ...

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)

Jetzt können Sie sogar grafische Anwendungen (sofern sie im Container installiert sind) mithilfe der X11-Weiterleitung an den SSH-Client ausführen:

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

Hier sind einige verwandte Ressourcen:

kein Balken
quelle
34

Wenn Sie hier nach einer Docker Compose-spezifischen Antwort suchen, wie ich es war, bietet sie eine einfache Möglichkeit, ohne die generierte Container-ID nachschlagen zu müssen.

docker-compose execNimmt den Namen des Dienstes gemäß Ihrer docker-compose.ymlDatei.

Um eine Bash-Shell für Ihren "Web" -Dienst zu erhalten, haben Sie folgende Möglichkeiten:

$ docker-compose exec web bash
bcmcfc
quelle
docker-compose runfunktioniert auch, wenn Ihr Container noch nicht existiert.
Paul
23

Hinweis : Diese Antwort bewirbt ein Tool, das ich geschrieben habe.

Ich habe einen containerisierten SSH-Server erstellt, an den Sie sich an jeden laufenden Container halten können. Auf diese Weise können Sie mit jedem Container Kompositionen erstellen. Die einzige Voraussetzung ist, dass der Container Bash hat.

Im folgenden Beispiel wird ein SSH-Server gestartet, der an einen Container mit dem Namen "my-container" angeschlossen ist.

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

Wenn Sie eine Verbindung zu diesem SSH-Dienst herstellen (mit dem SSH-Client Ihrer Wahl), wird im Container eine Bash-Sitzung mit dem Namen "my-container" gestartet.

Weitere Hinweise und Dokumentationen finden Sie unter: https://github.com/jeroenpeeters/docker-ssh

Jeroen Peeters
quelle
1
Das ist ziemlich süß. Der große Vorteil dieser Vorgehensweise besteht darin, dass Sie ein voll funktionsfähiges Terminal erhalten. Als ich den "Docker Exec" -Ansatz verwendete, konnte ich den Terminalinhalt nicht löschen, lesszeigte jedes Mal eine Warnung an, wenn ich ihn ausführte usw. Die Verwendung von Jeroens Container bietet mir bisher eine viel bessere Erfahrung. Lesen Sie einfach die Dokumentation . Der Beispielbefehl in der Antwort scheint nicht mehr gültig zu sein.
Rafał G.
1
Es ist ein großartiges Werkzeug. Wissen Sie, wie ich es als Jenkins-Pipeline-Docker-Agent verwenden kann? Ich möchte, dass Jenkins einige Dateien per SCP auf einen Remote-Host überträgt und sie mit SSH ausführt
Gilson
21

Wenn Sie Docker unter Windows verwenden und Shell-Zugriff auf einen Container erhalten möchten, verwenden Sie Folgendes:

winpty docker exec -it <container_id> sh

Höchstwahrscheinlich haben Sie Git Bash bereits installiert. Wenn Sie dies nicht tun, stellen Sie sicher, dass Sie es installieren.

Cosmin Ababei
quelle
1
Nimmt ein Linux Docker Container an?
Peter Mortensen
1
docker exec -ti <container_id> cmd funktioniert gut
PBo
17

Wenn der Container bereits beendet wurde (möglicherweise aufgrund eines Fehlers), können Sie dies tun

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

oder

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

oder

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

um einen neuen Container zu erstellen und eine Shell hinein zu bekommen. Da Sie --rm angegeben haben, wird der Container beim Verlassen der Shell gelöscht.

user674669
quelle
16

In einigen Fällen kann Ihr Bild auf Alpen basieren. In diesem Fall wird es werfen:

OCI-Laufzeitausführung fehlgeschlagen: exec fehlgeschlagen: container_linux.go: 348: Das Starten des Containerprozesses verursachte "exec: \" bash \ ": ausführbare Datei nicht in $ PATH gefunden": unbekannt

Weil /bin/bashes nicht existiert. Stattdessen sollten Sie Folgendes verwenden:

docker exec -it 9f7d99aa6625 ash

oder

docker exec -it 9f7d99aa6625 sh
Deoxyseia
quelle
15

SSH in einen Docker-Container mit diesem Befehl:

sudo docker exec -i -t (container ID) bash
Tjs
quelle
12

Verwenden Sie zum Herstellen einer Verbindung zu cmd in einem Windows-Container

docker exec -it d8c25fde2769 cmd

Wobei d8c25fde2769 die Container-ID ist.

Aqeel Qureshi
quelle
11

Es ist einfach !

Listen Sie alle Ihre Docker-Bilder auf:

sudo docker images

Auf meinem System zeigte es die folgende Ausgabe:

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

Ich habe zwei Docker-Images auf meinem PC. Angenommen, ich möchte den ersten ausführen.

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

Dadurch erhalten Sie die Terminalsteuerung des Containers. Jetzt können Sie alle Arten von Shell-Operationen im Container ausführen. Wie dabei lswerden alle Ordner im Stammverzeichnis des Dateisystems ausgegeben.

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

Führen Sie docker run -it <image> /bin/shzum Überprüfen von Dateien ein interaktives Terminal aus. Die Liste der Bilder erhalten Sie von docker images. Im Gegensatz zu docker execdieser Lösung funktioniert dies auch, wenn ein Image nicht gestartet wird (oder sofort nach dem Ausführen beendet wird).

ich gehe
quelle
Angenommen, Sie haben ein Linux Docker-Image?
Peter Mortensen
10

GOINSIDE-LÖSUNG

Installieren Sie das goinsideBefehlszeilentool mit:

sudo npm install -g goinside

und gehen Sie in einen Docker-Container mit einer geeigneten Terminalgröße mit:

goinside docker_container_name

alte Antwort

Wir haben diesen Ausschnitt eingefügt ~/.profile:

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

Dies ermöglicht nicht nur jedem, in einen laufenden Container zu gelangen, mit:

goinside containername

Es löst auch ein langlebiges Problem mit festen Docker-Containerterminalgrößen . Was sehr ärgerlich ist, wenn Sie sich dem stellen.

Wenn Sie dem Link folgen , haben Sie auch die Befehlsvervollständigung für Ihre Docker-Containernamen.

Soorena
quelle
1
Vielen Dank. Es funktioniert wie ein Zauber, zumindest für jene Bilder, die bereits Bash enthalten haben. Funktioniert möglicherweise nicht für alpine Bilder, kann jedoch mit einer anderen Funktion behoben werden, die speziell für sh / ash usw. geschrieben wurde.
Gaurav Bhaskar
8
$ docker exec -it <Container-Id> /bin/bash

Oder je nach Shell kann es sein

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

Sie können die Container-ID per docker psBefehl erhalten

-i = interaktiv

-t = ein Pseudo-TTY zuweisen

Ashutosh Chamoli
quelle
8

Ich habe eine Terminalfunktion erstellt, um den Zugriff auf das Terminal des Containers zu erleichtern. Vielleicht ist es auch für euch nützlich:

Das Ergebnis ist also, anstatt zu tippen:

docker exec -it [container_id] /bin/bash

du wirst schreiben:

dbash [container_id]

Fügen Sie Folgendes in Ihr ~ / .bash_profile ein (oder was auch immer für Sie funktioniert), öffnen Sie ein neues Terminalfenster und genießen Sie die Verknüpfung:

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

Sie können mit dem Terminal im Docker-Container interagieren, indem Sie die Option -ti übergeben

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

-t steht für Terminal -i steht für interaktiv

Alwin
quelle
6

docker execwird definitiv eine Lösung sein. Eine einfache Möglichkeit, mit der von Ihnen gestellten Frage zu arbeiten, besteht darin , das Verzeichnis in Docker in das Verzeichnis des lokalen Systems einzubinden .

Damit Sie die Änderungen im lokalen Pfad sofort anzeigen können.

docker run -v /Users/<path>:/<container path> 
Pratik
quelle
1
Ihr Befehl mountet tatsächlich das Verzeichnis des Hosts in den Container.
Demonbane
Ja! Erstellen Sie eine Sicherungskopie in einem anderen Verzeichnis, stellen Sie das Volume bereit und verschieben Sie die Sicherungskopie in den bereitgestellten Ordner.
Pratik
6

Verwenden:

docker attach <container name/id here>

Der andere Weg, obwohl eine Gefahr besteht, ist die Verwendung attach. Wenn Sie jedoch Ctrl+ Cdie Sitzung beenden, stoppen Sie auch den Container. Wenn Sie nur sehen möchten, was passiert, verwenden Sie 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)
Broker
quelle
6

Verwenden Sie diesen Befehl:

docker exec -it containerid /bin/bash
Admin Hack
quelle
4

Wenn Sie Docker mit installiert haben Kitematic, können Sie die GUI verwenden. Öffnen Sie Kitematicüber das Docker-Symbol und Kitematicwählen Sie im Fenster Ihren Container aus. Klicken Sie dann aufexec Symbol.

Sie können das Containerprotokoll und viele Containerinformationen (auf der Registerkarte Einstellungen) auch in dieser GUI sehen.

Wählen Sie Kitematic aus dem Menü

Klicken Sie auf exec

Alireza Fattahi
quelle
2

In meinem Fall muss ich aus irgendeinem Grund alle Netzwerkinformationen in jedem Container überprüfen. Die folgenden Befehle müssen also in einem Container gültig sein ...

ip
route
netstat
ps
...

Ich habe all diese Antworten durchgesehen, keine war hilfreich für mich. Ich habe Informationen auf anderen Websites gesucht. Ich werde hier keinen Super-Link hinzufügen, da er nicht auf Englisch geschrieben ist. Deshalb habe ich diesen Beitrag mit einer zusammenfassenden Lösung für Personen erstellt, die dieselben Anforderungen wie ich haben.

Angenommen, Sie haben einen laufenden Container mit dem Namen light-test. Folgen Sie den unteren Schritten.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Dieser Befehl erhält eine Antwort wie /var/run/docker/netns/xxxx.
  • Dann ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Das Verzeichnis ist möglicherweise nicht vorhanden mkdir /var/run/netns.
  • Jetzt können Sie ausführen ip netns exec xxxx ip addr show, um die Netzwerkwelt im Container zu erkunden.

PS. xxxxist immer der gleiche Wert, der vom ersten Befehl empfangen wurde. Und natürlich sind alle anderen Befehle gültig, dh ip netns exec xxxx netstat -antp|grep 8080.

Light.G
quelle
1

Eine andere Option ist die Verwendung von nsenter .

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
xuhdev
quelle
2
Es gibt eine Reihe von Problemen mit nsenter. Das erste ist, dass Sie physischen Zugriff auf den Docker-Host haben müssen, was nicht selbstverständlich ist (möglicherweise arbeiten Sie mit einer Remote-Docker-API). nsenterWenn Sie unter ausgeführt werden, sind Sie außerdem von mehreren Sicherheits- und Ressourcenbeschränkungen befreit, die Docker eingeführt hat (die je nach Umgebung ein Vorteil oder ein Nachteil sein können).
Larsks
1
Sogar der Autor von nsenter sagt , dass er docker execdiese Tage verwenden soll.
L0j1k
1
@larsks Ja, beide haben ihre eigenen Vorteile. Zum Beispiel ist dies ein Vorteil von nsenter gegenüber docker exec. docker execsieht für mich eleganter aus.
Xuhdev
2
@ L0j1k Nur um weniger verwirrend zu sein: Der Beitrag, auf den Sie verwiesen haben, stammt nicht vom Autor von nsenter, sondern vom Autor eines Docker-Images, auf dem nsenter ausgeführt wird.
Xuhdev
1

Wenn Sie Docker Compose verwenden, gelangen Sie in einen Docker-Container.

docker-compose run container_name /bin/bash

Innerhalb des Containers gelangen Sie zu WORKDIR, das in der Docker-Datei definiert ist. Sie können Ihr Arbeitsverzeichnis ändern durch

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

Im testFolgenden werden die folgenden Befehle zum Ausführen in einen laufenden Container mit dem Namen ausgeführt

Wenn der Container eine bashSchale hat

docker exec -it test /bin/bash

Wenn der Container eine bourneHülle hat und in den meisten Fällen vorhanden ist

docker run -it test /bin/sh
Nischay Goyal
quelle
-3

Für Docker-Compose-Up (Docker4Drupal)

docker-compose exec php bash

Ich benutze Docker für Drupal auf einem Linux-Laptop. Nachdem ich den Container ausgeführt habe, verwende ich ' docker-compose exec php bash', um mich mit dem Container zu verbinden, damit ich drush-Kommandos ausführen kann. Es funktioniert gut für mich.

illutek
quelle