różnica między docker attach a docker exec

82

Obaj będą mogli wykonywać polecenia w kontenerze. Obaj mogli odłączyć pojemnik.

Jaka jest więc prawdziwa różnica między docker exec i docker attach?

MJL
źródło

Odpowiedzi:

85

Pojawił się komunikat PR, który dodał do dokumentu:

Uwaga: to polecenie ( attach) nie służy do uruchamiania nowego procesu w kontenerze. Zobacz: docker exec.

Odpowiedź na pytanie „ Docker. Jak uzyskać bash \ ssh wewnątrz uruchomionego kontenera ( run -d)? ” Ilustruje różnicę:

(docker> = 1.3) Jeśli używamy docker attach, możemy użyć tylko jednej instancji powłoki .
Więc jeśli chcemy otworzyć nowy terminal z nową instancją powłoki kontenera, musimy po prostu uruchomićdocker exec

jeśli kontener docker został uruchomiony za pomocą /bin/bashpolecenia, możesz uzyskać do niego dostęp za pomocą dołączania, jeśli nie, musisz wykonać polecenie, aby utworzyć instancję bash wewnątrz kontenera za pomocą exec.

Jak wspomniano w tym numerze :

  • Dołącz nie służy do uruchamiania dodatkowej rzeczy w kontenerze, służy do dołączania do uruchomionego procesu.
  • docker exec” jest przeznaczony specjalnie do uruchamiania nowych rzeczy w już uruchomionym kontenerze, czy to w powłoce, czy w jakimś innym procesie.

W tym samym numerze dodaje się:

Chociaż attachnie jest dobrze nazwany, szczególnie ze względu na polecenie LXC lxc-attach(które jest bardziej podobne docker exec <container> /bin/sh, ale specyficzne dla LXC), ma konkretny cel dosłownego dołączenia cię do procesu uruchomionego przez Docker.
W zależności od tego, jaki jest proces, zachowanie może się różnić , na przykład dołączenie do /bin/bashda ci powłokę, ale podłączenie do redis-server będzie takie, jak po prostu zacząłeś redis bezpośrednio bez demonizacji.

VonC
źródło
24

Kiedy kontener jest uruchamiany przy użyciu / bin / bash, staje się kontenerami PID 1, a docker attach jest używany do uzyskania dostępu do PID 1 kontenera. Więc docker attach <container-id> przeniesie Cię do terminala bash, ponieważ jest to PID 1, jak wspomnieliśmy podczas uruchamiania kontenera. Wyjście z pojemnika zatrzyma pojemnik.

Natomiast w poleceniu docker exec możesz określić, do której powłoki chcesz wejść. Nie przeniesie Cię do PID 1 kontenera. Stworzy to nowy proces dla basha. docker exec -it <identyfikator-kontenera> bash . Wyjście z pojemnika nie zatrzyma pojemnika.

Możesz także użyć nsenter, aby wejść do kontenerów. nsenter -m -u -n -p -i -t <pid kontenera> Możesz znaleźć PID kontenera używając: docker inspect <id-kontenera> | grep PID

Uwaga: Jeśli uruchomiłeś swój kontener z flagą -d, wyjście z kontenera nie zatrzyma kontenera, niezależnie od tego, czy użyjesz attach, czy exec, aby dostać się do środka.

Samrat Priyadarshi
źródło
Ciekawy pomysł na użycie nsenter. Czy możesz rozwinąć? Wyjaśnienie opcji byłoby w porządku. Dlaczego nie wprowadzić wszystkich przestrzeni nazw? Dlaczego właśnie te?
x-yuri
7

Jak stwierdził Michael Sun w swojej odpowiedzi

docker execwykonuje nowe polecenie / tworzy nowy proces w środowisku kontenera, podczas gdy docker attachpo prostu łączy standardowe wejście / wyjście / błąd głównego procesu (z PID 1) wewnątrz kontenera do odpowiedniego standardowego wejścia / wyjścia / błędu bieżącego terminala (terminal używasz do uruchomienia polecenia).

Moja odpowiedź skupi się bardziej na umożliwieniu ci zweryfikowania powyższego stwierdzenia i lepszego zrozumienia go.

Otwórz okno terminala i uruchom polecenie docker run -itd --name busybox busybox /bin/sh. Polecenie ściągnie obraz, busyboxjeśli jeszcze go nie ma. Następnie utworzy kontener o nazwie busyboxprzy użyciu tego obrazu.

