Docker Attach vs Exec
之前在進入 Container 內部時經常使用到 docker attach <ContainerId>
這個命令,不過 Docker 還有提供另一個命令 docker exec
docker exec
顧名思義就是在 container 內部運行一段命令,我們可以在 Host 環境底下直接將命令傳送給 container 內部
交由 container 內部的系統來運行,所以範用性比起 docker attach
更加的廣泛,今天要來比較這兩個命令的區別
Docker Attach
第一個是我們常用的 docker attach
,首先我們先安裝 tumx
主要的用途是要開啟兩個 session,也可以開啟兩個 putty
也可以達到同樣的效果
我這邊使用的是 Play with Docker 的環境,可以使用以下命令來進行安裝
apk add tmux
安裝完成後輸入 tmux
就會進入到 tmux
所管理的 Session 了
進入後會看到底下有一條綠色的長條寫著 [0] 0:bash*
, 就代表你有正確進入到環境了
tmux
接下來按下快捷鍵 Ctrl + b
+ c
,建立一個新的 Session , 要注意 c
要獨立按下不要按著 Ctrl
這時底下會多出一個 bash 寫著 [0] 0:bash- 1:bash*
後面的星字號 *
代表目前所在的 Session,我們現在位於 Session 1
接下來按下快捷鍵 Ctrl + b
+ %
,將畫面一分為二,左邊為 Session 1 右邊為 Session 2,可以使用 Ctrl + b
+ 方向鍵
來進行左右 Session 切換
(DCAAttachExec-tmux.png)
都完成後我們在 Session 1 運行起一個 ubuntu container,這邊都是同一台 Host 所以在哪個 Session 執行都可以
docker run -dit ubuntu
之後在 Session 1 使用 docker attach
進入 container
docker attach fe3346
進入後輸入 ps
查看有什麼程式正在運行中,可以看到此 container 的 PID 1 正在運行 Bash
PID 1 代表 container 主要運行的任務,如果 PID 1 發生異常或停止,Docker 認為此 container 已經完成任務了,會將此 container 停止
root@fe3346a36290:/# ps a
PID TTY TIME CMD
1 pts/0 00:00:00 bash
12 pts/0 00:00:00 ps
接下來使用快捷鍵 Ctrl + b
+ 方向鍵
切換到 Session 2,並且也使用 docker attach
進入 container
docker attach fe3346
輸入命令後會發現怎麼兩個 Session 會同步運行,這是因為 docker attach
的機制,當輸入之後它會附加到container 目前正在運行的 bash
並且兩個 Session 都附加到同一個 bash 上, 所以才會看起來有同步運行的效果,而且因為是附加在 bash 上並且它又是 PID 1
正如剛剛所提到的 PID 1 的程式不可以停止運行,否則 container 會進行關閉,這也就是為什麼之前使用 docker attach
有時需要搭配快捷鍵 Ctrl + b
+ Ctrl + q
而不是使用 exit
進行退出, 這是因為使用 exit
會將 container 的 bash 關閉,所以整個 container 會進行關閉, 使用快捷鍵 Ctrl + b
+ Ctrl + q
則不會有這個問題
Docker Exec
接下來測試 docker exec
, 也是啟動一個 ubuntu container
docker run -dit ubuntu
這時改用 docker exec
來進入 container
這個命令的意思是請 docker 將命令交給 container 內部執行,也就是剛剛建立的 ubuntu container 並且運行 bash 這個程式
docker exec -it e0a84d bash
進入後輸入 ps a
,發現我們剛剛輸入的 exec 命令,已經不是 PID 1了,反而是 PID 9
root@e0a84d79da82:/# ps a
PID TTY STAT TIME COMMAND
1 pts/0 Ss+ 0:00 /bin/bash
9 pts/1 Ss 0:00 bash
23 pts/1 R+ 0:00 ps a
這就是與docker attach
最大的不同, docker exec
會另外執行一個 process, 不會附加到原本的 PID 1 上
這樣反而比較安全因為 docker exec
並不會改變 container 原有的行為,隨便進行附加可能會讓 container 產生意外
而且不是PID 1 就代表我們可以使用 exit
進行退出,不會造成 container 停止
最後 docker exec
可以執行任何的命令,並不限於進入 container 這個功能,例如可以使用以下指令
可以輕鬆的列出 distro 資訊,簡單的命令就再也不用在重複進入 container 內部後再進行輸入了
$ docker exec e0a84d cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Summary
今天比較了兩個進入 container 的方法 docker attach
和 docker exec
, 兩個都有各自使用的場合
例如可以利用docker attach
的特性,使用完 container 之後想要可以直接輸入 exit 退出同時將 container 關閉,可以不用手動下指令將 container 停止
docker exec
反之更加全面,所以反而都是選擇使用此命令來進入 container 內部
這也是一開使很容易搞混的地方,因為 attach 字面上看起來是附加但卻不是最佳解所以實際上用的不多,反而一個字面上不清楚的 exec 才是最佳解法
之後可以按照自己的需求來選擇要使用那一個命令