了解 docker run 指令
昨天從執行 Hello Docker 的過程中,了解 Docker 的三個基本元件。今天會更進一步地說明 docker run
更多細節。
首先,先回顧這張示意圖:
Hello Docker 使用的 docker run
指令,可以一條龍處理上圖所有任務。等等將會示範如何不使用 docker run
來達成執行 container,同時換用 BusyBox image 來做示範。
BusyBox 是一個 Linux 指令工具包,它執行後會進到 container 的命令提示字元裡,接著就能使用 BusyBox 所提供的 Linux 指令。
執行 container 任務先簡單拆解如下:
下載 image
首先 Docker 會確認 image 是否存在,可以用 docker images
指令來查看本機的 image,接著使用 docker pull
指令下載 image:
# 查看本機 image |
一開始執行 docker images busybox
會出現空列表,代表 host 沒有對應的 image,會需要下載。如果 image 存在,會跳到建立 container步驟。下載完成後,可以用一開始的指令 docker images busybox
再次確認是否有下載成功。
如果想確認這個 image 是否可以下載,可以上 DockerHub 上找,或使用 docker search
指令查詢:
$ docker search busybox |
這裡有個欄位 OFFICIAL
標示 OK,代表這個 image 是官方出品有掛保證的,通常會建議使用官方的 image,相較穩定可靠。
移除 image
若已下載的 image 已用不到,如 hello-world
,可以使用 docker rmi
移除:
$ docker rmi hello-world |
docker rmi
有可能會因為 container 未移除導致 image 移除失敗,先把對應的 container 移除,再執行 docker rmi
即可:
$ docker rmi hello-world |
image 間如果有依賴關係,也有可能會無法正常移除,此情境未來會說明。
到這裡為止,image 已準備完成。
建立 container
Docker 提供建立 container 的指令為 docker create
,實際執行範例如下:
# 建立 container |
說明 docker create
指令的選項與參數:
-i -t
簡單來說,當需要跟 container 的 process 互動時,通常會加入這兩個參數。互動指的是像git add -i
會跟使用者一問一答的行為。--name
可以幫 container 命名,這個名字會在docker ps
列表的NAMES
欄位出現。必須唯一,若撞名則 container 會創建失敗。- 選項後的第一個參數為 image 名稱,本例為
busybox
。
下 docker create
後會顯示一個 digest,這與 docker ps
列表裡的 CONTAINER ID
相同。另外可以注意到這次的 STATUS
不大一樣,是 Created
,它表示 container 創建完成。
執行 container
執行 container 使用 docker start
指令:
# 執行 container,`foo` 是前一節創建 container 指定的名字。 |
上面執行過程中,有出現兩個不一樣的命令提示字元,一個是 host 客製化的提示字元,另一個則是 / #
,這已經在 container 的世界裡了。
在 container 執行 whoami
得到的結果,會是 Docker 指定的使用者。本範例並沒有特別指定,所以是 BusyBox 預設的 root。而像 ls
的示範則是看到 container 裡的檔案系統。因為這些特色,讓 container 能做到類似 VM 的效果。
執行 BusyBox 的過程中,可以使用 Ctrl + P
與 Ctrl + Q
的連續組合鍵來達成「離開 container」--detach 的效果。離開後可以使用 docker ps
回來觀察 container 的狀態。container 還是 Up
的時候,可以使用 docker attach
再讓 container 回到前景:
# 使用 docker ps 可以觀察到狀態是 `Up`,正常運行中。 |
停止 container
停止 BusyBox container 有兩種方法,一種是在 container 裡下結束的指令 exit
;另一種則是使用 docker stop
指令:
docker stop foo |
注意這兩種方法有一點點差異,主要在於 Exited
後面的狀態碼不同,第一個方法是 0,代表正常結束。它使用正常流程 exit
指令結束 shell。
第二個方法使用 docker stop
會發送 SIGTERM
信號給 container 的主程序,等同於呼叫對主程序下 kill -15
指令一樣,是要求 process 強制結束。但因 process 結束遇到問題,因此才會出現不正常結束的狀態碼。
最後,使用 docker rm
指令移除 container,一切就會恢復成一開始還沒建 container 的狀態:
docker rm foo |
以上詳細說明了 image 下載與移除的過程,以及 container 的生命週期。現在再看一次示意圖,應該會對整個流程更有感覺:
建議讀者可以多了解今天的內容,因為不管是什麼 image,都會執行今天說明的流程。唯有熟悉整個流程,才有辦法在發生問題的時候,知道是哪個環節出問題與解決對應的問題。
指令說明
docker images
查看本地目前有哪些 image,用法如下:
docker images [REPOSITORY[:TAG]] |
REPOSITORY
沒給的話,會列出本機所有的 image;如果有給的話,則會把該 repository 所有 tag 都列出來;如果加給 TAG
,則只會列出該 repository + tag 對應的 image。
今天的範例是只有給
REPOSITORY
。TAG
的用法類似版號,實際範例未來會有機會看到。
docker pull
從遠端 repository 下載 image,用法如下:
docker pull NAME[:TAG|@DIGEST] |
TAG
若沒有給的話,預設會使用 latest,因此下面這兩個指令是等價的:
docker pull busybox |
docker rmi
rmi
即 rm image 之意,移除 image,用法如下:
docker rmi [OPTIONS] IMAGE [IMAGE...] |
docker create
建立 container。這個指令類似 docker run
,但它只有建立 container 而沒有執行。兩個指令單純只差在有沒有執行,所以它們的參數幾乎都共用。
用法如下:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...] |
--name
可指定 container 名稱-i|--interactive
是讓 container 的標準輸入保持打開-t|--tty
選項是告訴 Docker 要分配一個虛擬終端機(pseudo-tty)並綁定到 container 的標準輸入上
docker start
啟動 container。
docker start [OPTIONS] CONTAINER [CONTAINER...] |
-i|--interactive
把標準輸入綁定到容器上。
注意:這裡的
--interactive
參數與docker create
的--interactive
參數的意義不同,必須要兩個都有啟用才能與容器互動。而docker run
的--interactive
會同時兩個都啟用。
docker attach
把前景「接」到 container 上,用法如下:
docker attach [OPTIONS] CONTAINER |
只要處於 detach 的 container,都能使用這個指令回到 container 上。
docker stop
強制停止指定的 container,用法:
docker stop [OPTIONS] CONTAINER [CONTAINER...] |
此指令會送出 SIGTERM
信號給 container 的主程序,當 timeout(預設 10,可使用 -t|--time
參數調整)後會再送出 SIGKILL
,也就是 kill -9
。
類似地,
docker pause
是送SIGSTOP
;docker kill
則是直接送SIGKILL
。
今日自我回顧
Hello Docker 是使用 docker run
執行範例程式,今天則是了解如何操作各別指令執行 container。簡單來說,docker run
與其他指令的關係如下:
docker run = docker pull + docker create + docker start |
另外也使用 --interactive
選項與 --tty
選項,成功進入 container 的環境,並在裡面執行指令(whoami
與 ls
)。
- 了解
docker run
背後對應的細節 - 練習
docker pull
下載 image - 練習
docker create
建立 container - 練習
docker start
啟動 container - 練習
docker stop
停止 container - 練習 container 的 detach 與 attach