різниця між прикріпленням докера та виконувачем докера


82

Обидва зможуть виконувати команди в контейнері. Обидва могли від'єднати контейнер.

То яка реальна різниця між docker exec та docker attach?

Відповіді:


85

Був коміт PR, який додав до документа:

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

Відповідь на " Docker. Як отримати bash \ ssh всередині запущеного контейнера ( run -d)? " Ілюструє різницю:

(docker> = 1.3) Якщо ми використовуємо docker attach, ми можемо використовувати лише один екземпляр оболонки .
Отже, якщо ми хочемо відкрити новий термінал з новим екземпляром оболонки контейнера, нам просто потрібно запуститиdocker exec

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

Як зазначалося у цьому випуску :

  • Вкласти не для запуску зайвої речі в контейнері, це для прикріплення до запущеного процесу.
  • " docker exec" спеціально призначений для запуску нових речей у вже запущеному контейнері, будь то оболонка чи інший процес.

Те саме видання додає:

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


24

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

Тоді як у команді docker exec ви можете вказати, в яку оболонку ви хочете ввійти. Ви не потрапите до PID 1 контейнера. Це створить новий процес для bash. docker exec -it <id-контейнера> bash . Вихід з контейнера не зупинить контейнер.

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

Примітка: Якщо ви запустили контейнер із позначкою -d, тоді вихід із контейнера не зупинить контейнер, незалежно від того, використовуєте ви прикріплення або exec, щоб потрапити всередину.


Цікава ідея щодо використання nsenter. Чи можете ви детальніше сказати? Пояснення варіантів буде в порядку. Чому б не ввести всі простори імен? Чому саме ці?
x-yuri

7

Як заявив у своїй відповіді Майкл Сан

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тільки підключається стандартний вхід / вихід / помилка основного процесу всередині контейнера з відповідними стандартне введення / виведення / помилка струму термінал.


5

Docker exec виконує нову команду / створює новий процес у середовищі контейнера, тоді як прикріплення докера просто підключає стандартний вхід / вихід / помилку основного процесу (з PID 1) всередині контейнера до відповідного стандартного вводу / виводу / помилки поточного термінал (термінал, який ви використовуєте для запуску команди).

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

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

Наприклад, якщо ви запускаєте контейнер за допомогою “docker run –dit XXX / bin / bash”, ви можете приєднати його до контейнера (основного процесу) за допомогою двох різних терміналів. Поки ви вводите в одному терміналі, ви бачите, що він відображається в іншому терміналі, оскільки обидва термінали підключені до одного і того ж tty. Будьте обережні, що зараз ви перебуваєте в основному процесі контейнера; якщо ви наберете “вийти”, ви вийдете з контейнера ( тому будьте обережні, використовуючи клавіші роз'єднання для від'єднання ), і ви побачите, як обидва термінали вийшли. Але якщо ви запустили “docker exec –it XXX / bin / bash” у двох терміналах, ви запустили два нових процеси всередині контейнера, і вони не пов’язані між собою та основним процесом, і ви можете безпечно вийти з них .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.