Unterschied zwischen Docker Attach und Docker Exec

81

Beide können Befehle im Container ausführen. Beide konnten den Container abnehmen.

Was ist der wahre Unterschied zwischen Docker Exec und Docker Attach?

MJL
quelle

Antworten:

85

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/bashBefehl 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 erstellen exec.

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 attaches nicht gut benannt ist, insbesondere aufgrund des LXC-Befehls lxc-attach(der ähnlicher docker 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/bashSie 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.

VonC
quelle
24

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.

Samrat Priyadarshi
quelle
Interessante Idee zur Verwendung 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?
X-Yuri
7

Wie Michael Sun in seiner Antwort feststellte

docker execführt einen neuen Befehl aus / erstellt einen neuen Prozess in der Containerumgebung, während docker attachnur 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, busyboxfalls 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, PPIDwerden und andere Werte in Ihrem Fall unterschiedlich sein. Sie können auch andere Werkzeuge und Dienstprogramme verwenden und wie pstree, top, htopdie Liste der sehen PIDund PPID.

Das PIDund PPIDbedeutet 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-qSequenz. 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 PPIDder beiden Prozesse wird unterschiedlich sein. Tatsächlich ist der PPIDzweite Prozess der gleiche wie PIDder 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 busyboxin 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 PPIDerste und dritte Prozess sind gleich, was bestätigt, dass docker execein neuer Prozess in der Containerumgebung erstellt wird, während docker attachnur die Standardeingabe / -ausgabe / -fehler des Hauptprozesses innerhalb des Containers mit der entsprechenden Standardeingabe / -ausgabe / -fehler des Stroms verbunden wird Terminal.

Kartik Chauhan
quelle
5

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 .

Michael.Sun
quelle