Wie bekomme ich bash oder ssh in einen laufenden Container im Hintergrundmodus?

933

Ich möchte in einen laufenden Docker-Container ssh oder bash. Bitte siehe Beispiel:

$ 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 

Jetzt möchte ich so etwas bekommen (gehe in den laufenden Container):

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

Ich habe Vagrant benutzt und möchte ein ähnliches Verhalten wie vagrant ssh.

Timur Fayzrakhmanov
quelle
alternativ sudo docker exec -i -t 665b4a1e17b6 /bin/shin der
lage
1
Beachten Sie, dass die Verwendung von SSH zum Bashing in laufende Container eine schlechte Praxis ist - siehe Begründung hier . sudo docker exec -i -t container-name /bin/bashist ein Weg zu gehen.
patryk.beza

Antworten:

1307

Die Antwort lautet Dockers attachBefehl. Für mein Beispiel oben lautet die Lösung also:

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

Für Docker Version 1.3 oder höher: Dank an Benutzer WiR3D, der einen anderen Weg vorgeschlagen hat, die Shell eines Containers zu erhalten. Wenn wir verwenden attach, können wir nur eine Instanz der Shell verwenden. Wenn wir also ein neues Terminal mit einer neuen Instanz der Shell eines Containers öffnen möchten, müssen wir nur Folgendes ausführen:

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

oder

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fayzrakhmanov
quelle
5
Alternativ können Siesudo docker attach loving_heisenberg
Thiago Perrotta
51
Der Befehl attach funktioniert bei mir nicht. Er lässt den Docker einfrieren. Irgendwelche Ideen, warum das passiert?
Mo J. Mughrabi
10
Eine Erinnerung für boot2docker-Benutzer: remove sudo :)
Henno
17
-i -tequals-it
pasha.zhukov
47
Dies ist eine gefährliche Antwort, die ausgewählt und hoch bewertet werden muss. docker attachWenn Sie beispielsweise eine MongoDB-Instanz aufrufen, wird die Instanz beendet. Wie in dieser Frage näher erläutert attachund handelt execes sich um verschiedene Tiere.
FWC
675

Ab Docker 1.3:

docker exec -it <containerIdOrName> bash

Wenn der Docker-Container mit dem /bin/bashBefehl gestartet wurde, können Sie im Grunde genommen mit darauf zugreifen attach. Wenn nicht, müssen Sie den Befehl ausführen, um mit eine Bash-Instanz im Container zu erstellen exec.

So beenden Sie Bash, ohne Bash in einem Schurkenprozess laufen zu lassen:

exit

Ja, so einfach ist das.

WiR3D
quelle
Ich habe immer noch nicht herausgefunden, wie ich Nano zum Arbeiten bringen kann. Denke, dass Docker-ssh von Phusion beteiligt sein könnte
WiR3D
Gibt es eine Möglichkeit, Bash in Dockern standardmäßig festzulegen?
Ipeacocks
@ipeacocks ja, wenn der RUNBefehl in der Docker-Datei ist /bin/bash. Kommt aber drauf an was du meinst. Wenn Sie den Container ausführen und Bash sofort im selben Terminal verfügbar haben möchten, -itsollten Sie dies mit
ausführen
10
Die Verwendung der Docker-Gruppe ist eine schlechte Praxis. Jeder Benutzer, der sich in der Docker-Gruppe befindet, wird im Wesentlichen mit Root-Berechtigungen verwendet, ohne dass sudo verwendet werden muss. projectatomic.io/blog/2015/08/…
Maiku Mori
1
Ich denke, es macht aus Sicht der Host-Sicherheit keinen großen Unterschied, ob Sie sudovs dockergroup verwenden. In beiden Fällen ist eine Sicherheitslücke in Docker integriert, die dem Gast vollständige Berechtigungen im Host-Dateisystem zur Verfügung stellen kann - unabhängig davon, ob Sie die Docker-Gruppe verwenden oder sudoden Container starten.
Nobar
123

Obwohl der Autor der Frage ausdrücklich erklärt hat, dass sie an einem laufenden Container interessiert sind, ist es auch erwähnenswert, dass Sie, wenn der Container nicht läuft, ihn ausführen möchten, um herumzustöbern, Folgendes ausführen können:

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

Adam Kalnas
quelle
10
Das ergibt einen anderen Container, genau wie die Antwort von @ kraxor.
Blaisorblade
27

Versuche dies:

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

Quelle: https://docs.docker.com/articles/basics/#running-an-interactive-shell

