iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
1
DevOps

30 天與鯨魚先生做好朋友系列 第 4

了解 docker run 指令

昨天從執行 Hello Docker 的過程中,了解 Docker 的三個基本元件。今天會更進一步地說明 docker run 更多細節。

首先,先回顧這張示意圖:

Hello Docker 使用的 docker run 指令,可以一條龍處理上圖所有任務。等等將會示範如何不使用 docker run 來達成執行 container,同時換用 BusyBox image 來做示範。

BusyBox 是一個 Linux 指令工具包,它執行後會進到 container 的命令提示字元裡,接著就能使用 BusyBox 所提供的 Linux 指令。

執行 container 任務先簡單拆解如下:

  1. 下載 image
  2. 建立 container
  3. 執行 container
  4. 停止 container

下載 image

首先 Docker 會確認 image 是否存在,可以用 docker images 指令來查看本機的 image,接著使用 docker pull 指令下載 image:

# 查看本機 image
docker images busybox

# 下載 image
docker pull busybox

一開始執行 docker images busybox 會出現空列表,代表 host 沒有對應的 image,會需要下載。如果 image 存在,會跳到建立 container步驟。下載完成後,可以用一開始的指令 docker images busybox 再次確認是否有下載成功。

如果想確認這個 image 是否可以下載,可以上 DockerHub 上找,或使用 docker search 指令查詢:

$ docker search busybox
NAME                      DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
busybox                   Busybox base image.                             1986                [OK]
...

這裡有個欄位 OFFICIAL 標示 OK,代表這個 image 是官方出品有掛保證的,通常會建議使用官方的 image,相較穩定可靠。

移除 image

若已下載的 image 已用不到,如 hello-world,可以使用 docker rmi 移除:

$ docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:7f0a9f93b4aa3022c3a4c147a449bf11e0941a1fd0bf4a8e6c9408b2600777c5
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63

docker rmi 有可能會因為 container 未移除導致 image 移除失敗,先把對應的 container 移除,再執行 docker rmi 即可:

$ docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference "hello-world" (must force) - container 7aa21315f7ca is using its referenced image bf756fb1ae65
$ docker rm 7aa21315f7ca
7aa21315f7ca
$ docker rmi hello-world

image 間如果有依賴關係,也有可能會無法正常移除,此情境未來會說明。

到這裡為止,image 已準備完成。

建立 container

Docker 提供建立 container 的指令為 docker create,實際執行範例如下:

# 建立 container
docker create -i -t --name foo busybox

# 使用 docker ps 確認 container 狀態
docker ps -a

說明 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 指定的名字。
docker start -i foo

# container 內執行 Linux 指令
whoami
ls

上面執行過程中,有出現兩個不一樣的命令提示字元,一個是筆者 host 客製化的提示字元,另一個則是 / #,這已經在 container 的世界裡了。

在 container 執行 whoami 得到的結果,會是 Docker 指定的使用者。本範例並沒有特別指定,所以是 BusyBox 預設的 root。而像 ls 的示範則是看到 container 裡的檔案系統。因為這些特色,讓 container 能做到類似 VM 的效果。

執行 BusyBox 的過程中,可以使用 Ctrl + PCtrl + Q 的連續組合鍵來達成「離開 container」--detach 的效果。離開後可以使用 docker ps 回來觀察 container 的狀態。container 還是 Up 的時候,可以使用 docker attach 再讓 container 回到前景:

# 使用 docker ps 可以觀察到狀態是 `Up`,正常運行中。
docker ps

# 將 container 裡輸入輸出綁回前景
docker attach foo

停止 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。

今天的範例是只有給 REPOSITORYTAG 的用法類似版號,實際範例未來會有機會看到。

docker pull

從遠端 repository 下載 image,用法如下:

docker pull NAME[:TAG|@DIGEST]

TAG 若沒有給的話,預設會使用 latest,因此下面這兩個指令是等價的:

docker pull busybox
docker pull busybox:latest

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 是送 SIGSTOPdocker kill 則是直接送 SIGKILL

今日自我回顧

Hello Docker 是使用 docker run 執行範例程式,今天則是了解如何操作各別指令執行 container。簡單來說,docker run 與其他指令的關係如下:

docker run = docker pull + docker create + docker start

另外也使用 --interactive 選項與 --tty 選項,成功進入 container 的環境,並在裡面執行指令(whoamils)。

  • 了解 docker run 背後對應的細節
  • 練習 docker pull 下載 image
  • 練習 docker create 建立 container
  • 練習 docker start 啟動 container
  • 練習 docker stop 停止 container
  • 練習 container 的 detach 與 attach

上一篇
Hello Docker World
下一篇
使用 Port forwarding 開放服務
系列文
30 天與鯨魚先生做好朋友30

尚未有邦友留言

立即登入留言