So geben Sie einen Docker-Container ein, der bereits mit einem neuen TTY ausgeführt wird


545

Ich habe einen Container, in dem der Apache-Dienst im Vordergrund ausgeführt wird. Ich möchte in der Lage sein, von einer anderen Shell aus auf den Container zuzugreifen, um darin "herumzustöbern" und die Dateien zu untersuchen. Wenn ich mich an den Container anhänge, sehe ich mir momentan den Apache-Daemon an und kann keine Befehle ausführen.

Ist es möglich, einen anderen tty an einen laufenden Container anzuhängen? Möglicherweise kann ich die Tatsache ausnutzen, dass Docker tatsächlich nur LXC-Container umhüllt? Ich habe es versucht, sudo lxc-console -n [container-id] -t [1-4]aber es scheint, dass nur ein tty verfügbar ist und dieser den Apache-Daemon ausführt. Vielleicht gibt es eine Möglichkeit, mehrere lxc-Konsolen während des Builds zu aktivieren?

Ich würde den Container lieber nicht mit einem openssh-Dienst konfigurieren und erstellen, wenn dies möglich ist.


7
Hast du es versucht docker attach [conainer-id]?
Shabbychef

13
@shabbychef Sofern sich Docker Attach nicht geändert hat, wird der Befehl attach an das laufende tty angehängt, nicht an ein neues. Daher lautet der Fragentitel "... mit neuem TTY". Aus diesem Grund wird in der folgenden Antwort der Befehl attach nicht verwendet.
Programster

1
Seit 1.3 gibt es einen einfacheren Weg, wie in dieser Antwort beschrieben
Thomasleveil

Antworten:


1061

Mit Docker 1.3 gibt es einen neuen Befehl docker exec. Auf diese Weise können Sie einen laufenden Docker eingeben:

docker exec -it [container-id] bash

30
Ich habe dies geändert, um die richtige Antwort (von meiner eigenen) zu sein, da diese neue Methode, die es zum Zeitpunkt der Frage noch nicht gab, die derzeit beste IMO-Methode ist.
Programster

3
Beachten Sie jedoch, dass execdies kein normales Terminal ist. Beispielsweise können Sie den Benutzer nicht einmal im Container ändern.
Pithikos

3
@Pithikos: Ich kann exec verwenden, um eine Shell auszuführen und dann su someuserden Benutzer zu wechseln. Laufen Docker 1.4.1
lsh

2
Hinweis für alle, die diese Diskussion lesen. Ich bin mir sicher, dass docker exec -itich irgendwann eine voll funktionsfähige Pseudo-Version bereitstellen werde, aber im Moment (Docker Version 1.9.1) gibt es einige Mängel: github.com/docker/docker/issues/8755
blong

18
Wenn Sie den Fehler 'exec: "bash": ausführbare Datei nicht in $ PATH gefunden' erhalten, können Sie dies versuchen: docker exec -it [Container-ID] / bin / sh
Dai Kaixian

42

Sie sollten das Tool 'nsenter' von Jérôme Petazzoni verwenden, um einen Container ohne SSH einzugeben. Siehe: https://github.com/jpetazzo/nsenter

Installieren Sie mit einfachem Ausführen: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Verwenden Sie dann den Befehl docker-enter <container-id>, um den Container einzugeben.


Das ist der richtige Weg. Siehe Blog .
Jesse Glick

5
Mit Docker 1.3 gibt es einen neuen Befehl docker exec. Auf diese Weise können Sie einen laufenden Docker eingeben: docker exec -it <container-id> bash(siehe meine Antwort unten)
Michael_Scharf

5
Existiert docker-enternoch? Es gibt mir command not found.
Snowcrash

22

Aktualisieren

Ab Docker 0.9 muss die /etc/default/dockerDatei mit der '-e lxc'Startoption für den Docker-Daemon aktualisiert werden, bevor der Daemon neu gestartet wird, damit die folgenden Schritte jetzt funktionieren (ich habe dies durch einen Neustart des Hosts getan).

Update auf die Datei / etc / default / docker

Das ist alles, weil ...