kraxor
quelle
14
Es ist nicht geeignet, weil ich andere CONTAINER ID ( root@42f1e37bd0e5:/#und nicht root@665b4a1e17b6:/#)
Timur Fayzrakhmanov
Link ist tot, sollten Sie aktualisieren
Ahmet Karakaya
19

Basierend auf der Antwort von @ Timur habe ich das folgende praktische Skript erstellt

Konfiguration

Legen Sie eine docker-sshDatei $PATHmit folgendem Inhalt in Ihre

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

Hinweis : Einige Container enthalten nicht bash, aber ash, shetc. In diesen Fällen bashmuss im obigen Skript ersetzt werden.

Verwendungszweck

Wenn Sie nur eine laufende Instanz haben, führen Sie einfach aus

$> docker-ssh 

Andernfalls geben Sie einen Docker-ID-Parameter an, den Sie von docker ps(erste Spalte) erhalten.

$> docker-ssh 50m3r4nd0m1d
Matyas
quelle
Darf ich wissen, warum wir -l am Ende brauchen?
Nam G VU
um bash als Login-Shell zu starten, lesen Sie die Umgebungsparameter (in der Zeile über dem Befehl beschrieben)
Matyas
13

Wenn in Ihrem Container kein Bash installiert ist, können Sie Folgendes versuchen:

docker exec -it CONTAINER /bin/sh

Oder suchen Sie zuerst in / bin nach Muscheln:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
quelle
Was ist "Konsul" ? Haben Sie eine Referenz dafür? Meinen Sie "Konsole" ?
Peter Mortensen
9

Ich habe einen containerisierten SSH-Server erstellt, der jedem ausgeführten Container SSH-Funktionen bietet. Sie müssen Ihren Container nicht wechseln. Die einzige Voraussetzung ist, dass der Container Bash hat.

Wenn Sie einen Container mit dem Namen 'web-server1' haben. Der folgende Docker-Ausführungsbefehl startet einen zweiten Container, der SSH für den ersten Container bereitstellt.

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

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

Jeroen Peeters
quelle
Dies sollte die akzeptierte Antwort sein ^
Nam G VU
Übrigens, wie können wir .bashrc automatisch laden lassen, wenn wir eine SSH-Sitzung mit Ihrer Lösung starten? Außerdem wurde eine Ausgabe auf github github.com/jeroenpeeters/docker-ssh/issues/30
Nam G VU
6

@jpetazzo hat einen tollen Beitrag zu diesem Thema . Die kurze Antwort wäre zu verwenden nsenter:

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

PS: Vergiss nicht, die Diskussion in den Kommentaren des Beitrags zu überprüfen ...

Prost

Richard
quelle
1
Das ist ein ziemlich alter Beitrag, der eigentlich nicht mehr nötig ist . Die docker execLösung von @ WiR3D ist wesentlich komfortabler.
Drevicko
4

Sie können dem Docker-Container auch eine routingfähige IP-Adresse mit Pipework zuweisen und anschließend SSH mit dieser neuen IP-Adresse auf den Computer übertragen.

Dies wird "traditioneller" (ssh) sein, anstatt einen anwendungsspezifischen Befehl wie zu verwenden docker attach, und wird ihn schließlich über Systeme und Versionen hinweg "portabler" machen.

Radriaanse
quelle
Bitte fügen Sie die einfache Vorgehensweise hinzu. Um ehrlich zu sein, ich brauche es wirklich, aber ich habe keine Zeit, die einfachste Lösung dafür zu suchen. Könnten Sie Ihre Antwort hier posten? Es wäre toll ..
Timur Fayzrakhmanov
2
Es gibt zwei Möglichkeiten, dies zu erreichen, aber es ist nicht einfach und würde zu einem großen Beitrag werden. Sie können diesen Link auch selbst überprüfen , um Rohrleitungen oder diesen Link zu verwenden. Diese Funktion entspricht im Wesentlichen der Funktion "Rohrleitungen" und ist etwas einfacher, muss jedoch manuell ausgeführt werden. Es kommt also darauf an, wie viele Server im Gespräch sind. Wenn Sie etwas Spezifischeres nicht herausfinden können, lassen Sie es mich wissen. Aber ich habe auch nicht die Zeit, ein vollständiges Tutorial zu schreiben.
Radriaanse
Sie haben Recht - es gibt keine offensichtliche und einfache Möglichkeit, dies zu tun (Vielen Dank für die Links, ich denke, ich werde es später noch einmal besuchen.
Timur Fayzrakhmanov
2
docker run -it openjdk:8

Das funktioniert :-)

Kishan B
quelle
1

GEHEN HINEIN

Installieren Sie das goinsideKommandozeilen-Tool mit:

sudo npm install -g goinside

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

goinside docker_container_name

um weitere Informationen zu überprüfen diesen heraus.

Soorena
quelle
0

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

docker exec -t -i container_name /bin/bash
Agustí Sánchez
quelle
1
Dies ist die gleiche Antwort wie @AdamKalnas obwohl
Bruni
0

Nur zur Information. Wenn Sie sich in einem einfachen Container anmelden müssen, der kein Daemon ist, müssen Sie die folgenden Befehle verwenden:

docker start {id}
docker attach {id}
Nek
quelle
-1

Wenn der Container angehalten wird, wie beispielsweise ein reiner Datencontainer, empfiehlt es sich, jedes Mal einen Einwegcontainer auszuführen, wenn Sie eine Verbindung zum Datencontainer herstellen möchten. In diesem Fall könnte der Datencontainer selbst vollständig leer sein, da der temporäre Container über die Betriebssystemtools verfügen würde.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
David Dehghan
quelle