Beide können Befehle im Container ausführen. Beide konnten den Container abnehmen.
Was ist der wahre Unterschied zwischen Docker Exec und Docker Attach?
Antworten:
Es gab eine Commit-PR, die dem Dokument hinzugefügt wurde:
Hinweis: Dieser Befehl (
attach
) dient nicht zum Ausführen eines neuen Prozesses in einem Container. Siehe :docker exec
.
Die Antwort auf " Docker. Wie bekomme ich bash \ ssh in runned container ( run -d
)? " Veranschaulicht den Unterschied:
(Docker> = 1.3) Wenn wir verwenden
docker attach
, können wir nur eine Instanz der Shell verwenden .
Wenn wir also ein neues Terminal mit einer neuen Instanz der Container-Shell öffnen möchten, müssen wir nur ausführendocker exec
Wenn der Docker-Container mit dem
/bin/bash
Befehl gestartet wurde , können Sie mit attach darauf zugreifen. Wenn nicht, müssen Sie den Befehl ausführen , um mit eine Bash-Instanz im Container zu erstellenexec
.
Wie in dieser Ausgabe erwähnt :
- Anhängen dient nicht zum Ausführen einer zusätzlichen Sache in einem Container, sondern zum Anhängen an den laufenden Prozess.
- "
docker exec
" ist speziell für das Ausführen neuer Dinge in einem bereits gestarteten Container gedacht, sei es eine Shell oder ein anderer Prozess.
Das gleiche Problem fügt hinzu:
Obwohl
attach
es nicht gut benannt ist, insbesondere aufgrund des LXC-Befehlslxc-attach
(der ähnlicherdocker exec <container> /bin/sh
, aber LXC-spezifisch ist), hat es einen bestimmten Zweck, Sie buchstäblich an den von Docker gestarteten Prozess anzuhängen.
Abhängig davon, wie der Prozess abläuft, kann das Verhalten unterschiedlich sein . Wenn/bin/bash
Sie beispielsweise eine Verbindung zu redis-server herstellen, erhalten Sie eine Shell, aber wenn Sie eine Verbindung zu redis-server herstellen, haben Sie gerade begonnen, redis direkt zu starten, ohne zu dämonisieren.
Wenn ein Container mit / bin / bash gestartet wird, wird er zu den Containern PID 1, und Docker-Attach wird verwendet, um in die PID 1 eines Containers zu gelangen. So Docker <Container-id> anhängen werden Sie in der bash - Terminal nehmen , wie es PID ist 1 , wie bereits erwähnt , während der Behälter beginnen. Wenn Sie den Container verlassen, wird der Container angehalten.
Während in Befehl docker exec angeben können, in welche Shell Sie eintreten möchten. Sie gelangen nicht zu PID 1 des Containers. Es wird ein neuer Prozess für Bash erstellt. Docker Exec -it <Container-ID> Bash . Das Verlassen des Containers stoppt den Container nicht.
Sie können auch nsenter verwenden , um in Container einzutreten. nsenter -m -u -n -p -i -t < PID des Containers> Sie können die PID des Containers mithilfe von: docker inspect <Container-ID> | ermitteln grep PID
Hinweis: Wenn Sie Ihren Container mit dem Flag -d gestartet haben, wird der Container durch das Verlassen des Containers nicht gestoppt, unabhängig davon, ob Sie mit attach oder exec in den Container gelangen.
Wie Michael Sun in seiner Antwort feststellte
docker exec
führt einen neuen Befehl aus / erstellt einen neuen Prozess in der Containerumgebung, währenddocker attach
nur die Standardeingabe / -ausgabe / -fehler des Hauptprozesses (mit PID 1) im Container mit der entsprechenden Standardeingabe / -ausgabe / -fehler des aktuellen Terminals (des Terminals) verbunden wird Sie verwenden, um den Befehl auszuführen).
Meine Antwort wird sich mehr darauf konzentrieren, dass Sie die obige Aussage validieren und klarer verstehen.
Öffnen Sie ein Terminalfenster und führen Sie den Befehl aus docker run -itd --name busybox busybox /bin/sh
. Der Befehl zieht das Bild, busybox
falls es noch nicht vorhanden ist. Anschließend wird ein Container mit dem Namen erstelltbusybox
anhand dieses Bildes .
Sie können den Status Ihres Containers überprüfen, indem Sie den Befehl ausführen docker ps -a | grep busybox
.
Wenn Sie ausführen docker top busybox
, sollten Sie eine Ausgabe wie diese sehen.
UID PID PPID C STIME TTY TIME CMD
root 7469 7451 0 11:40 pts/0 00:00:00 /bin/sh
Natürlich sind die PID
, PPID
werden und andere Werte in Ihrem Fall unterschiedlich sein. Sie können auch andere Werkzeuge und Dienstprogramme verwenden und wie pstree
, top
, htop
die Liste der sehen PID
und PPID
.
Das PID
und PPID
bedeutet die Prozess-ID und die übergeordnete Prozess-ID. Der Prozess begann, als wir unseren Container mit dem Befehl erstellt und gestartet haben /bin/sh
. Führen Sie nun den Befehl ausdocker attach busybox
. Dadurch wird der Standard-Eingabe- / Ausgabe- / Fehlerstrom des Containers an Ihr Terminal angehängt.
Erstellen Sie nach dem Anhängen des Containers eine Shell-Sitzung, indem Sie den Befehl ausführen sh
. Presse - CTRL-p CTRL-q
Sequenz. Dadurch wird das Terminal vom Container getrennt und der Container läuft weiter. Wenn Sie jetzt ausführen docker top busybox
, sollten zwei Prozesse in der Liste angezeigt werden.
UID PID PPID C STIME TTY TIME CMD
root 7469 7451 0 11:40 pts/0 00:00:00 /bin/sh
root 7737 7469 0 11:43 pts/0 00:00:00 sh
Aber der PPID
der beiden Prozesse wird unterschiedlich sein. Tatsächlich ist der PPID
zweite Prozess der gleiche wie PID
der erste. Der erste Prozess fungiert als übergeordneter Prozess für die gerade erstellte Shell-Sitzung.
Jetzt renn docker exec -it busybox sh
. Überprüfen Sie im Container die Liste der ausgeführten Prozesse für den Container busybox
in einem anderen Terminalfenster, indem Sie den Befehl ausführen docker top busybox
. Sie sollten so etwas sehen
UID PID PPID C STIME TTY TIME CMD
root 7469 7451 0 11:40 pts/0 00:00:00 /bin/sh
root 7737 7469 0 11:43 pts/0 00:00:00 sh
root 7880 7451 0 11:45 pts/1 00:00:00 sh
Der PPID
erste und dritte Prozess sind gleich, was bestätigt, dass docker exec
ein neuer Prozess in der Containerumgebung erstellt wird, während docker attach
nur die Standardeingabe / -ausgabe / -fehler des Hauptprozesses innerhalb des Containers mit der entsprechenden Standardeingabe / -ausgabe / -fehler des Stroms verbunden wird Terminal.
Docker exec führt einen neuen Befehl aus / erstellt einen neuen Prozess in der Containerumgebung, während Docker Attach nur die Standardeingabe / -ausgabe / -fehler des Hauptprozesses (mit PID 1) im Container mit der entsprechenden Standardeingabe / -ausgabe / -fehler des Stroms verbindet Terminal (das Terminal, mit dem Sie den Befehl ausführen).
Ein Container ist eine isolierte Umgebung, in der einige Prozesse in der Umgebung ausgeführt werden. Insbesondere verfügt ein Container über einen eigenen Dateisystem- und PID-Bereich, die vom Host und anderen Containern isoliert sind. Wenn der Container mit „Docker Run –it…“ gestartet wird, hat der Hauptprozess eine Pseudo-Tty und STDIN bleibt offen. Wenn Sie im tty-Modus angehängt sind, können Sie ihn mithilfe einer konfigurierbaren Tastenfolge vom Container trennen (und laufen lassen). Die Standardsequenz ist STRG-p STRG-q. Sie konfigurieren die Tastenfolge mit der Option --detach-keys oder einer Konfigurationsdatei. Sie können mit Docker Attach wieder an einen abgetrennten Container anhängen.
Docker exec startet gerade einen neuen Prozess in der Containerumgebung, der zum PID-Bereich des Containers gehört.
Wenn Sie Ihren Container beispielsweise mit "docker run –dit XXX / bin / bash" starten, können Sie ihn über zwei verschiedene Terminals an den Container (den Hauptprozess) anschließen. Während Sie in ein Terminal eingeben, sehen Sie, dass es im anderen Terminal angezeigt wird, da beide Terminals mit demselben tty verbunden sind. Achten Sie darauf, dass Sie sich jetzt im Hauptprozess des Containers befinden. Wenn Sie "exit" eingeben , verlassen Sie den Container (seien Sie also vorsichtig, indem Sie die Tasten zum Trennen verwenden ), und beide Terminals werden beendet. Wenn Sie jedoch "docker exec - it XXX / bin / bash" in zwei Terminals ausführen, haben Sie zwei neue Prozesse im Container gestartet, die nicht miteinander und mit dem Hauptprozess verknüpft sind, und Sie können sie sicher verlassen .
nsenter
. Können Sie das näher erläutern? Die Optionen zu erklären wäre angebracht. Warum nicht alle Namespaces eingeben? Warum gerade diese?