... es [Docker 0.9] enthält eine neue "Engine Driver" -Abstraktion, um die Verwendung einer anderen API als LXC zum Starten von Containern zu ermöglichen. Es bietet auch einen neuen Engine-Treiber, der auf einer neuen API-Bibliothek (libcontainer) basiert und Kontrollgruppen ohne Verwendung von LXC-Tools verarbeiten kann. Das Hauptproblem ist, dass, wenn Sie sich auf lxc-attach verlassen, um Aktionen für Ihren Container auszuführen, z. B. das Starten einer Shell im Container, was für die Entwicklungsumgebung wahnsinnig nützlich ist ...

Quelle

Bitte beachten Sie, dass dadurch verhindert wird, dass die optionale Netzwerkfunktion des neuen Hosts nur von Docker 0.11 "funktioniert" und nur die Loopback-Oberfläche angezeigt wird. Fehlerbericht


Es stellt sich heraus, dass die Lösung für eine andere Frage auch die Lösung für diese war:

... Sie können Docker verwenden ps -notrunc, um die vollständige lxc-Container-ID abzurufen, und dann lxc-attach -n <container_id>run bash in diesem Container als root verwenden.

Update: Sie müssen es bald verwenden, ps --no-truncanstatt ps -notruncdass es veraltet ist.

Geben Sie hier die Bildbeschreibung ein Suchen Sie die vollständige Container-ID

Geben Sie hier die Bildbeschreibung ein Geben Sie den Befehl lxc attach ein.

Geben Sie hier die Bildbeschreibung ein Oben wird mein Apache-Prozess angezeigt, auf dem der Docker gestartet wurde.


Es gibt also keine Möglichkeit, dies nur mit Docker zu tun, oder? Ich persönlich bevorzuge es, LXC nicht selbst einzumischen.
Qkrijger

Gibt es eine Möglichkeit, stattdessen einen Befehl mit lxc-attach auszuführen, um die Bash zu starten? Danke!!
Joselo

@qkrijger soweit mir bekannt ist das richtig. Warum sollte man sich Sorgen machen, LXC zu "mischen"? Sie erkennen, dass Docker auf LXC aufgebaut ist, oder?
Programster

@ Joselo Ich verstehe Ihre Frage nicht, aber ich schlage vor, dass Sie einen neuen Beitrag mit mehr Details erstellen? Es gibt viele Möglichkeiten, einen Docker-Prozess zu starten, z. B. mit Bash oder als Daemon mit -d usw.
Programster

@programster ja, das ist mir klar :) Trotzdem fühlt sich die Verwendung von LXC direkt in Kombination mit Docker wie Hacking an. Spaß, aber nicht wirklich wartbar. Im Allgemeinen sollte man in der Abstraktionsschicht codieren, in der man arbeiten möchte. Wenn Sie LXC selbst wirklich benötigen, ist es möglicherweise Zeit für eine Pull-Anfrage auf Docker :)
qkrijger

7

Erster Schritt Container-ID abrufen:

docker ps

Dies wird Ihnen so etwas zeigen

BEHÄLTER-ID BILDBEFEHL ERSTELLTE STATUS-PORTS-NAMEN

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" vor 26 Sekunden Bis zu 25 Sekunden 0.0.0.0:8989->9999/tcp SLURM_TASK-303337_0

1170fe9e9460 ist in diesem Fall die Container-ID.

Zweitens geben Sie den Docker ein:

docker exec -it [container_id] bash

also im obigen Fall: docker exec -it 1170fe9e9460 bash


5

Was ist mit tmux / GNU Screen im Container? Scheint die reibungslosere Möglichkeit zu sein, mit einer einfachen Funktion auf so viele vty zuzugreifen, wie Sie möchten:

$ docker attach {container id}

Dies ist eine gute Lösung, wenn Sie wissen, dass Sie Zugriff auf einen Container erhalten möchten (z. B. um ihn zu debuggen). Dies würde jedoch OP nicht helfen, der angibt, dass er sich in einem vorhandenen Container umsehen möchte.
Luca Spiller

1
Mein Problem mit dieser Antwort ist, dass die Leute bereits nach der Verwendung gefragt haben docker attachund ich darauf hingewiesen habe, dass:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
Programster

