разница между подключением докера и выполнением докера

Оба смогут выполнять команды в контейнере. Оба могли отсоединить контейнер.

Так в чем же реальная разница между docker exec и docker attach?


person MJL    schedule 21.06.2015    source источник


Ответы (4)


Был commit PR, который добавил в документ:

Примечание. Эта команда (attach) не предназначена для запуска нового процесса в контейнере. См.: docker exec.

Ответ на вопрос «Docker. Как получить bash\ssh внутри запущенного контейнера (run -d)?" иллюстрирует разницу:

(docker >= 1.3) Если мы используем docker attach, мы можем использовать только один экземпляр оболочки.
Поэтому, если мы хотим открыть новый терминал с новым экземпляром оболочки контейнера, нам просто нужно запустить docker exec

если контейнер docker был запущен с помощью команды /bin/bash, вы можете получить к нему доступ, используя присоединение, если нет, вам нужно выполнить команду для создания экземпляра bash внутри контейнера с помощью exec.

Как упоминалось в этой проблеме:

  • Присоединение не для запуска дополнительных вещей в контейнере, а для присоединения к запущенному процессу.
  • «docker exec» специально для запуска новых вещей в уже запущенном контейнере, будь то оболочка или какой-то другой процесс.

В том же выпуске добавляется:

Хотя имя attach не очень удачное, особенно из-за команды LXC lxc-attach (которая больше похожа на docker exec <container> /bin/sh, но специфична для LXC), у нее есть конкретная цель — буквально привязать вас к процессу, запущенному Docker.
В зависимости от что это за процесс, поведение может отличаться, например, присоединение к /bin/bash даст вам оболочку, но присоединение к redis-серверу будет таким же, как если бы вы только что запустили redis напрямую без демонизации.

person VonC    schedule 21.06.2015

Когда контейнер запускается с использованием /bin/bash, он становится контейнером PID 1, и для доступа внутрь контейнера с PID 1 используется подключение к докеру. Таким образом, docker attach ‹ container-id > перенесет вас внутрь терминала bash, так как его PID 1, как мы упоминали при запуске контейнера. Выход из контейнера остановит контейнер.

В то время как в команде docker exec вы можете указать, в какую оболочку вы хотите войти. Это не приведет вас к PID 1 контейнера. Это создаст новый процесс для bash. docker exec -it ‹ идентификатор-контейнера > bash. Выход из контейнера не остановит контейнер.

Вы также можете использовать nsenter для входа внутрь контейнеров. nsenter -m -u -n -p -i -t ‹ PID контейнера > Вы можете найти PID контейнера, используя: docker inspect ‹ container-id > | grep PID

Примечание. Если вы запустили свой контейнер с флагом -d, то выход из контейнера не остановит контейнер, независимо от того, используете ли вы присоединение или exec для входа внутрь.

person Samrat Priyadarshi    schedule 09.05.2017
comment
Интересная идея об использовании nsenter. Можете ли вы уточнить? Объяснение вариантов было бы в порядке. Почему бы не ввести все пространства имен? Почему именно эти? - person x-yuri; 29.06.2019

Как заявил Майкл Сан в своем ответе

docker exec выполняет новую команду/создает новый процесс в среде контейнера, а docker attach просто соединяет стандартный ввод/вывод/ошибку основного процесса (с PID 1) внутри контейнера с соответствующим стандартным вводом/выводом/ошибкой текущего терминала( терминал, который вы используете для запуска команды).

Мой ответ будет больше сосредоточен на том, чтобы вы могли подтвердить приведенное выше утверждение и понять его более четко.

Откройте окно терминала и выполните команду docker run -itd --name busybox busybox /bin/sh. Команда извлечет образ busybox, если он еще не существует. Затем он создаст контейнер с именем busybox, используя этот образ.

Вы можете проверить статус своего контейнера, выполнив команду docker ps -a | grep busybox.

Если вы запустите docker top busybox, вы должны увидеть что-то вроде этого.

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

Конечно, PID, PPID и другие значения в вашем случае будут другими. Вы также можете использовать другие инструменты и утилиты, такие как pstree, top, htop, чтобы просмотреть список PID и PPID.

PID и PPID означают идентификатор процесса и идентификатор родительского процесса. Процесс начался, когда мы создали и запустили наш контейнер командой /bin/sh. Теперь запустите команду docker attach busybox. Это прикрепит стандартный поток ввода/вывода/ошибки контейнера к вашему терминалу.

После присоединения контейнера создайте сеанс оболочки, выполнив команду sh. Нажмите CTRL-p CTRL-q последовательность. Это отсоединит терминал от контейнера и продолжит работу контейнера. Если вы сейчас запустите docker top busybox, вы должны увидеть в списке два процесса.

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

Но PPID двух процессов будут разными. Фактически, PPID второго процесса будет таким же, как PID первого. Первый процесс действует как родительский процесс для сеанса оболочки, который мы только что создали.

Теперь запустите docker exec -it busybox sh. Оказавшись внутри контейнера, проверьте список запущенных процессов для контейнера busybox в другом окне терминала, выполнив команду docker top busybox. Вы должны увидеть что-то вроде этого

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

PPID первого и третьего процесса будут одинаковыми, что подтверждает, что docker exec создает новый процесс в среде контейнера, а docker attach просто соединяет стандартный ввод/вывод/ошибку основного процесса внутри контейнера с соответствующим стандартным вводом/выводом/ ошибка текущего терминала.

person Kartik Chauhan    schedule 20.07.2019

Docker exec выполняет новую команду/создает новый процесс в среде контейнера, в то время как docker attach просто соединяет стандартный ввод/вывод/ошибку основного процесса (с PID 1) внутри контейнера с соответствующим стандартным вводом/выводом/ошибкой текущего терминал (терминал, который вы используете для запуска команды).

Контейнер — это изолированная среда, в которой выполняются некоторые процессы. В частности, у контейнера есть собственное пространство файловой системы и пространство PID, которые изолированы от хоста и других контейнеров. Когда контейнер запускается с помощью «docker run –it…», основной процесс будет иметь псевдотерминал, а STDIN останется открытым. При подключении в режиме tty вы можете отсоединиться от контейнера (и оставить его работающим) с помощью настраиваемой последовательности клавиш. Последовательность по умолчанию — CTRL-p CTRL-q. Вы настраиваете последовательность клавиш, используя параметр --detach-keys или файл конфигурации. Вы можете повторно подключиться к отдельному контейнеру с помощью подключения докера.

Docker exec просто запускает новый процесс внутри среды контейнера, то есть принадлежит пространству PID контейнера.

Например, если вы запускаете свой контейнер с помощью «docker run –dit XXX /bin/bash», вы можете подключиться к контейнеру (основной процесс) с помощью двух разных терминалов. Пока вы вводите данные в один терминал, вы можете видеть, что он появляется в другом терминале, поскольку оба терминала подключены к одному и тому же tty. Будьте осторожны, сейчас вы находитесь в основном процессе контейнера, если вы наберете «exit», вы выйдете из контейнера (так что будьте осторожны, используйте клавиши отсоединения для отсоединения), и вы увидите оба терминала вышли. Но если вы запустите «docker exec –it XXX /bin/bash» в двух терминалах, то у вас внутри контейнера запустились два новых процесса, причем они не связаны друг с другом и с основным процессом, и вы можете спокойно выйти из них .

person Michael.Sun    schedule 06.09.2018