Обидва зможуть виконувати команди в контейнері. Обидва могли від'єднати контейнер.
То яка реальна різниця між docker exec та docker attach?
Відповіді:
Був коміт PR, який додав до документа:
Примітка: Ця команда (
attach
) не призначена для запуску нового процесу в контейнері. Див .:docker exec
.
Відповідь на " Docker. Як отримати bash \ ssh всередині запущеного контейнера ( run -d
)? " Ілюструє різницю:
(docker> = 1.3) Якщо ми використовуємо
docker attach
, ми можемо використовувати лише один екземпляр оболонки .
Отже, якщо ми хочемо відкрити новий термінал з новим екземпляром оболонки контейнера, нам просто потрібно запуститиdocker exec
якщо контейнер докера був запущений за допомогою
/bin/bash
команди, ви можете отримати до нього доступ за допомогою Attach, якщо ні, то вам потрібно виконати команду для створення екземпляра bash всередині контейнера за допомогоюexec
.
Як зазначалося у цьому випуску :
- Вкласти не для запуску зайвої речі в контейнері, це для прикріплення до запущеного процесу.
- "
docker exec
" спеціально призначений для запуску нових речей у вже запущеному контейнері, будь то оболонка чи інший процес.
Те саме видання додає:
Хоча
attach
це не дуже добре названо, особливо через команду LXClxc-attach
(яка більш схожаdocker exec <container> /bin/sh
, але специфічна для LXC), вона має конкретну мету буквально приєднати вас до запущеного процесу Docker.
Залежно від того, в якому процесі відбувається, поведінка може бути різною , наприклад, прикріплення до/bin/bash
дасть вам оболонку, але прикріплення до redis-сервера буде таким, як ви щойно розпочали redis безпосередньо без демонізації.
Коли контейнер запускається за допомогою / 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, щоб потрапити всередину.
Як заявив у своїй відповіді Майкл Сан
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
тільки підключається стандартний вхід / вихід / помилка основного процесу всередині контейнера з відповідними стандартне введення / виведення / помилка струму термінал.
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” у двох терміналах, ви запустили два нових процеси всередині контейнера, і вони не пов’язані між собою та основним процесом, і ви можете безпечно вийти з них .
nsenter
. Чи можете ви детальніше сказати? Пояснення варіантів буде в порядку. Чому б не ввести всі простори імен? Чому саме ці?