Możesz sprawdzić stan swojego kontenera, uruchamiając polecenie docker ps -a | grep busybox.

Jeśli uruchomisz docker top busybox, powinieneś zobaczyć takie wyjście.

UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                7469                7451                0                   11:40               pts/0               00:00:00            /bin/sh

Oczywiście, PID, PPIDoraz inne wartości będą różne w Twoim przypadku. Można korzystać z innych narzędzi i programów narzędziowych oraz jak pstree, top, htopaby wyświetlić listę PIDi PPID.

PIDI PPIDoznacza identyfikator procesu i proces nadrzędny ID. Proces rozpoczął się, gdy utworzyliśmy i uruchomiliśmy nasz kontener poleceniem /bin/sh. Teraz uruchom polecenie docker attach busybox. Spowoduje to dołączenie standardowego strumienia wejścia / wyjścia / błędu kontenera do terminala.

Po dołączeniu kontenera utwórz sesję powłoki, uruchamiając polecenie sh. CTRL-p CTRL-qSekwencja prasy . Spowoduje to odłączenie terminala od kontenera i utrzyma kontener w ruchu. Jeśli teraz uruchomisz docker top busybox, na liście powinny pojawić się dwa procesy.

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

Ale PPIDz tych dwóch procesów będzie inny. W rzeczywistości PPIDdrugi proces będzie taki sam, jak PIDpierwszy. Pierwszy proces działa jako proces nadrzędny dla właśnie utworzonej sesji powłoki.

A teraz biegnij docker exec -it busybox sh. Po wejściu do kontenera sprawdź listę uruchomionych procesów kontenera busyboxw innym oknie terminala, uruchamiając polecenie docker top busybox. Powinieneś zobaczyć coś takiego

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

PPIDPierwszego i trzeciego procesu będzie to samo, co potwierdza, że docker exectworzy nowy proces w środowisku kontenera podczas gdy docker attachtylko połączy standardowego wejścia / wyjścia / błąd głównego procesu wewnątrz pojemnika na odpowiednie standardowe wejście / wyjście / błąd prądu terminal.

Kartik Chauhan
źródło
5

Docker wykonuje nowe polecenie / tworzy nowy proces w środowisku kontenera, podczas gdy docker attach po prostu łączy standardowe wejście / wyjście / błąd głównego procesu (z PID 1) wewnątrz kontenera do odpowiedniego standardowego wejścia / wyjścia / błędu prądu terminal (terminal, którego używasz do uruchomienia polecenia).

Kontener to izolowane środowisko, w którym działają pewne procesy. W szczególności kontener ma własną przestrzeń systemu plików i przestrzeń PID, które są odizolowane od hosta i innych kontenerów. Gdy kontener zostanie uruchomiony przy użyciu polecenia „docker run –it…”, główny proces będzie miał pseudo-tty i STDIN pozostające otwarte. Po podłączeniu w trybie tty można odłączyć się od kontenera (i pozostawić go uruchomionego) za pomocą konfigurowalnej sekwencji klawiszy. Domyślna sekwencja to CTRL-p CTRL-q. Sekwencję klawiszy można skonfigurować za pomocą opcji --detach-keys lub pliku konfiguracyjnego. Możesz ponownie dołączyć do odłączonego kontenera za pomocą Docker Attach.

Docker exec właśnie uruchamia nowy proces w środowisku kontenera, czyli należy do przestrzeni PID kontenera.

Na przykład, jeśli uruchomisz kontener za pomocą „docker run –dit XXX / bin / bash”, możesz dołączyć do kontenera (głównego procesu) za pomocą dwóch różnych terminali. Kiedy wprowadzasz dane w jednym terminalu, możesz zobaczyć, że pojawia się w drugim terminalu, ponieważ oba terminale są podłączone do tego samego terminala. Uważaj, ponieważ jesteś teraz w głównym procesie kontenera, jeśli wpiszesz „exit”, wyjdziesz z kontenera ( więc uważaj, używając klawiszy odłączania do odłączenia ), a zobaczysz, że oba terminale zostały opuszczone. Ale jeśli uruchomisz „docker exec –it XXX / bin / bash” w dwóch terminalach, uruchomiłeś dwa nowe procesy wewnątrz kontenera i nie są one powiązane ze sobą ani z procesem głównym i możesz bezpiecznie z nich wyjść .

Michael.Sun
źródło