Nun, wenn der Container bereits ausgeführt wird, hilft Ihnen diese Lösung nicht weiter, aber wenn Sie zuvor dafür gesorgt haben, dass ein Multiplexer ausgeführt wird, benötigen Sie keine zusätzlichen ttys ... Seit ich tmux verwende, verwende ich eine tty und nur einer, der alles tut, was ich brauche, da ich einmal in tmux so viele vtys erzeugen kann, wie ich will.
cig0

4

nsentermacht das. Ich musste jedoch auch auf einfache Weise einen Container eingeben, und nsenter reichte für meine Anforderungen nicht aus. Es war in einigen Fällen fehlerhaft (schwarzer Bildschirm plus -wd-Flagge funktionierte nicht). Außerdem wollte ich mich als bestimmter Benutzer und in einem bestimmten Verzeichnis anmelden.

Am Ende habe ich mein eigenes Werkzeug zum Betreten von Containern hergestellt. Sie finden es unter: https://github.com/Pithikos/docker-enter

Die Verwendung ist so einfach wie

./docker-enter [-u <user>] [-d <directory>] <container ID>

Gerade ausprobiert, sehr cool! Auf Ubuntu musste sudo apt-get build-essential -y gcc docker-enter.c -o docker-enter sudo ausführen ./docker-enter <short-container-id> Schön, dass ich nicht die vollständige ID wie bei bekommen muss lxc-attach -n Codebase ist kurz genug, um das Ganze schnell nach böswilligen Dingen durchsuchen zu können.
Programster

Ich habe ein Ebuild auf gentoo unter github.com/steveeJ/personal-portage-overlay als App-Emulation / Docker- Enter verfügbar gemacht .
Stefanjunker

Ich habe ein Tutorial / Skript für automatische dies für Ubuntu-Benutzer bei programster.blogspot.co.uk/2014/01/…
Programster

2

Der "nsinit" Weg ist:

installiere nsinit

git clone git@github.com:dotcloud/docker.git
cd docker
make shell

aus dem Inneren des Behälters:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

von außen:

docker cp id_docker_container:/go/bin/nsinit /root/

benutze es

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash

2
docker exec -t -i container_name /bin/bash

Bringt Sie zur Containerkonsole.


Ich bin auf diese Frage gestoßen, weil ich das gleiche Problem hatte. Die Antwort, die ähnlich zu sein scheint, hat bei mir erst funktioniert, als ich sie geändert habe. Ich kann das aber löschen.
Danstan

2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh

1

Ich habe Powershell auf einem laufenden Microsoft / Iis gestartet, das als Daemon ausgeführt wird

docker exec -it <nameOfContainer> powershell

Es sieht so aus, als ob es sich um einen Linux-basierten Container handelt. Diese Antwort funktioniert wahrscheinlich nur, wenn Sie einen Windows-basierten Container haben - oder wenn Sie die .NET Core-Version von PowerShell installiert haben, z. B. PowerShell 6 oder höher.
Manfred

0

Unter Windows 10 habe ich Docker installiert. Ich führe Jnekins auf einem Container aus und habe dieselbe Fehlermeldung erhalten. Hier ist eine schrittweise Anleitung zur Behebung dieses Problems:

Schritt 1: Öffnen Sie gitbash und führen Sie Docker run -p 8080: 8080 -p 50000: 50000 jenkins aus.

Schritt 2: Öffnen Sie ein neues Terminal.

Schritt 3: Führen Sie "docker ps" aus, um eine Liste des laufenden Containers abzurufen. Kopieren Sie die Container-ID.

Schritt 4: Wenn Sie nun "docker exec -it {container id} sh" oder "docker exec -it {container id} bash" ausführen, wird eine ähnliche Fehlermeldung angezeigt wie "Das Eingabegerät ist kein TTY. Wenn ja Versuchen Sie mit mintty, dem Befehl 'winpty' voranzustellen. "

Schritt 5: Führen Sie den Befehl " $ winpty docker exec -it {container id} sh " aus.

vola !! Sie befinden sich jetzt im Terminal.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.